第15章运算符详解
本章介绍很多前面没有讲过的运算符,重点是位运算,然后引出一个重要的概念--Sequence Point,在最后一节总结C语言各种运算符的优先级和结合性。
15.1 位运算
整数在计算机中用二进制的位来表示,C语言提供一些运算符可以直接操作整数中的位,称为位运算,这些运算符的操作数都必须是整型的。在以后的学习中你会发现,有些信息利用整数中的某几个位来存储,要访问这些位,仅仅有对整数的操作是不够的,必须借助位运算,例如附录A第A.2节介绍的UTF-8编码就是如此,学完本节之后你应该能自己写出UTF-8的编码和解码程序。本节首先介绍各种位运算符,然后介绍与位运算有关的编程技巧。
15.1.1 按位与、或、异或、取反运算
在第4.3节中我们讲过逻辑与、或、非运算,并列出了真值表,对于整数中的位也可以做与、或、非运算,&是按位与(Bitwise AND)运算符、|是按位或(Bitwise OR)运算符,~(Tilde)是按位取反(Bitwise NOT)运算符,此外还有^(Caret)是按位异或(Bitwise XOR)运算符,我们在第13.1节中讲过异或运算。下面用二进制的形式举几个例子,如图15.1所示。
注意,&、|、^运算符都是要做Usual Arithmetic Conversion的(其中有一步是Integer Promotion),~运算符也要做Integer Promotion,所以在C语言中其实并不存在8位整数的位运算,操作数在做位运算之前都至少被提升为int型了,上面用8位整数举例只是为了书写方便。比如:
- unsigned char c = 0xfc;
- unsigned int i = ~c;
计算过程是这样的:常量0xfc是int型的,赋给c要转成unsigned char,值不变;c的十六进制表示是fc,计算~c时先提升为整型(000000fc)然后取反,最后结果是ffffff03。注意,如果把~c看成是8位整数的取反,最后结果就得3了,这就错了。为了避免出错,一是尽量避免不同类型之间的赋值,二是每一步计算都要按上一章讲的类型转换规则仔细检查。