c语言位运算问题? 关于c语言中的按位运算问题

\u5173\u4e8eC\u8bed\u8a00\u7684\u4f4d\u8fd0\u7b97\u7684\u95ee\u9898

\u7b2c\u4e00\u9898\uff1a
\u5982\u679c\u4e66\u672c\u4e0a\u771f\u662f\u90a3\u4e2a\u610f\u601d\uff0c\u90a3\u5c31\u662f\u5b83\u7684\u9519\u8bef\u3002
\u8fd9\u4e2a\u7a0b\u5e8f\u5173\u952e\u7684\u662f\u8fd9\u51e0\u884c\u4ee3\u7801:
b=a>>3; //\u4f60\u5199\u7684\u662f4\uff0c\u4f30\u8ba1\u662f\u6284\u9519\u4e86\uff0c\u5e94\u8be5\u662f3\uff0c\u4ee3\u8868\u5411\u53f3\u79fb3\u4f4d\u3002\u8fd9\u6837\u4ece\u53f3\u6570\u7b2c4\u4f4d\u5c31\u53d8\u6210\u4e86\u53f3\u6570\u7b2c\u4e00\u4f4d\u4e86
c=~(~0<<4); //\u8fd9\u4e2a\u624d\u662f\u5173\u952e\uff0c~0\u8868\u793a\u5404\u4e2a\u4f4d\u90fd\u662f1\uff0c\u518d\u5411\u5de6\u79fb4\u4f4d\uff0c\u6b64\u65f6\u4f4e4\u4f4d\u662f0\uff0c\u5176\u4ed6\u4f4d\u662f1\uff0c\u518d\u53d6\u53cd\u4ee5\u540e\uff0cc\u7684\u4e8c\u8fdb\u5236\u6570\u4f4e4\u4f4d\u662f1\uff0c\u5176\u4ed6\u4f4d\u662f0
d=b&c; //b\u548cc\u6309\u4f4d\u4e0e\uff0c\u56e0\u4e3ac\u7684\u4f4e4\u4f4d\u662f1\uff0c\u5176\u4ed6\u4f4d\u662f0\uff0c1&\u4efb\u4f55\u6570=\u4efb\u4f55\u6570\uff0c0&\u4efb\u4f55\u6570=0.\u6240\u4ee5\u53d6\u5230\u7684\u5c31\u662fb\u7684\u4f4e4\u4f4d\u4e86\u3002 \u4e5f\u5c31\u662fa\u76844-7\u4f4d\u3002
\u5982\u679c\u6309\u7167\u4e66\u672c\u4e0a\u5f52\u7eb3\uff1a\u4ece\u53f3\u9762\u5f00\u59cb\u53d6m\u2014n\u4f4d\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a
b=a>>(m-1);
c=~(~0<<(n-m));
d=b&c;
\u7b2c\u4e8c\u9898\uff1a
\u8fd9\u4e2a\u7a0b\u5e8f\u7684\u529f\u80fd\u5176\u5b9e\u5c31\u662f\u5c06\u4e00\u4e2a\u6570\u7684\u4e8c\u8fdb\u5236\u4f4d\u4e2d\u7684\u4f4en\u4f4d\uff0c\u79fb\u52a8\u5230\u5b83\u7684\u9ad8n\u4f4d\uff0c\u76f8\u5e94\u7684\uff0c\u539f\u6765\u7684\u9ad816-n\u4f4d\u4e5f\u5c31\u53d8\u6210\u4e86\u4f4e16-n\u4f4d\u4e86\u3002\u8fd9\u4e2a\u5c31\u662f\u5b83\u6240\u8c13\u7684\u201c\u5faa\u73af\u79fb\u4f4d\u201d\u3002
\u4e3e\u4e2a\u4f8b\u5b50\uff1a
a\u7684\u4e8c\u8fdb\u5236\u6570\uff1a0110 1100 0011 1010
\u53d6n\u4e3a4\uff0c\u5219
b=a<<12; //b=1010 0000 0000 0000 \u53ea\u4fdd\u7559\u4e86a\u7684\u4f4e4\u4f4d
c=a>>4; //c=0000 0110 1100 0011 \u4f4e4\u4f4d\u4e22\u5931\uff0c\u9ad84\u4f4d\u88650
c=c|b; //\u6b64\u65f6\u6309\u4f4d\u6216\uff0cc=1010 0110 1100 0011 \u5b9e\u73b0\u4e86\u4f4e4\u53d8\u6210\u4e86\u9ad84\u4f4d
\u660e\u767d\u4e86\u5427\uff1f
\u4e3e\u4f8b\u8bf4\u660e\u8865\u7801\u548c\u53cd\u7801\uff1a
\u53cd\u7801\u597d\u7406\u89e3\uff0c\u5c31\u662f\u53d6\u53cd,\u6bd4\u59820110\u7684\u53cd\u7801\u662f1001.
\u8865\u7801\u8981\u5206\u7c7b\u3002\u6b63\u6570\u7684\u8865\u7801\u5c31\u662f\u4ed6\u7684\u539f\u7801\u3002\u8d1f\u6570\u7684\u8865\u7801\u9075\u5faa\u89c4\u5219"\u7edd\u5bf9\u503c\u6309\u4f4d\u53d6\u53cd\u518d+1"
\u4e0b\u9762\u4e3e\u4f8b\u5b50\uff1a
8\u7684\u8865\u7801\uff1a 8\u7684\u539f\u7801\uff1a0000 1000\u3002\u8865\u7801\u4ecd\u7136\u662f0000 1000
-8\u7684\u8865\u7801\uff1a\u56e0\u4e3a\u662f\u8d1f\u6570\uff0c\u6700\u9ad8\u4f4d\u4e3a1\uff0c\u9700\u8981\u4fdd\u7559\u3002\u800c-8\u7684\u7edd\u5bf9\u503c\u5982\u4e0a,\u5408\u5728\u4e00\u8d77\u5c31\u662f1000 1000.\u5148\u6309\u4f4d\u53d6\u53cd\uff1a1111 0111\uff0c\u518d+1\uff1a 1111 1000\u3002\u8fd9\u4e2a\u5c31\u662f-8\u7684\u8865\u7801\u4e86\u3002

