- 逻辑移位
逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补。
- 算术移位
算术移位 就需要分有符号型值和无符号型值
对于无符号型值,算术移位等同于逻辑移位。
而对于有符号型值 ,算术左移等同于逻辑左移,算术右移补的是符号位,正数补0,负数补1。
- 那么C编译器中采用的是那种移位方式呢?
在汇编指令中,shl和shr表示逻辑左移和逻辑右移,sal和sar表示算术左移和算术右移。
首先让我们来看一段代码,
#include <stdio.h>
int main()
{
int a = 65; //有符号整型 0100 0001
unsigned int b = 65; //无符号整型 0100 0001
a <<= 1; //1000 0010 130
b >>= 1; //0010 0000 32
char c = 127; //0111 1111
c <<= 3; //1111 1000 -8
char d = 127; //0111 1111
d >>= 3; //0000 1111 15
char e = -8; //内存以补码为1111 1000存储 源码为1000 1000 反码为1111 0111
e >>= 3; //-1 补码1111 1111 源码 1000 0001 反码1111 1110
printf("%d %d\n",a,b);//130 32
printf("%d %d\n",c,d);//-8 15
printf("%d\n",e); //-1
return 0;
}
让我们来看一看这一段代码的汇编代码
只看汇编代码进行分析:
汇编代码的第四行和第七行以及第十一行是对a,b,c三个变量进行的移位操作,即有符号型变量左移和无符号型右移C编译器都处理为逻辑移位,用的指令是shl和shr,移出的空位用0来补。
而对于汇编代码的第十五行和第十九行是对d,e两个变量进行的移位操作,即正数和负数的有符号型变量的右移,C编译器处理为算术移位,用的指令是sar,移出的空位,正数补0,负数补1。
- 对于C编译器的逻辑移位和算术移位的总结
我所使用的C编译器是VS2008,基于该编译器采用对无符号型int,short,char进行移位时,编译器默认生成的汇编指令是逻辑左移和逻辑右移。
而对于有符号的int,short,char进行移位时,左移还是逻辑左移,但右移时生成的汇编指令是算术右移。