C語言操作符超詳細(xì)講解上篇
前言
操作符主要內(nèi)容包括:各種操作符的介紹,用表達(dá)式求值。
1、操作符的分類
- 算術(shù)操作符
- 移位操作符
- 位操作符
- 賦值操作符
- 單目操作符
- 關(guān)系操作符
- 邏輯操作符
- 條件操作符
- 逗號(hào)表達(dá)式
- 下標(biāo)引用、函數(shù)調(diào)用和結(jié)構(gòu)成員
2、算術(shù)操作符
+ - * / % (加法 減法 乘法 取余 取模)
int main() { int a = 9 / 2;//4 float b = 9 / 2; int c = 9.0 / 2; float d = 9.0 / 2;//4.5 float e = (float)9.0 / 2; printf("%d\n", a); printf("%f\n", b); printf("%d\n", c); printf("%f\n", d); printf("%f\n", e); return 0; }
運(yùn)行結(jié)果見下圖:
通過例子可發(fā)現(xiàn),變量的類型使用錯(cuò)誤的話,結(jié)果也是錯(cuò)誤的
- 除了 % 操作符之外,其他的幾個(gè)操作符可以作用于整數(shù)和浮點(diǎn)數(shù)
- 對(duì)于 / 操作符如果兩個(gè)操作數(shù)都為整數(shù),執(zhí)行整數(shù)除法。而只要有浮點(diǎn)數(shù)執(zhí)行的就是浮點(diǎn)數(shù)除法
- % 操作符的兩個(gè)操作數(shù)必須為整數(shù)。返回的是整除之后的余數(shù)
3、移位操作符
移位操作符的操作數(shù)只能是整數(shù)
<< 左移操作符
>> 右移操作符
3.1 左移操作符
- 移位規(guī)則:左邊拋棄、右邊補(bǔ)0
- 整數(shù)是 int 型,占4個(gè)字節(jié),有32位表示。其中最高位表示符號(hào),0為正,1為負(fù)
- 整數(shù)在內(nèi)存中存儲(chǔ)的是補(bǔ)碼的二進(jìn)制,正數(shù)的原碼、反碼、補(bǔ)碼是相同的
- 操作符對(duì)整數(shù)操作的流程:
(1)先將整數(shù)的原碼轉(zhuǎn)換成反碼
(2)反碼 +1轉(zhuǎn)換成補(bǔ)碼
(3)最后對(duì)整數(shù)的補(bǔ)碼進(jìn)行操作
(4)操作結(jié)束后,將操作后的補(bǔ)碼 -1 轉(zhuǎn)換成反碼
(5)將反碼轉(zhuǎn)換成最終的原碼
- 函數(shù)printf打印的是整數(shù)的原碼
3.1.1 正數(shù)左移1位
代碼如下(示例):
int main() { int a = 5; int b = a << 1;//操作的補(bǔ)碼二進(jìn)制位,a本身結(jié)果不變 printf("%d\n", a);//打印5 printf("%d\n", b);// -10 return 0; }
結(jié)果運(yùn)行見下圖,與分析的結(jié)果一致,左移1位的效果相當(dāng)于乘以2,左移在51單片機(jī)、STM32中,操作寄存器會(huì)經(jīng)常用到。
3.1.2 負(fù)數(shù)左移1位
int main() { int a = -5; int b = a << 1;//<< >> 操作的二進(jìn)制位 printf("%d\n", a);//打印-5 printf("%d\n", b);// -10 return 0; }
運(yùn)行結(jié)果見下圖,和分析的結(jié)果一致
3.2 右移操作符
右移移位規(guī)則運(yùn)算分兩種:
- 邏輯移位:左邊用0填充,右邊丟棄
- 算術(shù)移位:左邊用原該值的符號(hào)位填充,右邊丟棄
3.2.1 正數(shù)右移1位
int main() { int a = 5; int b = a >> 1;//右移不一定是除2 printf("%d\n", a);//打印-5 printf("%d\n", b);// -3 return 0; }
下面分析右移的過程:正數(shù)的原碼、反碼、補(bǔ)碼一樣
00000000 00000000 00000000 00000101 //5的二進(jìn)制補(bǔ)碼
//算術(shù)右移:左邊用原該值的符號(hào)位1填充,右邊丟棄1
00000000 00000000 00000000 00000010 //右移后的補(bǔ)碼
//右移后的補(bǔ)碼就是右移后的原碼 2
結(jié)果見下圖:
3.2.2 負(fù)數(shù)右移1位
int main() { int a = -5; int b = a >> 1;//右移不一定是除2 printf("%d\n", a);//打印-5 printf("%d\n", b);// -3 return 0; }
下面分析右移的過程:
10000000 00000000 00000000 00000101 //-5的二進(jìn)制原碼
11111111 11111111 11111111 11111010 //反碼
11111111 11111111 11111111 11111011 //補(bǔ)碼:反碼+1
//算術(shù)右移:左邊用原該值的符號(hào)位1填充,右邊丟棄1
11111111 11111111 11111111 11111101 //右移后的補(bǔ)碼
11111111 11111111 11111111 11111100 //反碼:補(bǔ)碼-1
10000000 00000000 00000000 00000011 //原碼 -3
結(jié)果見下圖:
3.3 移位操作符說明
注意事項(xiàng):
- 右移操作符采用邏輯移位還是算術(shù)移位,取決于電腦編譯器,我的是算術(shù)移位,所以舉例以算術(shù)移位分析的,邏輯移位分析流程一樣
- 對(duì)于移位運(yùn)算符,不要移動(dòng)負(fù)數(shù)位,這個(gè)是標(biāo)準(zhǔn)未定義的,例如:
int num = 10; num>>-1;//10右移-1位,這是錯(cuò)誤的表達(dá)
4、位操作符
位操作符有:
& //按位與 相同為1, 相異為0
| //按位或 有1為1, 全0為0
^ //按位異或 相同為0, 相異為1
//注:他們的操作數(shù)必須是整數(shù)
int main() { int a = 3; int b = -5; int c = a & b; int d = a | b; int e = a ^ b;//異或 //對(duì)應(yīng)的二進(jìn)制位:相同位0,相異為1 printf("%d\n", c);// 打印3 printf("%d\n", d);// -5 printfan("%d\n", e);// -8 return 0; }
00000000 00000000 00000000 00000011 3的補(bǔ)碼
11111111 11111111 11111111 11111011 -5的補(bǔ)碼
//按位與: 相同為1, 相異為0
00000000 00000000 00000000 00000011 3的補(bǔ)碼,原碼表示3
//按位或: 有1為1, 全0為0
11111111 11111111 11111111 11111011 -5的補(bǔ)碼,原碼表示-5
//按位異或: 相同為0, 相異為1
11111111 11111111 11111111 11111000 補(bǔ)碼
11111111 11111111 11111111 11110111 反碼
10000000 00000000 00000000 00001000 原碼 -8
輸出結(jié)果見下圖,與分析一致:
4.1 練習(xí) 1
不能創(chuàng)建臨時(shí)變量(第三個(gè)變量),實(shí)現(xiàn)兩個(gè)數(shù)的交換
int main() { int a = 3; int b = 5; printf("a=%d b=%d\n", a, b); //第一種,常用的方法,創(chuàng)建中間變量 int tmp = a; a = b; b = tmp; //第二種,不創(chuàng)建變量 a = a + b; b = a - b; a = a - b; //第三種,不創(chuàng)建變量,很難想到 a = a ^ b; b = a ^ b; a = a ^ b; printf("a=%d b=%d\n", a, b); return 0; }
4.2 練習(xí) 2
求一個(gè)整數(shù)存儲(chǔ)在內(nèi)存中的二進(jìn)制中1的個(gè)數(shù)
//舉例: 5 &1, 然后右移1位, 再&1
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000001
int main() { int num = 0; scanf("%d", &num); int i = 0; int cnt = 0; //位操作 for ( i = 0; i < 32; i++) {//每次右移一位就 &1 if (1==((num>>i)&1)) { cnt++;//所有位與1,相同為1,相異為0 } } printf("%d", cnt); return 0; }
總結(jié)
本文對(duì)部分操作符進(jìn)行了,介紹,也分析了操作符的具體實(shí)現(xiàn)過程,這里了解原理即可,具體運(yùn)算交給計(jì)算機(jī)執(zhí)行,沒必要每個(gè)都自己畫圖分析,耗時(shí),不細(xì)心可能還會(huì)出錯(cuò),32位二進(jìn)制建議大家劃分成4個(gè)字節(jié),8位一組,好看一些,這在STM32 單片機(jī)對(duì)寄存器操作時(shí),經(jīng)常這樣劃分,一目了然。
到此這篇關(guān)于C語言操作符超詳細(xì)講解上篇的文章就介紹到這了,更多相關(guān)C語言 操作符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言編程計(jì)算信噪比SNR理解學(xué)習(xí)
這篇文章主要介紹了C語言編程信噪比SNR計(jì)算的理解學(xué)習(xí),信噪比,英文名稱叫做SNR或S/N(SIGNAL-NOISE RATIO)。是指一個(gè)電子設(shè)備或者電子系統(tǒng)中信號(hào)與噪聲的比例2021-10-10虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程
虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程,需要的朋友可以參考下2013-02-02C++面試題之?dāng)?shù)a、b的值互換(不使用中間變量)
這篇文章主要介紹了不使用中間變量,C++實(shí)現(xiàn)數(shù)a、b的值互相轉(zhuǎn)換操作,感興趣的小伙伴們可以參考一下2016-07-07