《c陷阱与缺陷》4-6章笔记

来源:互联网 发布:2017上半年进出口数据 编辑:程序博客网 时间:2024/06/05 02:19

连接

1、extern 关键字表示对外部对象的引用,其定义只能在程序的某个地方进行,且只能定义一次。另外尽量少使用extern多处引用外部变量,如若干个函数需要共享一组外部对象,可以将这些函数放到一个源文件中,把需要用到的对象也放在同一个源文件中以static修饰符声明,static修饰符可以起到减少命名冲突的作用,函数也一样。

2、如果一个函数在被定义或声明之前被调用,那么它的返回类型默认就是整型,因此在函数调用前就定义或声明所要使用的函数,同时确保其声明的类型是一致的。

3、处理多文件多次声明的问题,比较好的方法是将需要用到的外部对象的所有模块放到头文件中,当需要用到的时候,包含这个头文件即可。


库函数

1、对库函数返回的数据类型、参数类型要清楚,否则会出现“截断”,整型溢出等情况。
比如参数需要的是一个负数,而参入的是sizeof操作表达式,其返回的unsigned值,则必须先将其转换称有符号数再将其反号

2、如要对某个文件同时进行输入和输出操作,必须在其中插入fseek函数的调用,以改变文件的状态。网上有具体分析

3、如要对标准输入输出缓存一定数据量再进行实际操作,可通过setbuf函数实现,直到其缓冲区填满或直接调用fflush。平时调试打印信息如printf注意是否以‘\n’结尾,否则会先缓存直到遇到换行符或缓冲区满才输出打印。

4、警惕函数返回局部声明的数组数据,其在函数退出时,会释放数组内容。如缓冲区是动态分配的,不能忘记最后要释放该缓冲区。

5、再调用库函数的时候,因首先检查作为作为错误指示的返回值,确认程序执行失败,再检测errno值(函数执行成功,但errno被设置,如fopen新建一个并不存在的文件)


预处理器

1、对于一些简单经常会调用到的操作,可实现为宏函数,以提高系统效率(函数调用增加系统开销,分配栈空间等)

2、注意宏定义中的空格,定义的宏与对应的操作以空格隔开,而对应的操作中存在空格不受影响

3、在宏定义中,把每个参数都用括号括起来,同样,整个表达式也应该用括号扩起来,以防止当宏用一个更大一些的表达式可能出现的问题。

4、宏函数调用的时候,确保参数不会引起副作用

5、避免宏展开产生庞大的表达式,换成代码实现也许更合适

6、多语句宏定义可以用 do{…}while(0)

7、不要用宏来定义变量类型,使用typedef,只要清楚宏定义就是字符替换,如

#define T1 struct foo *
T1 a, b; //只有a是指针,b是结构


可移植性缺陷

1、像int、char等类型用typedef定义新的类型,平台发生变动,只需重新改动类型定义即可

2、明确声明字符是有符号整数(unsigned char),还是无符号整数(signed char),否则不同编译器,对于未显示声明的,会做不同的转换。

3、移位运算,如关注向右移位时空出的位,可以将操作的变量声明为无符号类型;如果确定移位运算后的结果非负,可代替除法运算,其执行数度要快的多。

4、注意对负数进行取反的时候,是否可能造成整型溢出(负数的补码最大可表示-2^n,而正数的补码最大可表示2^n-1,对补码的知识可查看这个链接)

0 0
原创粉丝点击