2

a|=1<<1

a = a | (1<<1)
a = 0 | 2
a = 2

c语言位运算问题解答:

要解答这个问题我们先来看一个例子,代码如下图一,图中右边是问题中得到代码,左边是这段代码的汇编指令。两种情况的不同点详细说明如下:

第一种情况:

printf("%d",2>>64);

由图中的汇编代码可以看出,如果两个数都是常数的情况下,代码中是不含对应的汇编指令的,因为编译器已经省略了,编译器算出结果为0,直接把0传入给printf函数。

第二种情况:

int i=2;

printf("%d",i>>64);

此时i是个变量,编译器没法在编译时算出结果,这时就需要通过SARL算术右移指令进行,这里考虑到溢出这个指令有一个调整机制,它会根据左操作数i类型来调整右操作数,比如这里i是4字节32位,也就是它最多右移32位,如果右操作数大于32它会进行64%32=0,所以i>>64相当于i>>0,如果是i>>63,63%32=31相当于i>>31。这种调整不同的编译器可能会不同,目前GCC是这样的。

所以这个代码在GCC环境下输出结果为:

0

2

补充说明:如果想要了解更多可以写出代码,然后观察编译出来的汇编代码。

gcc -S test.c

图一




位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作

运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。

C语言提供的位运算符列表:
运算符 含义 描述
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0

1、“按位与”运算符(&)

按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1,

则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。按位与其

实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才为真。若,

