学习日记 - 《C陷阱与缺陷》 - Day 0
标签(空格分隔): 学习日记 《C陷阱与缺陷》
以下是废话
这个标题看上去有点厉害,一眼看起来是批判C的缺陷的一本书,但是,并不是。
看上去这本书很厉害,但是看看简介真的很厉害,书的作者是Andy,书中是这样评价他的
“Andy是世界上最出色的几位C++专家之一”
哦,确实厉害。
第一章 词法 “陷阱”
编译器负责将程序分解为一个一个符号的部分, 也就是说对于同一个符号,也有可能被分解为不同的部分。
比如 &
和 &&
就同一个符号,但是表达成的意思不同,分解的时候也是不同的。
1.1 = 不同于 ==
赋值运算符 和 比较运算符 区别
一般语言的 赋值运算符 都是 =
(更加常用)
而 比较运算符 就各有不同,比如 ==
或 :=
(Pascal、Ada等)
一般的比较写法:
while (x = y)
显式的比较写法:
while ((x = y) != 0)
1.2 & 和 | 不同于 && 和 ||
同 = 与 == 一样
按位计算符 & 、 |
逻辑运算符 && 、 ||
1.3 词法分析中的“贪心法”
编译器读取字符的方法可以形象地成为“贪心法”,或者是“大嘴法”。
通俗点说就是一直读取直至不能组成一个字符串。
这样的话,我们就要注意这些问题了
比如 == 是单个符号, 而 = = 却是两个符号,因为编译器读到了空格,把读到的就组成了一个字符。
看看一个例子
问:下面代码的输出效果一样吗?
a---b;
a -- -b;
a - -- b;
事实上,第一二行结果是一样的,但是第三行却是不同的。
再看一个例子
y = x/*p; //*p指向除数
按照注释的意思,这段代码的本意是用x除以p指向的值(指针)
但是
编译器会把/*理解成注释的开始(然后代码就给狗吃了)
所以,我们应该写成
y = / *p; //*p指向除数
或者
y = / (*p); //*p指向除数
到这里,应该理解到代码编写规范里面 运算符左右要留一个空格的重要性了吧
(老版的编译器还会把 =+ 理解为运算符,这个对于 a=+1 的话就有歧义了,还有 =/* 、 >>= 等稀奇古怪的错误) 逃)
1.4 整形变量
当整数常量的第一个数字为0的话,编译器就会把它看做是八进制数,所以 10 与 010 的意义是完全不同的
(有些编译器会把 099也看成八进制数的,也就是 9*8+9,结果和本意完全背离,ISO C是禁止这种写法的)
(注意不要为了对齐而把变量补0….)
1.5 字符和字符串
注意:单引号和双引号的含义迥异
单引号括起的一个字符是 整数
双引号括起的一个字符串代表 一个指针
printf('\n');
这是一个典型的错误…(逃
x = 'abc';
这样的写法x是a还是c要看编译器的心情了(取决于不同的编译器)…
dalao:在很多动态语言里面。字符串都允许是’ ’ 或者” “括起来的
最后
a+++++b;
这代码的含义是什么?
你猜?
(逃,其实编译不出来..