第5章 操作符和表达式
5.1 简介
5.2 收获
5.2.1 移位操作符的填充问题
左移n位,在右侧补充n个0
右移有两种方案。一是逻辑移位,左边移入的位用0填充;二是算术移位,左边移入的位由原先该值的符号位决定,符号位为1则移入的位均为1,符号位为0则移入的位均为0,这样能够保证原数的正负形式不变。
如果一个程序使用了有符号数的右移位操作,它就是不可移植的
5.2.2 赋值时的截短问题
EOF
需要的位数比字符型值所能提供的位数要多,这也是getchar
返回一个整型值
而不是字符值
的原因。然而,把getchar
的返回值首先存储于char
中将导致它被截短。然后这个被截短的值被提升为整型并与EOF
进行比较。当这段存在错误的代码在使用有符号字符集的机器上运行时,如果读取了一个值为\377
的字节时,循环将会终止,因为这个值截短再提升之后与EOF相等。当这段代码在使用无符号字符集的机器上运行时,这个循环将永远不会停止!
5.2.3 C没有显示的布尔值
C语言使用整数
代替布尔值
,规则零是假,任何非零值皆为真
避免混合使用整型值和布尔值
若一个变量用于表示布尔值,不要通过把它与任何特定的值进行比较来测试这个变量是否为真值,哪怕是与TRUE
或FALSE
。相反,应该像下面测试
5.2.4 操作符优先级
术语lexp表示左值表达式,rexp表示右值表达式。记住,左值意味着一个位置,而右值意味着一个值。
5.2.5 操作符容易出问题的地方
- 使用=替代了==
- 使用|替代了||,使用&替代了&&
- 有符号值的右移位操作是不可移植的。
- 连续赋值中各个变量的长度不一,意义不同
- 移位操作的位数不能是负数
- 编写了一个结果依赖于求值顺序的表达式,大忌啊!
5.2.6 编程好习惯
- 使用
复合赋值符
可以使程序更易于维护 - 使用
条件操作符
替代if
语句以简化表达式 - 使用
逗号操作符
来消除多余的代码 - 不要混用整型和布尔型值