第五章 操作符和表达式
这一章如果没做过玩过单片机、汇编的话,读起来可能比较吃力,尤其是在移位运算符、位运算符应用上。另外多注意一下左值和右值的理解。
总结:
算术操作符、赋值操作符、关系操作符、条件操作符。
短路求值(short-circuited evalution):如||这样的二目操作符,如果它的左操作数是真,右操作数便不再求值。带来的后果是如果右操作数的数组下标不合法,那么也不会报错。
C并不具备显式得布尔类型,布尔值是用整型表达式来表示的。在表达式中混用布尔值和任意的整型值可能会产生错误。要避免这些错误,每个变量要么表示成布尔型,要么表示成整型,不可让它身兼两值。不要对整形变量进行布尔测试,反之亦然。
C没有布尔,用整数代替。0为假,非0为真。
所以有的人经常这样:
#define FALSE 0
#define TRUE 1
..
if(flag == TRUE)...
if(flag)...
但是这样意义不大,如果flag设置为任意的整型值,那么第二对语句就不是等价的,只有当flag确实是True或者False才有意义。
因此如果flag你希望它来代表布尔值,就应该始终把它设置为0或者1。
左值和右值(L-value和R-value),左值往往提供一个内存的位置,但并不是一份拷贝。右值代表一个值,可以是一份拷贝。所以左值也可以是右值,但是右值不能成为左值。
比如:
a++ =b://wrong
b =a++; //right
a++并没有一个内存位置,有人会说a++必然会存在一个内存的位置,但是a++的结果是a的一份拷贝,其位置不certain。所以这个不是左值。
不同类型之间的值需要转换才能操作。
如果某个表达式过于依赖求值的顺序,那么应该尽力去避免,因为不同的编译器会产生不同的求值顺序,所以本质上表达式是不可移植的。
警告:
1、有符号值得右移位值操作时不可移植的。
这对编译器是一个考验,所有无符号的右移同左移一样,他是可移植的,但是如果存在有符号位的右移位操作,如果符号位是1,右移的全是1,如果符号位是0,右移的全是0。
2、移位操作的位数是个负值。
3、连续赋值中各个变量长度不一。
4、误用=而不是==进行比较。
太容易错误了,所以只要有逻辑表达式最好多看一便。
5、误用|替代||,误用&替代&&
位操作符,误用80%出错!
6、在不同的用于表示布尔值的非零值之间进行比较。
见上详述。
7、表达式赋值的位置并不决定表达式计算的精度。
8、编写结果依赖于求值顺序的表达式。
见上!
编程提示:
1、尝试使用以下条件操作符替代if语句以简化表达式。
这样带来的优势很明显,当一个表达式过长的时候,?:;的组合降大大缩短长度。
2、不要混用整型和布尔值。
关于位操作符。。。。嗯嗯,以后有时间在关注它的应用。
C和指针 (pointers on C)——第五章:操作符和表达式