C語言 位運算

1G=1024M;函數

1M=102KB;spa

1KB=1024B(字節);code

1B=8bits(位);blog

 

 

#include<stdio.h>
#include<stdlib.h>

//C語言中的邏輯運算符
//邏輯與(&&);邏輯或(||);邏輯非(!)。

//強調邏輯運算符與位邏輯運算符不一樣

//C語言中的位運算符有如下兩類:
//位邏輯運算符:&(位「與」)、^(位「異或」)、 | (位「或」)、~(位「取反」)。
//移位運算符: << (左移)、 >> (右移)
void main(){
    //一:取反運算(~)
    unsigned char ch1 = 165;
    //一個字符有8位,ch1換算成二進制是 1010 0101
    //位取反的操做符爲「~」,
    //即每位都取反,0變成1,1變成0,須要注意的是,位取反運算並不改變操做數的值。
    //那麼~ch1=0101 1010,換算成十進制是90
    unsigned char ch2 = ~ch1;
    //printf("\n%d", ~ch1);//  打印  -166  錯誤  解釋: ~ch1是取反運算,值會存儲在cpu的寄存器中,因此printf函數不肯定~ch1的類型
    printf("\n取反運算%d", (unsigned char)~ch1);//  打印  90  正確
    printf("\n取反運算%d",ch2);//  打印  90  正確

    //二:與運算(&)----清零
    //位與運算的操做符爲&,將對兩個操做數的每一位
    //進行與運算,位「與」運算的準則以下:(二者都爲1的時候纔是1,有一個爲0就是0)
    //1 & 1 = 1     1 & 0 = 0     0 & 1 = 0     0 & 0 = 0
    unsigned char ch3 = 15;
    //ch1        1010 0101
    //ch3        0000 1111
    //ch1&ch3    0000 0101   十進制是5
    unsigned char ch4 = ch1&ch3;
    printf("\n與運算%d", ch4);//  打印  5  正確
    //對於ch1&ch3的分析,發現與運算能夠用來"保持一部分位不變(不變用1),部分爲所有爲0(變0用0)"

    //三:或運算(|)---置1
    //位或運算的操做符爲|,將對兩個操做數的每一位進行或運算,位「或」運算的準則以下:(二者有一個是1就是1,二者都爲0纔是0)
    //1 | 1 = 1      1 | 0 = 1      0 | 1 = 1      0 | 0 = 0
    //例子
    //ch1        1010 0101
    //ch3        0000 1111
    //ch1|ch3    1010 1111   十進制是175
    unsigned char ch5 = ch1|ch3;
    printf("\n或運算%d", ch5);//  打印  175  正確
    //對於ch1|ch3的分析,發現與運算能夠用來"保持一部分位不變(不變用0),部分爲所有爲1(變1用1)"

    //四:異或運算(^)---取反
    //位或運算的操做符爲^,將對兩個操做數的每一位進行異或運算。
    //通俗地講,若是位「異或」運算的兩個位相同(同爲0或同爲1),結果爲0,
    //若兩個位不一樣(一個爲0,另外一個爲1),結果爲1,對應的準則爲:(二者相同結果是0,二者不一樣結果是1)
    //1 ^ 1 = 0  1 ^ 0 = 1  0 ^ 1 = 1  0 ^ 0 = 0
    //例子
    //ch1        1010 0101
    //ch3        0000 1111
    //ch1^ch3    1010 1010  十進制170
    unsigned char ch6 = ch1^ch3;
    printf("\n異或運算%d", ch6);//  打印  170  正確
    //對於ch1^ch3的分析,發現與運算能夠用來"保持一部分位不變(不變用0),部分取反(取反用1)"

    //五:左移運算(<<)
    //A稱爲操做數,其必須爲數字型變量或數字型常量,
    //此處的數字型包括整型、浮點型和char型,A中存儲的0、1序列向左或右移動n位,
    //移動後的值做爲整個表達式的輸出,執行移位運算並不改變操做數A的值。
    unsigned char ch7 = 1;
    //例子
    //ch7        0000 0001    十進制是1
    //ch7<<1     0000 0010    十進制是2  (1*2)
    //ch7<<2     0000 0100    十進制是4   (2*2)
    unsigned char ch8 = ch7<<1;
    unsigned char ch9 = ch7<<2;
    printf("\n左移運算ch7<<1=%d", ch8);//  打印  2  正確
    printf("\n左移運算ch7<<2=%d", ch9);//  打印  4  正確
    unsigned char cha = 128;
    //例子
    //cha        1000 0000    十進制是128
    //cha<<1     0000 0000    十進制是0  
    unsigned char chb = cha << 1;
    printf("\n左移運算cha<<1=%d", chb);//  打印  0  正確

    //六:右移運算(>>)
    unsigned char chc = 255;
    //例子
    //chc        1111 1111    十進制是255
    //chc>>1     0111 1111    十進制是127  (255/2)
    //chc>>2     0011 1111    十進制是63    (127/2)
    unsigned char chd = chc >> 1;
    unsigned char che = chc >> 2;
    printf("\n右移運算chc >> 1=%d", chd);//  打印  127  正確
    printf("\n右移運算chc >> 2=%d", che);//  打印  63  正確


    //練習
    // 1010 0101十進制是165
    //練習1:前四位不變,後四位清零
    //分析:清零操做使用與運算符;前四位不變1111,後四位清零0000,二進制是1111 0000---十進制是240
    unsigned char chf = 240;
    unsigned char chg = ch1&chf;
    //ch1        1010 0101    十進制是165
    //chf        1111 0000    十進制是240  
    //ch1&chf    1010 0000    十進制是160
    printf("\n前四位不變,後四位清零%d", chg);//  打印  160  正確

    //練習2:前四位不變,後四位置1
    //分析:置1使用或運算符,前四位不變--0000,後四位置1--1111,二進制是 0000 1111---十進制是15
    unsigned char chh = 15;
    unsigned char chi = ch1 | chh;
    //ch1        1010 0101    十進制是165
    //chh        0000 1111    十進制是15  
    //ch1|chf    1010 1111    十進制是175
    printf("\n前四位不變,後四位置1--%d", chi);//  打印  175  正確

    //練習3:前四位不變,後四位取反
    //分析:取反有2中方法,取反運算符和異或運算符,取反運算符只能所有取反,異或運算符能夠部分取反
    //前四位不變,說明只能使用異或運算符;前四位不變0000;後四位取反1111,二進制是 0000 1111---十進制是15
    //注:異或相同爲0,不一樣爲1,兩個0的值仍然是0,兩個1的值是0,一個0和一個1結果是1
    unsigned char chj = ch1^chh;
    //ch1        1010 0101    十進制是165
    //chh        0000 1111    十進制是15  
    //ch1|chf    1010 1010    十進制是170
    printf("\n前四位不變,後四位取反--%d", chj);//  打印  170  正確

    system("pause");
}

     

           在C語言的位運算中,左移也就是所說的邏輯移位,右端補0,而右移是算數移位,左端補齊的是最高位的符號位。所以負數左移,有可能變成正數
,但負數右移,確定仍是負數。

 特別注意,這是運算的變量是有符號類型的狀況,若是是無符號類型,就算最高位是1,那麼左移填充的符號位依然是0。內存

 

 

 

位運算注意點
    在進行位運算時,要求全部參與運算變量必須是 unsigned char類型,這是由於正數和負數在內存中都是以補碼方式存儲
若是使用char,這是有符號的類型,那麼若是這個char小於0,那麼在內存中的存儲就會變化,當出現拷貝操做時,就會改變原數據
若是使用unsigned char,全部的數據都是正數(正數的原碼,補碼一致),拷貝時,系統就不會修改原數據了
相關文章
相關標籤/搜索