《C陷阱与缺陷》读书笔记

本文是自己读《C陷阱与缺陷》过程中的笔记,内容主要摘自原书


1. 当两个有符号整数运算时,“溢出”有可能发生。

例如:ab是两个非负整型变量,检查a+b是否会溢出,可以采用如下方式:

ANCI C标准在<limits.h>中定义了INT_MAX

1if ((unsigned)a + (unsigned)b > INT_MAX)

Complain();

2if (a > INT_MAX – b)

Complain();

 

2. 如果一个函数没有floatshortchar类型的参数,在函数声明中完全可以省略参数类型的说明,但是函数定义中不能省略参数类型的说明,例如:

double square();

int square(int digit)

{

return 0;

}

如果涉及floatshortchar类型参数,声明中没有包含数据类型,float会自动转换为double类型,shortchar会自动转换为int类型。

 

3. C语言规定未定义的标识符后跟一个括号,那么它被视为一个返回整型的函数。例如:

main()

{

double s;

s = sqrt(2);

printf(“%g\n”, s);

}

等同于下面的程序:

extern int sqrt();

main()

{

double s;

s = sqrt(2);

printf(“%g\n”, s);

}

 

4. 每个外部对象只在一个地方声明,一般在一个头文件中,需要用到该外部对象的所有模块都应该包含这个头文件,定义该外部对象的模块也应该包含这个头文件。

 

5. Big Endian:最低地址存放高位字节,内存从最低地址开始,按序存放。 Little Endian:最低地址存放低位字节,内存从最低地址开始,按序存放。

所有的处理器都是按Big Endian存放数据的,内存中根据处理器厂商的不同则不同,有Big Endian也有Little Endian

 

6. fp = fopen(FILENAME, “r+”);通过r+可进行读写操作,但是一个输入操作不能随后直接跟一个输出操作,反之亦然。如要同时进行输入和输出,必须在其中插入fseek函数的调用。

 

7. 库函数signal唯一安全、可移植的操作就是打印一条出错信息,然后使用longjmpexit立即退出程序。

 

8. 当一个程序异常终止时,程序输出的最后几行常常丢失。这是由于异常终止的程序可能没有机会清空输出缓冲区,生成的输出可能位于内存的某个位置,但却永远不会被写出了,可以通过调用setbuf解决这个问题:

setbuf(stdout, (char *)0);

这个必须在任何输出写入到stdout前执行,最佳位置是作为main函数的第一个语句。

 

9. 函数调用的开销比宏调用的开销大。某些常用库函数(如:getcharputchar等)在stdio.h中采用宏实现,同时,在库文件中采用函数形式也进行了实现,因此,不包含stdio.h文件时,对某些常用函数的调用采用的是库文件中的函数调用,导致程序运行效率下降。

 

10. char c -> (unsigned)c,当把char型字符变量,使用(unsigned)c转换类型,不能得到等价的无符号整数。因为在转换过程中,char型字符变量先被转换成int型整数,此时可能得到非预期结果。

 

11. 非负数的移位运算相当于除法,负数的移位运算与除法不等效。(-1)>>1的值-1(-1)/2的值0不同,n > 移位有效值 > 0n为整数的位数。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值