《C陷阱与缺陷》读书笔记
最近花了一点时间阅读了《C陷阱与缺陷》 ,东西不多,有些标题就够了,
自己总结下需要记录的,以后没事看看。
自己敲的,虽然有误与不足,转载请说明,附原文链接
第 0 章 导读
无
第 1 章 词法“陷阱”
本章都是一些,拼写错误,主要是仔细,别误写即可。
1.1 =不同于==
比较运算符与赋值运算符的相互误写
1.2 &和|不同于&&和||
按位运算符与逻辑运算符的混用
1.3 词法分析中的“贪心法”
1)“大嘴法”:每一个符号应该包含尽可能多的字符;
a---b 意思是:(a--)-b
2)注释
1.4 整型常量
整型变量开头字符是0,实则为八进制数。
1.5 字符与字符串
1)单引号的为字符,实则为整数,为ASCII字符集。
2)双引号的为字符串,代表一个指向无名数组起始字符的指针,该数组被双引号中的字符和二进制为零的’ ’初始化。
Practice:
1.某些C编译器允许嵌套注释,写一个测试程序:
例如:/*/**/”*/”:允许嵌套,等效于一个引号;不允许,等效于字符串“*/”;
所以为了测试该编译器是否允许嵌套注释,而且不报错:
/*/*/0*/**/1
如果允许嵌套: /* /*/0*/ **/ 1 值为1:
如果不允许嵌套: /* / */ 0 * / **/ 1 值为0*1=0;
2.n-->0含义n-- >0,为什么不是n- ->0?
根据大嘴法,--作为单个符合;
3.a+++++b含义
a++ + ++b;
若是根据大嘴法,a++ ++ +b;语法是不正确的;
等价于((a++)++)+b,a++的结果是不能作为左值的,编译器不会接受。
第 2 章 语法“陷阱”
2.1 理解函数声明
任何C变量的声明都由两部分组成:类型以及一组类似表达式的声明符。
1)float *g(),(*h)();()优先级高于*,所以g是一个函数,该函数的返回值类型为指向浮点数的指针。同理,h是一个函数指针,h所指向的函数的返回值为浮点类型。
2)分析(*(void(*)())0)()
(*fp)();fp是一个函数指针,*fp该指针指向的函数;
(*0)(),指向返回值为void类型的函数指针。(*fp)()的值为void,fp的声明如下:
void (*fp)(); 用(void(*)())0替换fp;
(*(void(*)())0)();
或者 typedef void (*fun)();
(*(fun)0)();
假定sig是一个整数,(*sfg)(sig)值为void类型,可以声明sfg;
void (*sfg)(int);后面int为函数的参数;
void ( *signal(int , void(*)(int) ) (int);
2.2 运算符的优先级问题
If(flag &FLAG!=0) !=优先级高于&;
R=hi>1);
if(x*mid)
lo=mid+1;
else
return mid;
}
return NULL;
}
第 4 章 连接
一个C程序可能是由多个分别编译的部分组成,这些不同部分通过一个通常叫做连接器的程序合并成一个整体。
4.1 什么是连接器
C重要思想:分别编译;
处理命名冲突:干脆完全禁止
4.2 声明与定义
int a;如果其位置所有函数体之外,被称为外部对象a的定义,分配存储空间,初始值为0;
extern int a;引用a,其存储空间在其他地方。
4.3 命名冲突与static修饰符
两个具有相同名称的外部对象实际上代表的是同一个对象。
static修饰符是一个能减少此类命名冲突的有用工具,可修饰变量和函数。
static int a;a的作用域限制在一个源文件内,其他源文件,a是不可见。
4.4 形参、实参与返回值
float自动转为doub,short或char转为int类型。
4.5 检查外部类型
4.6 头文件
声明放头文件,#include “file.h”
第 5 章 库函数
5.1 返回整数的getchar函数
getchar返回整数,若是char,无法容下,被截取;
5.2 更新顺序文件
5.3 缓冲输出与内存分配
5.4 使用ernlo检测错误
5.5 库函数signal
Setjmp,longjmp
第 6 章 预处理器
注意介绍宏,使用函数造成开销,宏只是对程序的文本起作用。
6.1 不能忽视宏定义中的空格
6.2 宏并不是函数
注意加括号,防止优先级问题,
宏展开可能产生庞大的表达式,占用空间远远超过了期望的空间
6.3 宏并不是语句
6.4 宏并不是类型定义
#define f int,可移植性好,但是声明多个变量出现问题;
Practice
实现max,只被求值一次;
定义临时变量
static int t1,t2;
#define max(a,b) (t1=(a),t2=(b),t1>t2?t1:t2)
第 7 章 可移植性缺陷
C程序能够在不同的环境中移植
7.1 应对C语言标准变更
函数原型
7.2 标识符名称的限制
C实现必须能够前6个字符不同的外部名称;,定义没有区分大小写
7.3 整数的大小
不同类型整数的相对长度定义:
1、3种类型的整数其长度非递减的:short、int、long,long至少32位
2、一个普通的整数(int)足够容纳任何数字下标
3、字符长度由硬件特性决定
7.4 字符是有符号整数还是无符号整数
7.5 移位运算符
向右移位,0或者1填充
7.6 内存位置0
null指针不指向任何对象
7.7 除法运算时发生的截断
余数与被除数的正负号相同
h=n&HASHSIZE
最好:h=(n+HASHSIZE)%HASHSIZE
7.8 随机数的大小
rand(),返回0到2^15-1的整数,有的为31位;
7.9 大小写转换
7.10 首先释放,然后重新分配
7.11 可移植性问题的一个例子
第 8 章 建议与答案
8.1建议
8.2答案
附录A:PRINTF,VARARGS与STDARG
附录B:Koenig和Moo夫妇访谈
C++程序员建议:
1、避免使用指针
2、提倡使用程序库
3、使用类表示概念
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net