C語(yǔ)言中各種運(yùn)算類型全面總結(jié)
一、概述
C語(yǔ)言中支持下面4種類型的運(yùn)算
運(yùn)算類型 | 運(yùn)算符 |
四則運(yùn)算 | +,-,*,/,% |
關(guān)系運(yùn)算 | <,>,<=,>=,==,!= |
邏輯運(yùn)算 | &&,||,! |
位運(yùn)算 | &,|,^,>>,<<,~ |
二、四則運(yùn)算
(+,-,*,/,%)
- 就是數(shù)學(xué)中的加,減,乘,除等運(yùn)算
- 遵循先乘除后加減的運(yùn)算優(yōu)先級(jí)
- 可以使用括號(hào)改變運(yùn)算順序
注意:
C語(yǔ)言中的除法運(yùn)算,其除數(shù)不能為0
下面通過(guò)一段程序感受一下:
#include <stdio.h> int main() { int a = 5; int b = 2; double c = 3; c = a / b; printf("c = %f\n", c); c = a % b; printf("c = %f\n", c); return 0; }
下面為輸出結(jié)果:
通過(guò)上面的代碼,可以得到一些小結(jié)論:
- 整型數(shù)的除法運(yùn)算結(jié)果會(huì)舍棄小數(shù)部分
- 取余(%)運(yùn)算也是一種除法運(yùn)算,結(jié)果為余數(shù)
- 浮點(diǎn)數(shù)不能進(jìn)行取余運(yùn)算
三、關(guān)系運(yùn)算
(<,>,<=,>=,==,!=)
- 比較兩個(gè)值大小關(guān)系或相等關(guān)系的運(yùn)算
- 比較的結(jié)果為邏輯值: 真(1),假(0)
- 可以使用括號(hào)()改變關(guān)系運(yùn)算的順序
如上面的圖片所示,c 的值就為0
下面通過(guò)一段代碼,感受一下:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 3; c = a != b; printf("c = %d\n", c); c = a - b >= a + b; printf("c = %d\n", c); c = (a < b) + (c < b); printf("c = %d\n", c); return 0; }
下面為輸出結(jié)果:
小技巧:如果不同類型的運(yùn)算同時(shí)出現(xiàn)在一個(gè)表達(dá)式中,那么盡量使用括號(hào)()指明運(yùn)算順序。
運(yùn)算優(yōu)先級(jí)(優(yōu)先級(jí):四則運(yùn)算 > 關(guān)系運(yùn)算 > 賦值操作)
四則運(yùn)算
- 正負(fù)號(hào) > 乘除運(yùn)算 > 加減運(yùn)算
關(guān)系運(yùn)算
- 大小比較運(yùn)算 > 相等比較運(yùn)算
賦值操作
下面看一段代碼,深入感受一下運(yùn)算優(yōu)先級(jí):
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a != b + a * b; printf("c = %d\n", c); return 0; }
下面為輸出結(jié)果,可以看出,c 的輸出結(jié)果為1,為什么為1呢?這是由于乘法優(yōu)先級(jí)大于加法優(yōu)先級(jí)大于關(guān)系運(yùn)算優(yōu)先級(jí),所以程序執(zhí)行過(guò)程是這樣,先計(jì)算 a * b,然后將 a * b 的結(jié)果 2 加上 b,得到4,最后再比較 a != 4,得到的結(jié)果當(dāng)然為1啦,我們還可以通過(guò)反匯編來(lái)觀察代碼的執(zhí)行過(guò)程。
c = a != b + a * b的匯編代碼
所以如果想得到a != b 再加上a * b的結(jié)果,一定要記得加括號(hào),如下:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = (a != b) + (a * b); printf("c = %d\n", c); return 0; }
這樣才能得到正確結(jié)果,如下所示:
小結(jié):
- 整型數(shù)除法有兩種:取商(/),取余(%)
- 浮點(diǎn)數(shù)除法與數(shù)學(xué)中除法運(yùn)算相同,結(jié)果為浮點(diǎn)數(shù)
- 不同運(yùn)算的優(yōu)先級(jí)不同,可使用括號(hào)改變運(yùn)算優(yōu)先級(jí)
- 同一個(gè)表達(dá)式中應(yīng)避免不同的運(yùn)算類型(四則運(yùn)算,關(guān)系運(yùn)算)
四、邏輯運(yùn)算與位運(yùn)算
邏輯運(yùn)算(&&,ll,!)
- 邏輯運(yùn)算的參與者為邏輯值(真或假)
- 任何非零值在邏輯運(yùn)算中都為真
- 任何零值在邏輯運(yùn)算中都為假
左操作數(shù) | 右操作數(shù) | 結(jié)果 |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
左操作數(shù) | 右操作數(shù) | 結(jié)果 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
邏輯運(yùn)算中的短路法則
對(duì)于&&運(yùn)算
- 從左向右進(jìn)行,如果有一個(gè)操作數(shù)為假,則整個(gè)表達(dá)式為假
- 第一個(gè)為假的操作數(shù)之后的其它操作數(shù)不再計(jì)算
對(duì)于||運(yùn)算
- 從左向右進(jìn)行,如果有一個(gè)操作數(shù)為真,則整個(gè)表達(dá)式為真
- 第一個(gè)為真的操作數(shù)之后的其它操作數(shù)不再計(jì)算
取非運(yùn)算(!)
單目運(yùn)算(只需要一個(gè)操作數(shù)),運(yùn)算結(jié)果為邏輯值
- 對(duì)真值取非的結(jié)果為假
- 對(duì)假值取非得結(jié)果為真
話不多說(shuō),上代碼:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a && b; printf("c = %d\n", c); c = !(a - b) || (c < b); printf("c = %d\n", c); c = 10000; c = !!c; printf("c = %d\n", c); return 0; }
下面為運(yùn)行結(jié)果:
位運(yùn)算(&,|,~,^,<<,>>)
- 直接對(duì)數(shù)據(jù)的二進(jìn)制位進(jìn)行操作
- 位運(yùn)算的基本單位是二進(jìn)制位,所以也是一種0和1的操作
- 可以使用括號(hào)()改變位運(yùn)算的運(yùn)算順序
- 位運(yùn)算的操作數(shù)只能是整型數(shù)(浮點(diǎn)數(shù)不能直接進(jìn)行位運(yùn)算)
運(yùn)算符 | 含義 | 示例 | 優(yōu)先級(jí) |
~ | 按位求反 | ~0101 -> 1010 | 1(高) |
<< | 左移:高位移出,低位補(bǔ)0 | 0011 << 1 -> 0110 | 2 |
>> | 右移:低位移出,高位補(bǔ)符號(hào)位 | 0101 >> 2 -> 0001 | 2 |
& | 按位與 | 0111 & 1100 -> 0100 | 3 |
^ | 按位異或:相同為0,不同為1 | 0111 ^ 1100 -> 1011 | 4 |
| | 按位或 | 0111 | 1100 -> 1111 | 5(低) |
注:
1.按位與和邏輯與的計(jì)算法相同:兩者為1,結(jié)果為1,否則為0
2.按位或和邏輯或的計(jì)算法相同:兩者為0,結(jié)果為0,否則為1
位運(yùn)算實(shí)例
- 將整數(shù)5的第2個(gè)二進(jìn)制位置1
- 將整數(shù)7的第4個(gè)二進(jìn)制位取反
- 將整數(shù)2的最后兩位取反
- 將整數(shù)15右移2位,再將第2個(gè)二進(jìn)制位置0
- 設(shè)變量a的二進(jìn)制數(shù)是10101101,若想通過(guò)運(yùn)算a ^ b使得a的中間4位取反,其余位不變,則b的值是多少?
代碼如下:
#include <stdio.h> int main() { printf("c = %d\n", 5 | 2); printf("c = %d\n", 7 ^ 8); printf("c = %d\n", 2 ^ 3); printf("c = %d\n", (15 >> 2) & 13); printf("c = %d\n", 173 ^ 60); return 0; }
運(yùn)行結(jié)果如下:
這里需要特別注意:對(duì)某一位或者某幾位取反可以用異或(^)運(yùn)算,這在工程里常用!??!
運(yùn)算優(yōu)先級(jí)(優(yōu)先級(jí)從上到下為由高到低)
- 正負(fù)號(hào)>邏輯非>按位取反
- 乘除>加減>按位左右移
- 大小比較運(yùn)算>相等比較運(yùn)算
- 按位與>按位異或>按位或
- 邏輯與>邏輯或
- 賦值操作
小結(jié)
- 邏輯運(yùn)算中有特殊的短路法則,結(jié)果確定后不再向下計(jì)算
- C語(yǔ)言中的真值對(duì)應(yīng)非零值,假值對(duì)應(yīng)零值
- 位運(yùn)算直接對(duì)數(shù)據(jù)的二進(jìn)制位進(jìn)行操作
- 位運(yùn)算的操作數(shù)只能是整型數(shù)(浮點(diǎn)數(shù)不能直接進(jìn)行位運(yùn)算)
五、深度剖析位運(yùn)算
不同類型的本質(zhì)在于:
占用的內(nèi)存大小不同,如:short占用2字節(jié),int占用4字節(jié)
表示具體數(shù)據(jù)的方式不同
- 正整數(shù)用原碼表示,負(fù)整數(shù)用補(bǔ)碼表示
- 整數(shù)型和浮點(diǎn)型的二進(jìn)制表示不同
位運(yùn)算時(shí)需要明確的知道的事
- 操作數(shù)的類型(占用的內(nèi)存大小)
- 操作數(shù)是正數(shù)還是負(fù)數(shù)(符號(hào)位,數(shù)據(jù)表示)
- 不同類型的操作數(shù)先自動(dòng)對(duì)齊再進(jìn)行位運(yùn)算(補(bǔ)符號(hào)位)
如下面的一段代碼:
short a = 1; int b = 4; int c = a | b; printf("c = %d\n",c);
b為int類型,占4個(gè)字節(jié),a為short類型,占2個(gè)字節(jié)。所以a要先要補(bǔ)符號(hào)位,由于a是正數(shù),所以補(bǔ)0,這樣就可以進(jìn)行位運(yùn)算了,得出c的結(jié)果為5。
下面來(lái)看一段代碼:
#include <stdio.h> int main() { short a = 1; short b = 2; int c = a - b; c = c >> 4; printf("c = %d\n", c); c = c * -1 * 16 >> 4; printf("c = %d\n", c); printf("c = %d\n", 16 << 2); return 0; }
下面為輸出結(jié)果:
小結(jié)論
- 正數(shù)符號(hào)位為0,右移運(yùn)算時(shí),高位補(bǔ)0,低位移除
- 負(fù)數(shù)符號(hào)位為1,右移運(yùn)算時(shí),高位補(bǔ)1,低位移除
- 左移運(yùn)算時(shí),最高位移除,低位補(bǔ)0
- 最高位的具體位置,由數(shù)據(jù)類型決定
類型補(bǔ)充小知識(shí)
- char 字符型,一個(gè)字節(jié)的整型,范圍[-128,127]
- 字符數(shù)據(jù)(單引號(hào)括起來(lái)的字符)的本質(zhì)是整型數(shù)
- char類型的變量可以打印為整數(shù)或者字符
再看一段代碼:
#include <stdio.h> int main() { char c = 'A'; short a = c; int b = c; printf("c = %c\n", c); printf("c = %d\n", c); printf("a = %d\n", a); printf("b = %d\n", b); c = 0x40; printf("c = %x\n", c); printf("c = %d\n", c); c = c << 1; printf("c = %d\n", c); c = c << 1; printf("c = %d\n", c); return 0; }
下面為輸出結(jié)果:
需要注意的是,因?yàn)閏為char類型,所以64左移1位后,用二進(jìn)制表示為1000 0000,最高位的1表示符號(hào)位,所以就是-128。
小結(jié)
- 不同類型的本質(zhì)區(qū)別是:占用內(nèi)存不同,數(shù)據(jù)表示不同
- 右移運(yùn)算時(shí),高位補(bǔ)符號(hào)位,低位移除
- char是只占用一個(gè)字節(jié)的整型,可表示英文字符
- 數(shù)據(jù)符號(hào)位的具體位置由數(shù)據(jù)類型決定
到此這篇關(guān)于C語(yǔ)言中各種運(yùn)算類型全面總結(jié)的文章就介紹到這了,更多相關(guān)C語(yǔ)言運(yùn)算類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)學(xué)生宿舍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生宿舍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Opencv?視頻讀取與寫入的實(shí)現(xiàn)示例
本文將介紹如何使用OpenCV進(jìn)行視頻讀寫。通過(guò)閱讀本文,您將了解如何讀取視頻文件、處理視頻幀、寫入視頻文件等操作,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08C語(yǔ)言循環(huán)語(yǔ)句之重復(fù)執(zhí)行特定的代碼塊
在C語(yǔ)言中分支和循環(huán)語(yǔ)句是實(shí)現(xiàn)條件執(zhí)行和重復(fù)執(zhí)行的重要工具,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言循環(huán)語(yǔ)句之重復(fù)執(zhí)行特定的代碼塊的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01C++ OpenCV實(shí)現(xiàn)銀行卡號(hào)識(shí)別功能
這篇文章主要介紹了如何使用OpenCV C++實(shí)現(xiàn)銀行卡號(hào)識(shí)別功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,需要的可以參考一下2022-01-01C++實(shí)現(xiàn)LeetCode(9.驗(yàn)證回文數(shù)字)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(9.驗(yàn)證回文數(shù)字),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07隊(duì)列的動(dòng)態(tài)鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn)代碼分享
DynaLnkQueue.cpp - 動(dòng)態(tài)鏈?zhǔn)疥?duì)列,即隊(duì)列的動(dòng)態(tài)鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn)2014-02-02如何用C寫一個(gè)web服務(wù)器之CGI協(xié)議
本文主要介紹了如何用C寫一個(gè)web服務(wù)器之CGI協(xié)議,對(duì)C語(yǔ)言和web感興趣的同學(xué),可以詳細(xì)看下,并且試驗(yàn)一下。2021-05-05