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"); }
特別注意,這是運算的變量是有符號類型的狀況,若是是無符號類型,就算最高位是1,那麼左移填充的符號位依然是0。內存
位運算注意點 在進行位運算時,要求全部參與運算變量必須是 unsigned char類型,這是由於正數和負數在內存中都是以補碼方式存儲 若是使用char,這是有符號的類型,那麼若是這個char小於0,那麼在內存中的存儲就會變化,當出現拷貝操做時,就會改變原數據 若是使用unsigned char,全部的數據都是正數(正數的原碼,補碼一致),拷貝時,系統就不會修改原數據了