1. 词法分析
贪心法:尽可能的多读字符
符号中间不应有空格
y = x/*p; /*p …/*/
y = x;
整型常量,第一个字符加0是为八进制
x = 026; // x = 32d
2. 语法分析
运算符优先级
操作符 [] () ->
单目 (从右到左)
双目 (算术、移位、关系、逻辑 )
三目
赋值 (自右向左)
逗号
switch break;
刻意省略break;
eg: case sub:opnd2 = -opnd2;
case add: ……break;
函数调用即使不带参数也应该包括参数列表,f()调用函数, f的地址.
3. 语义分析
空指针: 绝对不能使用NULL内容.
边界问题: 使用不对称边界
- 最简单的例子
- 仔细计算边界
求值顺序 f(x, y) 不是逗号运算
g((x, y)) 是逗号运算
数组下一个元素取地址是合法的.
整数溢出情况 if (a > INT_MAX - b) //a+b 溢出
4. 连接
外部变量: 声明类型必需一样
static 只在一个源文件可见
6. 预处理
1. 宏定义中每个参数都用括号括起来,整个表达式用括号括起来
2. 宏中自增自减,不要使用
3. 宏产生的表达式可能很大
4. 检查宏是否合理,最好就是产开进行检查
5. 宏 并不是函数 优点比调用函数快。
7. 可移植性
1. 移位计数 0 <= count < n
2. -1 >>1 != 0; //非负进行移位
-1/2 =0;
3. NULL 中能用于赋值和比较
8. 建议与答案
事先周密思考 (这是我所缺陷的)
在调试程序很长时间之后,疲惫不堪的程序员,开始漫步目的瞎碰,这里试一下,那里试一下,如果碰巧程序可以运行,便万事大吉,这中工作方式往往导致一场灾难。
附录A
%g 保留六位有效数字
1. 大小超过六位 科学计数发 > 999999
2. 位数超过六位 四舍五入 0.6666667
3. 较小的数值 <= -5
4. 精度修饰指定了打印数值中有效数字,如果小数点后不跟数字则小数点也将被删除
%e
1. 小数点后六位有效数字
空白字符
% d 某数是非负数,就在它前面插入一个空格
标志字符 # 只对下列有效
%#x, %#o ‘0x’ ‘0’
%#e E f 小数点会被打印
printf(“%*.*s\n”,12, 5, str); // printf(“%12.5s\n”, str);
%n 指出已经打印出的字符数.