C語言----位運算(進階篇二十六)


 

  作用

    在小內存時代,經常把一個字節分成好幾份來用,以達到節約內存的目的。

    現在經常用於網絡數據傳輸,單片機領域……。

    

    注意:

 

      ※在進行任何位運算前,首先應將進任何表達式的結果轉換成二進制,算完以后再轉回原來的進制即可得到結果。

      ※不能對浮點數進行位運算。

  按位與

    格式:二進制&二進制

      如:

        int a=3&5;

       

        記憶方法:在邏輯與運算中,兩邊的表達式都為真,結果才為真。因此按位與運算時,兩個位都為1,結果才為1。

      作用:

        ※清零:要將某一位清零,可將相應的位設置為0,其它位為1,再使用&運算。

        ※取指定位:想取某一位,可將相應的位設置為1,其它位為0,再使用&運算。

  按位或

    格式:二進制|二進制

      如:

        int a=3|5;

     

        記憶方法:在邏輯或運算中,兩邊的表達式有一個為真,結果就為真。因此按位或運算時,有一個位為1,結果就為1。

       作用:

        ※將某位置1:要將某一位置1,可將相應的位設置為1,再使用 | 運算

 

  按位異或

    格式:二進制^二進制

      如:

        int a=3^5;

      

        記憶方法:“異”就是不同的意思,異或實際上是判斷兩數是否“不同”,如果不同就為真。因此按位異或時,兩數不同,結果為1。

      定理:

        1、任何數與自己異或都為0

        2、任何數與0異或值不改變

      作用:

        ※翻轉位:要將某一位翻轉,可將相應的位置1,第一次用 ^ 運算,可將其翻轉,第二次用 ^ 運算,又可將其轉回來。早期的鼠標指針用的就是一種圖形異或運算,所以速度非常快。

 

        ※不用臨時變量交換兩個值。如a=4,b=5,可用以下語句實現互換:

          a=a^b;

          b=b^a;

          a=a^b;

        用等量代換法分析:a=a^b,那么b=b^a相當於b=b^(a^b),去括號得b=b^a^b,移項得b=b^b^a,根據定理1得b=0^a,根據定理2得b=a。

        這時候b的值是4,而a只是個中間值。

        a=a^b相當於a=(a^b)^(b^a^b),去括號得a=a^b^b^a^b,移項得a=a^a^b^b^b,根據定理1得a=0^0^b,根據定理2得a=b。

        這時候a的值是5,交換完畢

 

      程序1

        矩陣異或

 

// 26-1異或矩陣.c
//※翻轉位:要將某一位翻轉,
//   可將相應的位置1,第一次用 ^ 運算,可將其翻轉,第二次用 ^ 運算,又可將其轉回來。

#include <stdio.h>

main()
{
    //源矩陣
    int a[4][4] =
    {
        {1,2,3,4},
        {1,2,3,4},
        {1,2,3,4},
        {1,2,3,4}
    };

    //源矩陣
    /*
    int a[4][4] =
    {
        {8,8,6,6},
        {8,8,6,6},
        {6,6,8,8},
        {6,6,8,8}
    };
    */

    //異或矩陣
    int b[4][4] =
    {
        {0,3,3,0},
        {3,0,0,3},
        {3,0,0,3},
        {0,3,3,0},
    };

    //輸出源矩陣 和 異或矩陣
    printf("輸出源矩陣和異或矩陣\n");
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", a[i][j]);  //輸出源矩陣
        }
        printf("\t");
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", b[i][j]);
        }
        printf("\n");
    }

    //輸出第一次異或后的矩陣
    printf("第一次異或后的矩陣:\n");
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            a[i][j] ^= b[i][j];
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }

    //第二次異或后的矩陣  在次異或就會復原最初始的矩陣
    printf("第二次異或后的矩陣:\n");
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            a[i][j] ^= b[i][j];
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
}

 

  按位取反

    格式:~二進制

      如:int a=~3;

      得到11111100,它是個負數。

 

  左移

    格式:二進制<<要移動的位數

    如:

      int a=3<<2;

      相當於00000011<<2得到00001100

      轉成十進制后,a的值為12

 

    作用:將二進制數左移一定的位數,最右邊補0。任何一位移出左邊界,自動丟棄。

    ※不越界的左移相當於讓變量值乘以2。

  右移

    格式:二進制>>要移動的位數

      如:

        int a=12>>2;

        相當於00001100>>2得到00000011

        轉成十進制后,a的值為3

 

    作用:將二進制數右移一定的位數,最左邊補0(或1)。任何一位移出右邊界,自動丟棄。

    ※不越界右移相當於讓變量值除以2。

    注意:右移比左移要復雜些,如果要移的數為負數,最左邊符號位為1,為了不改變此數的符號位,往右移的時候,左邊會自動補1。

    位運算的優先級:~ 高於 << >> 高於 & 高於^ 高於 |

 


免責聲明!

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



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