C语言中位运算符问题 这句话怎么解释啊 C语言按位运算符问题

c\u8bed\u8a00\u4f4d\u8fd0\u7b97\u7684\u95ee\u9898

>>\u7684\u4f18\u5148\u7ea7\u6bd4|\u9ad8\uff0c~\u7684\u4f18\u5148\u7ea7\u4e5f\u6bd4|\u9ad8\uff0c\u6240\u4ee5k=~i|j>>3;\u5b9e\u4e3ak=(~i)|(j>>3);\u3002i=013==00000000 00001011(0\u6253\u5934\u7684\u662f\u516b\u8fdb\u5236)\uff0c\u6240\u4ee5~i==11111111 11110100\uff1bj=0x13==00000000 00010011\uff0cj>>3==00000000 00010011>>3==00000000 00000010\uff1b~i|j>>3==11111111 11110100|00000000 00000010==11111111 11110110==0xFFF6==0177766(8)\u3002\u6240\u4ee5D\u6b63\u786e\uff0c\u9009D\u3002

\u697c\u4e3b\u4f60\u597d

&\u5728c\u8bed\u8a00\u4e2d\u662f\u6309\u4f4d\u4e0e\u8fd0\u7b97 \u51e1\u662f\u4f4d\u8fd0\u7b97 \u5e94\u8be5\u5148\u5c06\u5bf9\u5e94\u7684\u6570\u8f6c\u6362\u4e3a\u4e8c\u8fdb\u5236 \u7136\u540e\u518d\u7ee7\u7eed\u8fd0\u7b97

\u9996\u5148\u697c\u4e3b\u6ce8\u610f0177\u662f\u4ee50\u5f00\u5934\u7684 \u8bf4\u660e\u662f\u516b\u8fdb\u5236\u6570

\u4e00\u4e2a\u516b\u8fdb\u5236\u6570\u5bf9\u5e94\u4e09\u4e2a\u4e8c\u8fdb\u5236\u4f4d

\u516b\u8fdb\u5236\u65701\u5bf9\u5e94: 001
\u516b\u8fdb\u5236\u65707\u5bf9\u5e94: 111
\u56e0\u6b64: 0177\u5bf9\u5e94\u7684\u4e8c\u8fdb\u5236\u6570\u5c31\u662f: 001 111 111

\u518d\u5219 \u8fd9\u91cc\u9664\u4e86\u5e957\u4f4d\u662f1\u5916 \u5176\u4f59\u7684\u90fd\u662f0

\u53e6\u5916\u6309\u4f4d\u4e0e\u8fd0\u7b97&\u5c31\u662f\u53ea\u8981\u67090 \u90a3\u4e48\u5fc5\u4e3a0

\u56e0\u6b64\u8fd9\u91cc\u5c31\u662f\u5c06n\u4e2d\u96647\u4e2a\u4f4e\u4e8c\u8fdb\u5236\u4f4d\u5916\u7684\u5176\u4ed6\u5404\u4f4d\u5747\u7f6e\u4e3a0

\u5e0c\u671b\u80fd\u5e2e\u52a9\u4f60\u54c8

这句话的理解有这样一个基础,那就是右移n位相当于除以2的n次方,而这个基础就是对于无符号数来说的。
比如无符号数8,如果用8位二进制表示,就是二进制的0000 1000,
右移0位,也就是不移动,等于8,就等于8除以1,也就是8除以2的0次方;
右移1位,0000 0100 ,等于4,就等于8除以2,也就是8除以2的1次方;
右移2位,0000 0010 ,等于2,就等于8除以4,也就是8除以2的2次方;
右移3位,0000 0001 ,等于1,就等于8除以8,也就是8除以2的3次方;
对于有符号数,最高位为符号位,>> 右移运算,移动的时候符号位会被同时移动。

比如有符号数的-8,如果用8位二进制补码表示,就是二进制的 1111 1000,
右移0位,也就是不移动,等于-8,就等于8除以1,也就是8除以2的0次方;
右移1位:
如果补1进来, 1111 1100 ,等于-4, 就等于8除以2,也就是8除以2的1次方;
如果补0进来, 0111 1100 ,等于124,就不等于8除以2了;

右移2位,0000 0010 ,等于2,就等于8除以4,也就是8除以2的2次方;
如果补1进来, 1111 1110 ,等于-2, 就等于8除以4,也就是8除以2的2次方;
如果补0进来, 0011 1110 ,等于62,就不等于8除以4了;

右移3位,0000 0001 ,等于1,就等于8除以8,也就是8除以2的3次方;
如果补1进来, 1111 1111 ,等于-1, 就等于8除以8,也就是8除以2的3次方;
如果补0进来, 0001 1111 ,等于31,就不等于8除以8了;

根据以上分析,对于带符号数负数,发现右移时有两种情况:补1(也就是符号位)进来,还能够保持除以2的n次方的关系成立;补0进来就不行。
不同的C编译系统根据自己的特点在这个问题上可能就采取了不同的办法。比如VC和DEV C++,对于带符号数的右移运算就采取了补符号位的方式。

当x为负数时,由于符号位为1,右移时,DEV C++系统是规定最高位补1。
例如,-8=11111000B
-8>>2=11111110B
即-8>>2=-2,满足了与正数同样的运算结果,即x>>2的值,等于x/(2^2)。
+8>>2=+2
00001000 >>2 ==> 00000010

扩展阅读:扫一扫题目出答案 ... c语言位运算符详解 ... c语言位运算符取反 ... 不正确的字符串常量 ... c++位运算符 ... c语言位运算例题 ... c语言位运算符怎么用 ... 免费拍照答题一秒出答案 ... c语言中的 是间址运算符 ...

本站交流只代表网友个人观点,与本站立场无关
欢迎反馈与建议,请联系电邮
2024© 车视网