Экзаменационные задачи
1.Дана функция, записанная на языке Си, в которой пропущены некоторые фрагменты. Требуется восстановить пропущенные фрагменты таким образом, чтобы получившийся код был синтаксически и семантически корректным.
а)
void func(){
/* объявления и инициализация пропущены */
x=*y;
/* вывод пропущен */
}
- #include <stdio.h>
- using namespace std;
- void func() {
- int x;
- int c = 5;
- int *y =&c;
- x = *y;
- printf("x = %d y = %d, *y = %d",x,y,*y);
- }
б)
void func(){
/* объявления и инициализация пропущены */
*x=y;
/* вывод пропущен */
}
- #include <stdio.h>
- using namespace std;
- void func() {
- int *x,y;
- y = 500;
- *x = y;
- printf("x = %d y = %d, *x = %d",x,y,*x);
- }
в)
void func()
{
/* объявления и инициализация пропущены */
x=&y;
/* вывод пропущен */
}
- #include <stdio.h>
- using namespace std;
- void func() {
- int *x;
- int y = 0;
- x = &y;
- printf(" x = %d y = %d, &y = %d",x,y,&y);
- }
2.Объясните смысл выражений с указателями: воспользовавшись графическим представлением переменных, значений и указателей изобразите состояние памяти после вычисления выражений в каждом случае.
а) int x[5],*p; p=x+1;
б) int x=1; int*y=&x;
в) int x;int y[3]={1,2,3}; x=*(y+2); г) int **x,*y,z=0;x=&y;y=&z;
д) int r1[2]={11,12};int r2[2]={21,22}; int
*m[2]={r1,r2};
е) char* s=”123”;char c=*(s+3);
3.Напишите код на языке Си для выделения памяти под двумерный массив чисел типа int в динамической памяти (куче). Далее запишите код функции, на вход которой подаются указатель на этот массив, индексы элемента в массиве. Функция возвращает значение элемента массива, соответствующее переданным индексам. Индексация элементов - с нуля.
Варианты размещения:
а) построчное размещение элементов в памяти;
- #include <iostream>
- #include <stdlib.h>
- int func(int *t, int i, int j, int n){
- return *(t+i*n+j);
- }
- int main(){
- int *t;
- int n = 10;
- int m = 10;
- t = (int*) malloc(n*m*sizeof(int));
- for (int i = 0; i< n; i++){
- for (int j = 0; j<m; j++){
- *(t+i*n+j)=10*i+j;
- std::cout<<*(t+i*n+j)<<" ";
- }
- std::cout<<" \n ";
- }
- for (int i = 0; i < m*n; i++){
- std::cout<<*(t+i)<<" ";
- }
- std::cout<<func(t,2,3,n)<<" \n ";
- return 0;
- }
б) постолбцовое размещение элементов в памяти;
- #include <iostream>
- #include <stdlib.h>
- int func(int *t, int i, int j, int n){
- return *(t+j*n+i);
- }
- int main(){
- int *t;
- int n = 10;
- int m = 10;
- t = (int*) malloc(n*m*sizeof(int));
- for (int i = 0; i< n; i++){
- for (int j = 0; j<m; j++){
- *(t+j*n+i)=10*i+j;
- std::cout<<*(t+j*n+i)<<" ";
- }
- std::cout<<" \n ";
- }
- std::cout<<func(t, 2,3,n)<<" ";
- return 0;
- }
в) древовидное размещение (массив указателей на одномерные массивы).
- #include <iostream>
- #include <stdlib.h>
- int func(int **t,int i, int j){return *(t[i]+j);}
- int main(){
- int **t;
- int n = 10;
- int m = 5;
- t = (int**) malloc(n*sizeof(int*));
- for (int i = 0; i< n; i++){
- t[i] = (int*) malloc(m*sizeof(int));
- for (int j = 0; j<m; j++){
- *(t[i]+j)= 10*i+j;
- std::cout<<*(t[i]+j)<<" ";
- }
- std::cout<<" \n ";
- }
- std::cout<<func(t,3,2);
- return 0;
- }
4. Имеется программа на языке Си
/* программа в одном файле */ #include <stdio.h>
int x=123;
int main(int,char**){printf(“%d\n”,x)}
Разделите программу на два файла таким образом, чтобы определение переменной x содержалось в одном файле, а ее использование (вывод на печать) – в другом.
- A.cpp
- #include <stdio.h>
- int x=123;
- B.cpp
- #include <stdio.h>
- extern int x;
- int main(int,char**){printf(“%d\n”,x)}
5. Имеется два фрагмента кода на языке Си:
а) int fun1(){ int x=0; x++; return x; }
- for (int i=0; i<5; i++){
- std::cout<<fun1();}
// out: 11111
б) int fun2(){ static int x=0; x++; return x; }
- for (int i=0; i<5; i++){
- std::cout<<fun2();}
// out: 12345
В чем различие функций? Приведите контекст вызова, демонстрирующий разницу между ними.
6. Имеется два фрагмента кода на языке Си:
а) int fun1(){/*реализация пропущена*/}
б) static int fun2(){/*реализация пропущена*/}
В чем различие функций? Приведите пример, демонстрирующий разницу между ними.
Статическая функция видна другим функциям в пределах единицы трансляции(в одном файле).
7.С использованием модификаторов __declspec(dllimport) и __declspec(dllexport) напишите минимальный код
приложения, использующего код произвольной функции, импортируемой из динамической библиотеки:
а) случай неявного связывания (выполняемого загрузчиком при анализе заголовка исполняемого файла);
#ifdef MYDLL_EXPORTS#define MYDLL_API __declspec(dllexport)#else#define MYDLL_API __declspec(dllimport)#endif // Переменнаяextern MYDLL_API int Var; // ФункцияMYDLL_API void Function(int, int);б) случай явного связывания (вызовами LoadLibrary и GetProcAddress).
//Load the DLL
HMODULE lib = LoadLibrary("testing.dll");
//Create the function
typedef void (*FNPTR)();
FNPTR myfunc = (FNPTR)GetProcAddress(lib, "myfunc");
//EDIT: For additional safety, check to see if it loaded
if (!myfunc) {
//ERROR. Handle it.
}
//Call it!
myfunc();
8.Имеется фрагмент кода (по листингу из отчета), создающий новый поток исполнения. Переделайте код таким образом, чтобы при создании потока в параметр функции потока записывалось целое число. Выведете это число на печать из функции потока.
- #include <windows.h>
- #include <iostream.h>
- DWORD WINAPI newthread(LPVOID iNum)
- {
- cout << "Thread is started." << endl;
- сout<<(int)iNum;
- cout << "Thread is finished." << endl;
- return 0;
- }
- int main()
- {
- int theinteger = 10;
- HANDLE hThread;
- DWORD IDThread;
- cout << "n = " << n << endl;
- hThread = CreateThread(NULL, 0, newthread, (void*)theinteger, 0, &IDThread);
- if (hThread == NULL)
- return GetLastError(); // ждем пока поток function закончит работу
- WaitForSingleObject(hThread, INFINITE); // закрываем дескриптор потока function
- CloseHandle(hThread);
- return 0;
- }
9.Напишите код с использованием Win32 API функций, реализующий простейшую конструкцию параллельного программирования «разветвление-слияние».Как можно организовать ожидание завершения вторичного потока?
- //include
- DWORD a = 5;
- DWORD b = 4;
- DWORD c = 3;
- HANDLE threads[2]; // 2 потока
- int main(){
- DWORD idThr1, idThr_2, ids;
- HANDLE thr1 = CreateThread(Null,0, thr1func,a,0,&idThr1);
- threads[0]= thr1;
- DWORD idThr1, idThr_2, ids;
- HANDLE thr2 = CreateThread(Null,0, thr2func,b,0,&idThr2);
- threads[0]= thr2;
- ids = WaitForMultipleObjects(2,threads,TRUE,-1);
- CloseHandle(thr1);
- CloseHandle(thr2);
10.Объясните работу программы по листингу из Вашего отчета по лабораторной работе №8.