1.声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是( )💗
A.(int *p[10])(int*)
B.int [10]*p(int *)
C.int (*(*p)[10])(int *)
D.int ((int *)[10])*p
C正确。*先和p结合表明是一个指针,然后(*p)与[10]结合表明指向含有事业元素的数组的指针,类型是int(*)(int *),每个元素类型是函数指针,函数的返回值是int,参数是int *。
2.关于回调函数描述错误的是( )💗
A.回调函数就是一个通过函数指针调用的函数
B.回调函数一般通过函数指针实现
C.回调函数一般不是函数的实现方调用,而是在特定的场景下,由另外一方调用。
D.回调函数是调用函数指针指向函数的函数。
D错误。回调函数是调用函数指针指向的函数。
3.(多选)下面test函数设计正确的是:( )💗
char* arr[5] = {"hello", "bit"};
test(arr);
A.void test(char* arr);
B.void test(char** arr);
C.void test(char arr[5]);
D.void test(char* arr[5]);
B、D正确,因为arr是char*的数组,函数传参需要二级指针接收
4.下面程序的结果是:( )💗
int main() { int aa[2][5] = {10,9,8,7,6,5,4,3,2,1}; //&aa取出的是整个数组的地址,&aa+1表示跳过一整个数组后的地址 int *ptr1 = (int *)(&aa + 1); //aa表示二维数组第一行的地址,+1则表示二维数组第二行的地址,相当于aa[1]==5 int *ptr2 = (int *)(*(aa + 1)); *(ptr2-1)表示向前移动一个字节解引用,也就是6 printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1)); //*(ptr-1)表示的是数组跳过一整个数组的地址向前移动一个字节,访问到的是1的地址,解引用得到1 return 0; }
A.1, 6
B.10, 5
C.10, 1
D.1, 5
所以结果 A正确。
5.下面代码中print_arr函数参数设计哪个是正确的?( )💗
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10}; print_arr(arr, 3, 5);
A.void print_arr(int arr[][],int row, int col);
B.void print_arr(int* arr, int row, int col);
C.void print_arr(int (*arr)[5], int row, int col);
D.void print_arr(int (*arr)[3], int row, int col);
A.修改为void print_arr(int arr[][5],int row, int col);B.形参是二维数组,错误。C.正确,形参是数组指针。D二维数组不可以省略列,所以3改为5
6.下面程序的结果是:( )💗
int main() { int a[5] = {5, 4, 3, 2, 1}; %a取到整个数组的地址,+1表示跳过整个数组的大小 int *ptr = (int *)(&a + 1); //*(a+1),a表示数组首元素的地址,+1表示向后跳一个字节的大小,即a[0]+1==a[1]==4 //ptr等于a[5]的地址,-1表示向前跳一个字节的大小,也就是a[5]-1==a[4]==1 printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; }
A.5, 1
B.4, 1
C.4, 2
D.5, 2
B正确。