第五题:
void foo(int[][3]); int main(void) { int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; foo(a); printf("%dn", a[2][1]); return 0; } void foo(int b[][3]) { ++b; b[1][1] = 9; } |
其实和前一题有异曲同工之妙,++b的步长实际上是3个int,也就是++b运算以后,b指向{4,5,6}这个数组的开始,而b[1]就是{7,8,9}, b[1][1]实际上就是8这个值也就是main函数中的a[2][1].
第六题:
int a, b, c, d; a = 3; b = 5; c = a, b; d = (a, b); printf("c=%d ", c); printf("d=%dn", d); |
这个其实有两个C语言知识点,一个是等号操作符优先级高于逗号操作符,另一个是逗号操作符相当于运算逗号前半部后半部的表达式,然后返回后半部表达式的值。所以c等于a(先计算等号),而d等于b(逗号表达式返回b)。
第七题:
int a[][3] = {1, 2, 3, 4, 5, 6}; int (*ptr)[3] = a; printf("%d %d ", (*ptr)[1], (*ptr)[2]); ++ptr; printf("%d %dn", (*ptr)[1], (*ptr)[2]); |
依然是2维数组相关题目,ptr为指向int [3]数组的指针,首先指向a[0],所以(*ptr)[1], (*ptr)[2]就是a[0][1], a[0][2].然后++ptr,相当于ptr指向了a[1],这时得到的是a[1][1],a[1][2],所以结果就是2,3, 5, 6。
第八题:
int *f1(void) { int x = 10; return &x; } int *f2(void) { int *ptr; *ptr = 10; return ptr; } int *f3(void) { int *ptr; ptr = malloc(sizeof *ptr); return ptr; } |
这里考的是返回一个指针的问题,一般来说返回指针的函数,里面一定有malloc之类的内存申请操作,传入指针类型,则是对指针指向的内容做修改。如果想修改指针本身,那就要传入指针的指针。
第九题:
int i = 3; int j; j = sizeof(++i + ++i); printf("i=%d j=%dn", i, j); |
这道题考的内容其实就是sizeof,如果计算表达式,那么表达式是不会做计算的,也就是不管加加减减,sizeof就是针对i计算大小。在32位机器上,这个j应该为4。
我将代码扩展了一下,看看大家能不能想到结果:
short m; int n; double dn; int j = sizeof ( m + n); int k = sizeof ( n + n); int l = sizeof ( m); int l2 = sizeof (m * m); int l3 = sizeof (m + dn); int l4 = sizeof (m + m); |
第十题:
void f1(int*, int); void (*p[2])(int*, int); int main(void) { int a = 3; int b = 5; p[0] = f1; p[1] = f1; p[0](&a, b); printf("%d %d ", a, b); p[1](&a, b); printf("%d %dn", a, b); return 0; } void f1(int *p, int q) { int tmp = *p; *p = q; q = tmp; } |
函数指针的数组p勉强算是一个知识点,另外一个知识点就是第八题提到的,对于int q这样的参数,是不会修改其内容的。而*p则可修改p指向的内容。