第十一题:
void e(int); int main(void) { int a = 3; e(a); putchar('n'); return 0; } void e(int n) { if (n > 0) { e(–n); printf("%d ", n); e(–n); } } |
这道题自己debug一下就完全明白了,主要知识点就是递归调用,另外前置后置自减操作的返回值问题。
第十二题:
typedef int (*test)(float*, float*); test tmp; |
也是经常出现的一类题,对复杂的指针定义做解析,实际上K&R里面(5.12)也有介绍该如何解读。不熟悉的朋友可以试着练习练习标准库中的bsearch,qsort以及signal函数。
第十三题:
char p; char buf[10] = {1, 2, 3, 4, 5, 6, 9, 8}; p = (buf + 1)[5]; printf("%dn", p); |
也就是p实际指向*(buf + 1 + 5),写的更诡异一些就是p=5[buf +1];也是同样结果。
第十四题:
类似十三题,也是把数组弄得有些诡异,(p += sizeof(int))[-1];相当于*(p + sizeof(int) + (-1))。
第十五题:
int ripple(int n, …) { int i, j, k; va_list p; k = 0; j = 1; va_start(p, n); for (; j < n; ++j) { i = va_arg(p, int); for (; i; i &= i – 1) ++k; } return k; } int main(void) { printf("%dn", ripple(3, 5, 7)); return 0; } |
这道题也是两个知识点,一个是可变参数函数定义以及如何实现,va_arg会把5,7依次取出来。另一个知识点是i &= i-1,实际上是计算了i二进制形式中1的个数,每次计算都会消减掉最低有效位上的1。比如7二进制表示为111。i &= i –1的计算结果依次为110,100, 000 (也就是0)。在hacker's Delights这本书里介绍了很多类似技巧。
第十六题:
int counter(int i) { static int count = 0; count = count + i; return count; } int main(void) { int i, j; for (i = 0; i <= 5; i++) j = counter(i); printf("%dn", j); return 0; } |
只要了解静态局部变量的真正内涵,这道题就是小菜啦。