C語言基礎知識(四)——位操作


一、進制基礎知識

  1、通常,1字節(Byte)包含8位(bit)。C語言用字節表示儲存系統字符集所需的大小。

  2、對於一個1字節8位的二進制數,最右邊(第0位)是最低階位,最左邊(第1位)是最高階位,第幾位表示2的指數大小。

  3、1字節(8位)可存儲256個值,unsigned char用1字節表示的范圍是0-255,signed char用1字節表示的范圍是(-128)-(+127)。

  4、每個8進制位對應3個二進制位,每個16進制位對應4個二進制位。

  5、補碼反碼等與有符號整數有關的部分省略。

二、C操控位工具(2)——按位運算符

  注意:按位運算符操作的位不會改變其它位。

        邏輯運算符的優先級低於算數運算符。

  1、按位邏輯運算符 ~ & | ^

  1.1、二進制按位取反運算符~

     簡單來說就是每一位都取相反數,1變成0,0變成1,規則如下:

     (~1) = 0,(~0) = 1

     示例如下:

    ~(10011010)    //結果為01100101,每一位都取相反數

  1.2、二進制按位與運算符&

     簡單來說全為1則結果為1,不全為1或者全不為1則結果為0,規則如下:

     1 & 1 = 1,1 & 0 = 0, 0 & 0 = 0,結果操作位在運算符左右位置無關

     示例如下:

    (10000011) & (00111101)    //結果為00000001,只有最后一位全為1  

  1.3、二進制按位或運算符|

     簡單來說就是有1(全為1或者不全為1)則結果為1,全不為1(全為0)則結果為0,規則如下:

     1 | 1 = 1,1 | 0 = 1, 0 | 0 = 0,結果操作位在運算符左右位置無關

     示例如下:

    (10000010) | (01111100)    //結果為11111110,只有最后一位全為0

 

  1.4、二進制按位異或運算符^

     簡單來說就是操作位數值相同(全為0或者全為1)為0,相反(一個0一個1)為1,規則如下:

     1 ^ 1 = 0,1 ^ 0 = 1, 0 ^ 0 = 0,結果操作位在運算符左右位置無關

     示例如下:

   (10000010) ^ (01111110)    //結果為11111100,最第為全為0,第二位全為1,其它位均相反

 

  1.5、應用

    根據按位邏輯運算符可進行 打開位(設置位)關閉位(清空位)切換位檢查位的值等操作。

  2、移位運算符

     注意:移位運算符向左或者向右移位,被移出的位直接丟棄,移進的位補0。

  2.1、左移運算符<<

    示例如下:   

     (10001010)  <<  2    //結果為00101000

 

  2.2、右移運算符>>

    示例如下:

     (10001010)  >> 2    //結果為00100010

   2.3、應用

      針對2的冪可快速進行有效的乘法和除法,類似十進制中移動小數點來乘以或除以10,如下所示:

    number << n        //表示number乘以2的n次冪
    number >> n        //若number非負,則用number除以2的n次冪

 三、C操控位工具(2)——位字段

  1、位字段簡介

        位字段是一個signed int或者unsigned int類型變量中的一組相鄰的位,需通過一個結構體聲明來建立,該結構為每個字段提供標簽,並確定該字段的寬度。如下所示:

  /* 定義一個包含4個成員變量的結構體prnt,每個成員的位寬為1 */  
  struct{
      unsigned int autfd : 1;
      unsigned int bldfc : 1;
      unsigned int undln : 1;
      unsigned int itals : 1;
  }prnt;
    
  /* 為結構體成員賦值 */
  prnt.itals = 0;
  prnt.undln = 1;   
    
    /* 定義一個包含2個成員變量的結構體prcode,成員變量位寬不一 */  
    struct{
        unsigned int code1 : 2;
        unsigned int code2 : 8;
    }prcode;
    
    /* 為結構體成員賦值 */
     prcode.code1 = 3;          /**< code1最大可賦值3 */
     prcode.code1 = 100;        /**< 賦值范圍在0-255中均可 */    

   變量prnt會prcode被儲存在int大小的內存單元中。

  2、聲明的總位數超過范圍的解決方法

    如果聲明的總位數超過一個unsigned int類型的大小,則會用到下一個unsigned int類型的存儲位置。一個字段不允許跨越兩個unsigned int之間的邊界。編譯器會自動移動跨界的字段,保持

       unsigned int的邊界對齊。一旦發生這種情況,第一個unsigned int 中會保留一個未命名的"洞",可用此未命名的洞來填充超過的位數。如下所示:

  struct{
      unsigned int field1 : 1;
      unsigned int          : 2;       /**< 填補field1的"洞" */
      unsigned int field2 : 1;
      unsigned int          : 0;       /**< 填補field2的"洞" */
          unsigned int field3 : 1;      /**< 填補field3的"洞"並未給出 */
  }stuff;

  位字段在unsigned int中存儲的位置根據機器而定,有些從右往左順序存儲,有些則從左往右,由於這些原因位字段通常都不容易移植。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM