在C语言中,移位运算是双目运算符,属于位运算的范畴,它分为左移(<<)运算和右移(>>)运算两种。
对于左移运算,运算符的左边是移位对象,右边是整型表达式,代表左移的位数。左移时,无论移位对象是有符号数还是无符号数,都是右端(低位)补0,左端(高位)移出的部分舍弃。左移时,如果左端移出的部分不包含二进制数1,则每左移1位相当于移位对象乘以2,左移2位相当于移位对象乘以4。因此当左移后移出部分不包含1时,可以用这一特性代替乘法运算,以加快运算速度。如果移出部分包含二进制数1时,这一特性就不适用。
而右移运算符,运算符左边是移位对象,右边是整型表达式,代表右移的位数。右移时,右端,右端(低位)移出的部分舍弃,而左端分为两种情况:对于无符号整数和正整数,高位补0;对于负整数,高位补1。右移时,如果右端移出的部分不包含二进制数1,则每右移1位相当于移位对象除以2,右移2位相当 于移位对象除以4。因此当右移后移出部分不包含1时,可以用这一特性代替除法运算,以加快运算速度。如果移出部分包含二进制数1时,这一特性就不适用。
掌握移位运算的关键是牢记对于有符号数和无符号数的处理差异。对于左移运算,无论移位对象是有符号数(包括正数和负数)还是无符号数,都是低位补0,高位舍弃。而右移运算则较复杂,若移位对象是无符号数,是高位补0,低位舍弃;若移位对象是有符号数,则要视其正负而定:对于正数(最高位为0),是高位补0,低位舍弃,对于负数(最高位为1),则是高位补1,低位舍弃。可以总结为:左移不分正负,左丢弃右补零;右移要分正负,右丢弃左补高(极代表正负,正补0,负补1)。
下面举例说明下,
short int m = 6;
short int n = -6;
unsigned short int a = 6;
unsigned short int b = 65530;
printf("%d,%d,%u,%un",m<<2,n<<2,a<<2,b<<2);
printf("%x,%x,%x,%xn",m<<2,n<<2,a<<2,b<<2);
printf("%d,%d,%u,%un",m>>2,n>>2,a>>2,b>>2);
printf("%x,%x,%x,%xn",m>>2,n>>2,a>>2,b>>2);
以上程序输出的结果为
24,-24,24,65512
18,ffe8,18,ffe8
1,-2,1,16382
1,fffe,1,3ffe