P16
分析(*(void(*)())0) ();
第一步:拆分(*(void(*)())0)
和()
。说明这是一个函数,函数没有传入参数,而函数入口是前者指针所指向的地址。
第二步:继续拆分可分为两部分,(void(*)())
和(*0)
,后者表示,对取地址0
的内容,在本式中该地址内容就是函数的入口,而前者就是一个强制类型转换
第三步:分析(void(*)())
,它所修饰的变量表示“一个返回值为空的函数指针”。结合第二步,所以0
就是一个“一个返回值为空的函数指针”。
综上所述,该语句表示执行0
地址的函数。 若用typedef
可以简化语句。
typedef void(*A)();
(*(A)0) ();
P38
有两个字符串s和t,将其连接成单个字符串r?
char *r;
r = malloc(strlen(s) + strlen(t) + 1);
if (!r){
exit(1);
}
strcpy(r, s);
strcat(r, t
//用完后);
free(r);
该程序有三个细节值得注意:
- 使用
malloc
函数申请完内存后,需要检查申请是否成功 - 字符串最后会以
/0
结尾,所以申请内存的时候需要多申请一个字符空间。 - 使用完申请的内存空间后,需要释放掉,防止内存泄漏。
P61
判断两个非负整数相加是否溢出
//错误,当发生溢出时,所有关于结果如何的假设都不再靠谱
if(a + b < 0)
complain();
//正确
if((unsigned int)a + (unsigned int)b < INT_MAX)
complain();
//正确
if(a < INT_MAX - b)
complain();