关闭

读《C陷进与缺陷》笔记

标签: c语言
115人阅读 评论(0) 收藏 举报
分类:

无意中觅得的好书,这本书总结了很多程序员的错误经验。


词法“陷阱”

编译器中负责将程序分解为一个一个符号的部分,叫“词法分析器”。


1.显示比较。

当需要对变量赋值后,并检查改变量的新值是否为0时,为了避免编译器的警告,我们应该显示的进行比较。

例如:

if(x = y)
    fun();
应该写作:
if((x = y) != 0)
    fun();
很明显下面的代码意图一目了然。



2.词法分析中的“贪心法”

C语言中的符号,例如/*=,只有一个字符长,称为单字符符号。而例如/*==,称为多字符符号。

当C编译器读入字符/后又跟了一个字符*,那应该做出判断:是当做两个单独字符,还是合起来当做一个字符对待。

C编译器的解决方法就是“贪心法”,一个一个读入字符,如果能合起来组成一个字符,又继续读,直到读入的字符不可能和之前的字符们组成一个有意义的字符。

需要注意的是,(除了字符串、字符常量)符号的中间不能有空白(空格符、制表符、换行符)。
例如见下面表达式:

a---b   等价于 a -- - b    等价于 (a--)-b
而(上面下面不等价)
a - -- b    等价于 a-(--b)

再例如:
想要表达用x除以p指向的值,再把商赋值给y。

y = x/*p        /* p指向除数*/
这个就是错的,编译器会理解成把x赋值给y,它把/*理解为一段注释的开始,并不断读入字符,直到*/出现为止。

y = x / *p      /* p指向除数 */
y = x/(*p)      /* p指向除数 */
这两种才能正确表达意思。



3.字符与字符串

单引号引起的一个字符代表一个整数,整数值为该字符在编码器中采用的字符集中的序列值。对于采用ASCII字符集的编译器而言,'a'的含义与97(十进制)或者0141(八进制)完全一致。

双引号引起的字符串,代表的是一个指向无名数组起始字符的指针。该数组被 双引号之间的字符 和 一个额外的二进制为零的字符'\0' 初始化。
这里写图片描述

printf("Hello \n");
等价于
char h[] = {'H','e','l','l','o',' ','\n','\0'};
printf(h);
等价于
char h[] = {'H','e','l','l','o',' ','\n',0};
printf(h);

这里写图片描述



因为单引号括起的一个字符代表一个整数,而双引号括起的一个字符代表一个指针,所以不能混用。例如:

char *s = '/';

编译器会报错,因为'/'只是一个整数,而不是一个指针。



整型数的存储空间存储空间可以容纳多个字符(一般4个,每个占2位),所以C编译器允许在一个字符常量中包括多个字符。例如:'yes',在VC++6.0中,编译器一个一个读入字符时,将会依次用后一个字符覆盖前一个字符,最后就得到最后一个字符的整数值。例如下图:
这里写图片描述

这里写图片描述

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13302次
    • 积分:409
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:13篇
    • 译文:0篇
    • 评论:4条