转自: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:
计算机实际存放的是数据的补码,原码和反码是为了让人们好理解,弄出来的概念。