溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言中怎么實現(xiàn)位操作

發(fā)布時間:2021-07-07 14:52:12 來源:億速云 閱讀:120 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關(guān)C語言中怎么實現(xiàn)位操作,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

  C語言中提供了&(與)、|(或)、^(異或)、~(取反)、>>(右移)、<<(左移)6種位操作符。我們可以在程序中合理地使用這些位操作符號來提高程序的運行效率,例如,對于下面的示例代碼:   intx=0;   inty=0;   x=257/8;   y=456%32;

我們可以通過位操作符將其修改成如下形式:

  intx=0;

  inty=0;

  x=257>>3;

  y=456-(456>>4<<4);   這樣就可以使程序在性能上得到一定提升。   盡量避免對未知的有符號數(shù)執(zhí)行位操作   在C語言中,如果在未知的有符號數(shù)上執(zhí)行位操作,很可能會導致緩沖區(qū)溢出,從而在某些情況下導致攻擊者執(zhí)行任意代碼,同時,還可能會出現(xiàn)出乎意料的行為或編譯器定義的行為。   下面來看一個簡單的示例:   #include

  intmain(void)

  {

  intx=0;

  inty=0x80000000;

  charbuf[sizeof("128")];

  x=sprintf(buf,"%u",y>>24);

  if(x==-1||x>=sizeof(buf))

  {

  //錯誤處理

  }

  printf(buf);

  return0;

  }

  代碼中,y>>24的執(zhí)行結(jié)果為4294967168,而sizeof(buf)的結(jié)果為4。當我們將y>>24的結(jié)果值轉(zhuǎn)換為字符串“4294967168”時,超出了buf范圍,所以結(jié)果值無法完全存儲在buf中。因此,在執(zhí)行語句“x=sprintf(buf,"%u",y>>24)”時,sprintf方法在進行寫操作時就會越過buf的邊界,從而產(chǎn)生緩沖區(qū)溢出。

  如果在編譯器VC++中執(zhí)行這段程序,將會產(chǎn)生錯誤報告。

  在C99中,要修正這樣的錯誤,最好利用snprintf方法來代替sprintf方法。因為snprintf方法最多從源串中復制n-1個字符到目標串中,然后再從后面加一個0。因此,如果目標串的大小為n,將不會產(chǎn)生溢出。

當然,如果將變量y聲明成為無符號類型

  即將:

  inty=0x80000000;

  修改為:

  unsignedinty=0x80000000;

  那么這種緩沖區(qū)溢出錯誤將不會發(fā)生。

  在右移中合理地選擇0或符號位來填充空出的位

  在右移運算中,空出的位用0還是符號位進行填充呢?

  其實答案由具體的C語言編譯器實現(xiàn)來決定。在通常情況下,如果要進行移位的操作數(shù)是無符號類型的,那么空出的位將用0進行填充;如果要進行移位的操作數(shù)是有符號類型的,則C語言編譯器實現(xiàn)既可選擇0來進行填充,也可選擇符號位進行填充。

  因此,如果很關(guān)心一個右移運算中的空位,那么可以使用unsigned修飾符來聲明變量,這樣空位都會被設(shè)置為0。同時,如果一個程序采用了有符號數(shù)的右移位操作,那么它就是不可移植的。

  移位的數(shù)量必須大于等于0且小于操作數(shù)的位數(shù)

  如果被移位的操作數(shù)的長度為n,那么移位的數(shù)量必須大于等于0且小于n。因此,在一次單獨的操作中不可能將所有的位從變量中移出。例如,一個int型的整數(shù)是32位,并且n是一個int型整數(shù),那么n<<31和n<<0是合法的,但n<<32和n<<-1是不合法的。因此,我們在進行移位運算的時候必須做相關(guān)測試。示例代碼如下所示: y="">=sizeof(unsignedint)*CHAR_BIT)

  {

  //錯誤處理

  }

  else

  {

  result=x>>y;

  }

  這里還需要說明的是,對于變量x與y,C99規(guī)定:

  對于x<y可以用結(jié)果類型表示,那么這個表達式就是結(jié)果值,否則,其行為是未定義的;如果x是無符號類型,則x>y,如果x是無符號類型或非負值的有符號類型,那么x>>y的移位結(jié)果為x/2y的商的整數(shù)部分;如果x是有符號類型的負值,那么x>>y的移位結(jié)果是由編譯器所定義的。因此,對一個帶符號整數(shù)進行右移運算和將它除以2的某次冪不一定是等價的。要證明這一點很容易,考慮(-1)>>1的值,它的執(zhí)行結(jié)果不可能為0,而在大多數(shù)C語言編譯器中(-1)/2的結(jié)果都是0。

盡量避免在同一個數(shù)據(jù)上執(zhí)行位操作與算術(shù)運算

  雖然位操作在很大程度上可以提高程序的執(zhí)行效率,但在同一個變量上執(zhí)行位操作和算術(shù)運算會模糊程序員的意圖,削弱代碼的可移植性與可讀性,還會導致安全審核員或代碼維護人員難以確定應(yīng)該執(zhí)行什么檢查以消除安全缺陷,保證數(shù)據(jù)的完整性。

以上就是C語言中怎么實現(xiàn)位操作,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI