C语言位运算问题

#include<stdio.h>int main(){     int a=12,b=-10,c,d,e,f,g,h;  c=a&b;  d=a|b;  e=a^b;  f=a<<2;  g=a>>2;  h=~b;  printf("%d\n",c);  printf("%d\n",d);  printf("%d\n",e);  printf("%d\n",f);  printf("%d\n",g);  printf("%d\n",h);     return 0;}   刚刚学C,请大家帮忙分析一下结果怎么来的,谢谢!

1、假设一个数用8为来存储,最高位表示符号(0表示正,1表示负)。那么12的二进制源码就是00001100,-10的二进制源码就是10001010
2、正数源码、反码、补码都一样;负数的反码是除最高位外,其余位都取反,反码加1就是补码。
如12的源码、反码、补码均是00001100,-10的源码是10001010,反码是11110101(最高位不取反),补码是11110110。
3、负数在是以补码的形势存储,所以位运算是对反码进行操作(有的书说正数是对源码操作,但是正数源码、反码、补码都一样,为了照顾负数,我是认为对补码操作的)
4、&运算,只有对应的两个二进位均为1时,结果位才为1 ,否则为0。
所以a&b=00000100(补码),转化为源码00000100,十进制c=4
5、|运算,只要对应的二个二进位有一个为1时,结果位就为1。
所以a|b=11111110(补码)—>11111101(补码)—>10000010(源码),十进制d=-2
6、^运算,当两对应的二进位相异时,结果为1。
所以a^b=11111010(补码)—>11111001(反码)—>10000110(源码),十进制e=-6
7、左移、右移难表述,用12演示一下
00001100左移两位后{(00)001100}00,{}内的是未左移的,由于以8位存储,所以()内的就不要了,计算数值时以00110000计算,明显f=48,g=3
9、~运算,对参与运算的数的各二进位按位求反。
所以~b=00001001,h=9
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-11-25
首先,这个程序的结果,在不同的计算机上会不同。它可能受字长、位移补位的方式的不同而改变。
不过要想理解其中的位运算规则也不难,把程序稍稍改一下,让每一步运算结果都按二进制打印出来。运行下面的程序,相信你会觉得一目了然:

#include <stdio.h>

void Print( char const *title, int value)
{
int i = sizeof( int) * 8;
printf( "%8s = ", title);
while ( i --)
putchar( 1 & ( value >> i) ? '1' : '0');
putchar( '\n');
}

int main()
{
int a=12,b=-10,c,d,e,f,g,h;
Print( "a", a);
Print( "b", b);
Print( "c = a&b", c = a&b);
Print( "d = a|b", d = a|b);
Print( "e = a^b", e = a^b);
Print( "f = a<<2", f = a<<2);
Print( "g = a>>2", g = a>>2);
Print( "h=~b", h=~b);
return 0;
}本回答被提问者采纳
第2个回答  2011-11-26
位运算~有位与,位或,位非,位异或,左移,右移。。
1.位与
就如题目中的c=a&b,假设a=3,b=4,化为2进制后
a=0000 0000 0000 0000 0000 0000 0000 0011
b=0000 0000 0000 0000 0000 0000 0000 0100
我们知道与是都为1才返回1,所以结果是
C:0000 0000 0000 0000 0000 0000 0000 0000.也就是0~~
2.位或
像上面的一样,只不过进行的是或运算
3.位非
对数字求负,然后减1.如10~=-11
4.位异或
也是对数字的2进制进行运算,但是只有一个数为1才返回1,如还是c=a^b,a=3,b=4,二进制形式如上面的~结果为0000 0000 0000 0000 0000 0000 0000 0111,也就是十进制的7
5.左移
把数字的2进制形式的所有位数向左移动指定的位数,后面用0补上
6.右移。
与左移相反~你懂的~哦哦
第3个回答  2011-11-25
#include<stdio.h>

int main() {
int a = 12,b = -10;
printf("(%d)&(%d) = %d\n",a,b,a&b);
printf("(%d)|(%d) = %d\n",a,b,a|b);
printf("(%d)^(%d) = %d\n",a,b,a^b);
printf("(%d << 2) = %d\n",a,a<<2);
printf("(%d >> 2) = %d\n",a,a>>2);
printf("(%d~) = %d\n",b,~b);
return 0;
}
(12)&(-10) = 4 // 00001100&11110101 = 00000100 = 4,按位与
(12)|(-10) = -2 // 00001100|11110101 = 11111110 = -2,按位或
(12)^(-10) = -6 // 00001100^11110101 = 11111110 = -6,按位异或
(12 << 2) = 48 // 左移2位,等同于乘以4
(12 >> 2) = 3 // 右移2位,等同于除以4
(-10~) = 9 // 按位求反。
相似回答