关于移位运算符和取反运算符的一点感悟

转自:http://www.cppblog.com/

今天在学习移位运算符和取反运算符的时候,发现一些问题!现在呢在这里说一下自己的感悟!

先看下面一道 取反和移位相结合的问题


#include<stdio.h>
int main()
{
 char a=0x11;
 char b;
 b=~a<<2;
 printf("%d\n",b);
 b=~(a<<2);
 printf("%d\n",b);
 b=~a>>2;
 printf("%d\n",b);
 b=~(a>>2);
 printf("%d\n",b);
 return 0;
}

 

输出结果是:

-72
-69
-5
-5

 

刚开始在想为什么相同的操作(只是移位方向不同),为什么上面两个结果不一样,而下面两个结果却是一样的呢。有些人在疑问是不是因为下面两个表达式都是先移位后取反的呢?我可以肯定不是这样的,但是不能解释这个结果。这个问题我纠结了半天!  不过对下面的知识了解之后便豁然开朗了。

移位运算符分为左移运算符和右移运算符。
当对一个数执行左移运算的时候,右边的空位是用0补齐。
而当对一个数执行右移运算的时候,左边的空位是用符号位补齐的(这是我之前没注意的地方,惭愧)。

 

解体步骤如下:


a=0x11=0001 0001

~a=1110 1110
a<<2=0100 0100
a>>2=0000 0100


~a<<2=1011 1000  
现在 1011 1000是补码,转化成原码之后是
1100 1000=-72  -72是十进制

~(a<<2)=0100 0100
转化为原码之后是 1100 0101=-69


~a>>2=1111 1011(注意现在是用1补齐的,因为~a的符号位是1)
转化为原码之后是  1000 0101=-5


~(a>>2)=1111 1011
转化为原码之后是  1000 0101=-5

PS:

计算机实际存放的是数据的补码,原码和反码是为了让人们好理解,弄出来的概念。




你可能感兴趣的:(关于移位运算符和取反运算符的一点感悟)