参照《c与指针》,在c语言中左移时,不论算术左移还是逻辑左移效果都是相同的。而且对于有符号和无符号类型执行相同的操作,即按照二进制位向左左移N位。例如:

1 clude <stdio.h>
2 int main()
3 {
4     int a = 0xafffffff;
5     printf("%d\n",a<<1);
6     int b = 0xff;
7     printf("%d\n",b<<1);
8 }
ubuntu@ubuntu:~/code/2017.8.28$ ./test3
1610612734
510

 

  int型变量a在内存中转换为2进制储存 1010 1111 1111 1111 1111 1111 1111 1111为一个负整数,b在内存中储存为 0000 0000 0000 0000 0000 0000 1111 1111为一个正整数,程序结果如上。a左移后转化为正整数,b转换为正整数 ,都按2进制左移一位(包括符号位)。

  而对于右移来讲,针对不同的编译器,可能会进行算术或逻辑移位。在gcc下进行算术移位,即对于正整数右移,算数移位与逻辑移位相同,右移后左端补0,对于负整数右移,算数移位为符号位1不动,右移后左端补1。

1 #include <stdio.h>
2 int main()
3 {
4     int a = 0xafffffff;
5     printf("%d\n",a<<1);
6     int b = 0xff;
7     printf("%d\n",b<<1);
8 }
ubuntu@ubuntu:~/code/2017.8.28$ ./test3
-671088641
127

  a作为负数 右移左端补1,b作为正数右移左端补0,验证了以上结论。

  在左移右移中,如果数据类型总位数小于int,则先转化为int再进行移位运算。如果左移或右移位数大于数据类型位数,则先进行对数据类型位数取模,再用余数进行移位运算。

 1 #include <stdio.h>
 2 int main()
 3 {
 4     char a = 0x11;
 5     //for(i = 0;i < 100;i++)
 6     //{
 7     //    printf("%d\n", a>>i);
 8     //}
 9     printf("%d\n", a>>(sizeof(int)*8+3));
10     printf("%d\n", a>>3);
11     printf("%lu\n", sizeof(a>>3));
12     printf("%ld\n",sizeof(a)) ;
13 }
ubuntu@ubuntu:~/code/2017.8.27$ gcc -o test1 test1.c
test1.c: In function ‘main’:
test1.c:9:21: warning: right shift count >= width of type [-Wshift-count-overflow]
     printf("%d\n", a>>(sizeof(int)*8+3));
                     ^
ubuntu@ubuntu:~/code/2017.8.27$ ./test1
2
2
4
1
ubuntu@ubuntu:~/code/2017.8.27$ 

    针对一个char型数据,当打印sizeof(a>>3)时输出为4,说明此时a>>3这个变量为int型。而上边对于a>>3与a>>(32+3)的输出结果相同,同时系统警告移位大于

数据类型宽度,证明了上文结论。

 

  

  

版权声明:本文为hehedaxiaxiaoming原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hehedaxiaxiaoming/p/7444585.html