C语言支持按位布尔运算,其可运用到任何”整型”的数据类型上.
C提供了一系列的逻辑运算||,&&,和!,分别对应于命题逻辑中的OR,AND和NOT运算,但是它们的功能是完全不同的.逻辑运算认为所有非零的参数都表示TRUE,而零参数表示FALSE.它们返回1或者0,分别表示结果为TRUE或者为FALSE.
按位运算只有在参数被限制为0或者1时,才和与其对应的逻辑运算有相同行为.逻辑运算符&&和||,如果对第一个参数求值就能确定表达式结果,那么逻辑运算符就不会对第二个参数求值.因此,例如表达式a&&5/a将不会造成被零除,而表达式p&&*p++也不会导致间接引用空指针.
C提供了系列的移位运算,以向左或者向右移动位模式.对于一个位表示为[xn-1,xn-2,...,x0]的运算数x,C表达式x<<k会生成一个值,其位表示为.也就是说,x向左移动k位,丢弃k个最高位[xn-k-1,xn-k-2,...,x0,0...,0 ],并在右端补了k个0.移位量应该是一个0~n-1之间的值.移位运算从左至右结合,所以x<<j<<k等价于(x<<j)<<k.注意运算符的优先级:1<<5-1应该按照1<<(5-1)而不是(1<<5)-1来求值.
有一个相应的右移运算x>>k,但是它的行为有点微妙.一般而言,机器支持两种形式的右移:算术右移和逻辑右移.逻辑右移在左端补k个0,得到的结果是[0,...,0,xn-1,xn-2,...,xk ],.算术右移在左端补k个最高位的拷贝.得到的结果是[xn-,...,xn-,xn-1,xn-2,...,xk].算术右移对有符号整数数据的运算很有用.
C标准并没有明确定义应该使用哪种类型的右移.对于无符号数,右移必须是逻辑的.而对于有符号数据,算术的逻辑的都可以.这意味着任何一种或者另一种右移形式的代码都潜在地会遇到可移植性问题.实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,且许多程序员也都假设使用这种右移.
一些应用:
参考:
<<深入理解计算机系统>>(修订版)第2章 [美]Randal E.Bryant David O’Hallaron 著
龚奕利 雷迎春 译