A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。(为了区分十进制和其他进制,本文规

定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据

的基本单位是字节(Byte),一个字节由8个位(bit)所组成。位是用以描述电脑数据量的最小单位。



位运算简介C语言中的各种运算都是以字节的形式进行,在编写很多系统程序时,如驱动程序、磁盘文件管理程序等,常要求将数据按位(bit)进行运算或者处理。

还真是啊,以前没留意过。

是不是因为2是数字常量或字符常量(宏定义),不占用空间;而i是一般变量,需要占用空间导致的呢?
马克一下,看看那个大神知道,共同学习一下。

C语言位运算详解 位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作 运算符。这些运算符只能用于整型操作数,即.

  • c璇█浣嶈繍绠楅棶棰?
    绛旓細c璇█浣嶈繍绠楅棶棰瑙g瓟锛氳瑙g瓟杩欎釜闂鎴戜滑鍏堟潵鐪嬩竴涓緥瀛愶紝浠g爜濡備笅鍥句竴锛屽浘涓彸杈规槸闂涓緱鍒颁唬鐮侊紝宸﹁竟鏄繖娈典唬鐮佺殑姹囩紪鎸囦护銆備袱绉嶆儏鍐电殑涓嶅悓鐐硅缁嗚鏄庡涓嬶細绗竴绉嶆儏鍐碉細printf("%d",2>>64);鐢卞浘涓殑姹囩紪浠g爜鍙互鐪嬪嚭锛屽鏋滀袱涓暟閮芥槸甯告暟鐨勬儏鍐典笅锛屼唬鐮佷腑鏄笉鍚搴旂殑姹囩紪鎸囦护鐨勶紝鍥犱负缂栬瘧鍣...
  • C璇█浣嶈繍绠楅棶棰
    绛旓細3銆佽礋鏁板湪鏄互琛ョ爜鐨勫舰鍔垮瓨鍌紝鎵浠ヤ綅杩愮畻鏄鍙嶇爜杩涜鎿嶄綔锛堟湁鐨勪功璇存鏁版槸瀵规簮鐮佹搷浣锛屼絾鏄鏁版簮鐮併佸弽鐮併佽ˉ鐮侀兘涓鏍凤紝涓轰簡鐓ч【璐熸暟锛屾垜鏄涓哄琛ョ爜鎿嶄綔鐨勶級4銆&杩愮畻锛屽彧鏈夊搴旂殑涓や釜浜岃繘浣嶅潎涓1鏃讹紝缁撴灉浣嶆墠涓1 锛屽惁鍒欎负0銆傛墍浠&b=00000100锛堣ˉ鐮侊級锛岃浆鍖栦负婧愮爜00000100锛屽崄杩涘埗c=4 5銆亅杩...
  • C璇█涓浣嶈繍绠绗闂 杩欏彞璇濇庝箞瑙i噴鍟
    绛旓細杩欏彞璇濈殑鐞嗚В鏈夎繖鏍蜂竴涓熀纭锛岄偅灏辨槸鍙崇Щn浣嶇浉褰撲簬闄や互2鐨刵娆℃柟锛岃岃繖涓熀纭灏辨槸瀵逛簬鏃犵鍙锋暟鏉ヨ鐨勩傛瘮濡傛棤绗﹀彿鏁8锛屽鏋滅敤8浣嶄簩杩涘埗琛ㄧず锛屽氨鏄簩杩涘埗鐨0000 1000锛屽彸绉0浣嶏紝涔熷氨鏄笉绉诲姩锛岀瓑浜8锛屽氨绛変簬8闄や互1锛屼篃灏辨槸8闄や互2鐨0娆℃柟锛涘彸绉1浣嶏紝0000 0100 锛岀瓑浜4锛屽氨绛変簬8闄や互2锛屼篃...
  • 鍏充簬C璇█鐨浣嶈繍绠鐨闂
    绛旓細c=~(~0<<4);//杩欎釜鎵嶆槸鍏抽敭锛寏0琛ㄧず鍚勪釜浣嶉兘鏄1锛屽啀鍚戝乏绉4浣嶏紝姝ゆ椂浣4浣嶆槸0锛屽叾浠栦綅鏄1锛屽啀 鍙栧弽 浠ュ悗锛宑鐨勪簩杩涘埗鏁颁綆4浣嶆槸1锛屽叾浠栦綅鏄0 d=b&c;//b鍜宑鎸変綅涓庯紝鍥犱负c鐨勪綆4浣嶆槸1锛屽叾浠栦綅鏄0锛1&浠讳綍鏁=浠讳綍鏁帮紝0&浠讳綍鏁=0.鎵浠ュ彇鍒扮殑灏辨槸b鐨勪綆4浣嶄簡銆備篃灏辨槸a鐨4-7浣嶃
  • C璇█浣嶈繍绠楅棶棰
    绛旓細鏄塂 棣栧厛瑕佺煡閬揷1鐨勪簩杩涘埗鏄11111111锛宑2鏄0 c1鍙崇Щ涓や綅灏辨槸00111111锛屼笌c2浣嶆垨灏卞緱0011111111锛屾墍浠1鍊煎彉涓3f 鐒跺悗c1鏄00111111锛026涓10011110锛屽彇浣嶅紓鎴栧緱10100001锛屾墍浠2鍊煎彉涓篴1
  • C璇█浣嶈繍绠楅棶棰
    绛旓細= (i>>(3*j))&7 鍋囪姝ゆ椂i=24銆乯=1锛岄偅涔坕>>(3*j)灏辩浉褰撲簬24>>3锛屾剰鎬濆氨鏄妸24杩欎釜鏁版崲鎴愪簩杩涘埗鍚庝篃灏辨槸00011000鐨勫悇浣嶅悜鍙崇Щ鍔3浣嶏紝鍙樻垚00000011鍗3銆傜劧鍚庡啀绠3&7锛屾剰鎬濇槸鎶3鍜7鎸変綅杩涜涓杩愮畻锛岀浉褰撲簬00000011&00000111=00000011=3锛屾墍浠ユ渶鎬荤粨鏋滃氨鏄痯erson[1]=3銆備互姝ょ被鎺ㄣ
  • c璇█鐨浣嶈繍绠鏄粈涔?
    绛旓細鏄浣嶈繍绠锛,鍏堟妸a,b杞寲鎴愪簩杩涘埗銆傜劧鍚庝綅鐩告垨锛屾湁1鍑1,鏃1鍑0銆傛瘮濡傦紝a=5锛宐=2锛5鐨勪簩杩涘埗琛ㄧず鏄101銆2鐨勪簩杩涘埗琛ㄧず鏄10锛岄偅涔101|10=111锛111鍗佽繘鍒惰〃绀烘槸7銆傛墍浠|b=7锛屽鏋渁=3锛宐=2锛岄偅涔坅|b锛岀粨鏋滄槸锛11|10=11锛宎|b=3銆傛瘮濡傝緭鍑"asdf\b\b"閭d箞浣犵湅鍒扮殑浠荤劧鏄痑sdf浣嗘槸鍏夋爣鍦...
  • C璇█浣嶈繍绠楅棶棰
    绛旓細int x=03,y=02,z=01;杩愮畻绗鐨勪紭鍏堢骇鏈楂橈紝娆′箣鏄&锛屾渶鍚庢槸| x鐨勪簩杩涘埗鐨勫悗4浣嶆槸0011 y鐨勬槸0010 z鐨勬槸0001 鍏堢畻~z锛寏0001=1110 鐒跺悗y鍜屽畠杩涜涓庤繍绠楋紝1110&0010=0010 鐒跺悗鎵цx鍜屽畠鐨勬垨杩愮畻锛0011|0010=0011 0011灏辨槸3锛屾墍浠ョ粨鏋滄槸3 ...
  • c璇█涓,濡備綍瀹炵幇浣嶈繍绠?
    绛旓細c璇█锛氬彇鏁村瀷鍙橀噺x涓殑绗琾浣嶅紑濮嬬殑n涓猙it浣嶏紝鍙互閲囩敤浣嶈繍绠鐨勬柟娉曘傚厛鍚戝乏绉讳綅锛屼涪寮冨墠闈笉闇瑕佺殑浣嶏紝鍐嶉氳繃鍚戝悗绉讳綅锛屼涪寮冨悗闈笉闇瑕佺殑浣嶏紝鏈鍚庡啀鍚戝乏绉讳綅鍒板師鏉ョ殑浣嶇疆锛屽氨鍙互浜嗐1//num&(num-1)=(1111)&(1110)=(1110)2//num&(num-1)=(1110)&(1101)=(1100)3//num&(num-1)=(...
  • C璇█闂,鍦浣嶈繍绠涓,鎿嶄綔鏁版瘡鍙崇Щ涓浣,鍏剁粨鏋滅浉褰撲簬浠涔?鑻ュ乏绉1浣...
    绛旓細1銆佸彸绉伙紝闄や互2鍙崇Щn浣嶉櫎浠2鐨刵娆℃柟锛涘彸绉荤殑姒傚康鍜屽乏绉荤浉鍙嶏紝灏辨槸寰鍙宠竟鎸姩鑻ュ共浣嶏紝杩愮畻绗︽槸>>锛涘彸绉诲绗﹀彿浣嶇殑澶勭悊鍜屽乏绉讳笉鍚岋紝瀵逛簬鏈夌鍙锋暣鏁版潵璇达紝姣斿int绫诲瀷锛屽彸绉讳細淇濇寔绗﹀彿浣嶄笉鍙橈紝渚嬪锛歩nti=0x80000000锛沬=i>>1锛//i鐨勫间笉浼氬彉鎴0x40000000锛岃屼細鍙樻垚0xc0000000 2銆佸乏绉伙紝涔樹互2...
  • 扩展阅读:扫一扫题目出答案 ... c#入门基础知识 ... c语言ll 和&&的运算 ... c语言必背100代码 ... c语言一个&和两个& ... c++新手代码大全 ... c++编程 ... 学c#有前途吗 ... c语言补码对照表 ...

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