C语言的各类运算概述
C语言的一个很有用的特性就是支持按位布尔运算。
位级运算:
对char数据类型表达式求值的例子:
逻辑运算:逻辑运算符||、&&和!,分别对应于命题逻辑中的OR、AND和NOT 运算。逻辑运算认为所有非零的参数都表示TRUE,而参数0表示FALSE,它们返回1或者0,分别表示结果为TRUE或者 为FALSE。如果对第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值。
移位运算:x<<k,x向左移动左位,丢弃最高的上位,并在右端补上个0, 移位运算是从左至右可结合的。 一般而言,机器支持两种形式的右移:逻辑右移和算术右移。逻辑右移在左端补k个0, 算术右移是在左端补k个最高有效位的值。
C语言标准并没有明确定义应该使用哪种类型的右移。对于无符号数据右移必须是逻辑的。而对于有符号数据(默认的声明的整型对象),算术的或者逻辑的右移都可以。实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,且许多程序员也都假设机器会使用这种右移。Java对于如何进行右移有明确的定义。表达式x>>k会将x算术右移k个位置, 而x>>>k会对x做逻辑右移。
移动k位:对于一个由w位组晟的数据类型,如果要移动k>w位,通过计算k mod w得到的. 对于c程序来说是没有一保证的,所以移位数量应该保持小于字长,Java特别要求位移数量应该按照我们前面所讲的求模的方法来计算。
练习题:
答案:
第一步: a, a^b
第二步:a^(a^b)=b,a^b
第三步:b,b^(a^b)=a
答案:
A:first=k+1,last=k+1
B:因为此时结果为a^a=0;
C:for(first,=0,last=cnt-1;first<last;first++,last--)
inplace_swap(&a[first],&a[last]);
答案:
A:x&0x000000FF
B:x^ (~0x0FF)
C:x|0xFF
答案:
bis(x,y)
bis(bic(x,y),bic(y,x))
答案:
X=0x66=0110 0110
Y=0x39=0011 1001
x&y=0010 0000=0x20
x|y=0111 1111=0x7F
~x|~y=1001 1001|1100 0110=1101 1111=0xDF
x&!y=0x00
x&&y=0x01
x||y=0x01
!x||!y=0x00
x&&~y=0x01
答案:
if(!(x^y)&&(x&(~y)))
填写下表,说明不同移位运算对单字节数的影响。思考移位运算的最好方式是使用二进制表示。将最初的值转换为二进制执行移位运算,然后再转换回十六进制。每个答案都应该是8个二进制数字或者2个十六进制数字。
答案:
1100 0011 0001 1000 0x18 0011 0000 0x30 1111 0000 0xF0
0111 0101 1010 1000 0xA8 0001 1101 0x1D 0001 1101 0x1D
1000 0111 0011 1000 0x38 0010 0001 0x21 1110 0001 0xE1
0110 0110 0011 0000 0x30 0001 1001 0x19 0001 1001 0x19