《C陷阱与缺陷》读书笔记
Posted 功不唐捐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《C陷阱与缺陷》读书笔记相关的知识,希望对你有一定的参考价值。
这本书很薄,仅有150来页,打算花上这个下午时间来消化。下面是读书笔记:
第1章 词法陷阱
- 词法分析中的贪心算法:每个符号应该包括尽可能多的字符。因此,注释的嵌套是不允许的。
第2章 语法陷阱
- int (*fp)()中的fp是一个函数指针,指向返回为int的类型的函数。原因在于()的优先级高于*;而 int *fp()中的fp是一个返回类型为指针的函数;
- (void)(*)()的含义: (void)(*fp)()中,fp是一个指向返回类型为void的函数的指针,去掉fp后,(void)(*)()指的是这种指针的类型。
- 理解 (*(void)(*)())0() 的含义:首先利用void)(*)()对0进行强制转换,使“0”称为指针类型,然后使用“*”解引用,其实质为(*cast(0) ) (),还是对函数指针的一个使用;
- 运算符的优先级中,最重要的两点:a,总则:0目(数组下标,函数调用,结构成员选择) > 单目 > 双目(算术,移位,关系依次递减) > 三目 > 赋值;b,任何一个逻辑运算符的优先级低于任何一个关系运算符;b,移位运算符的优先级比算术运算符低,但是比关系运算符高。
第3章 语义陷阱
- 数组和指针:在讲数组作为函数的参数传递的时候,数组会自动被转化为指针的形式。
- 在C语言中将一个整数转换为一个指针,最后得到的结果取决于具体的C编译器的实现。
- 通常,#define NULL 0;当常数0被转换为指针使用的时候,这个指针绝对不能被解引用(dereference)。换句话说,当我们将0赋值给一个指针变量,绝对不能企图使用该指针所指向的内存中存储的内容。
- 整数溢出:若a和b为非负整数,检查a+b是否会溢出? a+b < 0 是不能正确执行的。如某些机器上,数据运算的结果为正/负/零/溢出四种,则a+b时,内部寄存器会出现溢出而不是负,则if检查失败。正确方式是将a和b都转换成无符号整数。if((unsigned)a + (unsigned) b > INT_MAX),其中INT_MAX在<limits.h>中所定义。或者 if(a > INT_MAX -b)。
第4章 连接
- 链接器的作用:输入一组目标模块和库文件,输出一个载入模块。其主要作用是解决命名冲突。
- static修饰符作用有二:其一是声明变量或者函数是静态的;其二是被static修饰的变量或者函数只能在改源文件内引用。换句话说,如果一个函数仅仅被同一个源文件的其他函数调用,就应该声明该函数为static。这样可以避免与标准库文件中的外部对象名称发生冲突。
- 如果一个未标明的标识符后面跟一个开括号,那么它将被视为一个返回整型的函数。
- 每个外部对象只在一个地方声明。这个声明的地方一般就在一个头文件中,需要用到该外部对象的所有模块都应该包括这个头文件。特别需要指出的是定义该外部对象的模块也应该包括这个头文件。
第5章 库函数
- signal信号处理函数需要尽可能的简单。
第6章 预处理器
- 不能忽视宏定义中的空格。
- 宏并不是函数。
- 宏并不是语句。
- 宏不是类型定义。定义类型请使用typedef。
第7章 可移植性缺陷
第8章 建议与答案
以上是关于《C陷阱与缺陷》读书笔记的主要内容,如果未能解决你的问题,请参考以下文章