詳細(xì)介紹了C語言表達(dá)式、算術(shù)運(yùn)算符、賦值運(yùn)算符、關(guān)系運(yùn)算符、條件結(jié)構(gòu)、邏輯運(yùn)算符、位運(yùn)算符的語法和使用方法,并討論了運(yùn)算符的優(yōu)先級。
1、表達(dá)式與算術(shù)運(yùn)算符
在C語言中,表達(dá)式是一個(gè)類似數(shù)學(xué)中的算式,表達(dá)式由變量、字面值、常量、運(yùn)算符號構(gòu)成。表達(dá)式的計(jì)算結(jié)果是一個(gè)值,值的類型可以數(shù)值,也可以是邏輯值。
【 例3-1 】 計(jì)算存款一年本金利息和的表達(dá)式
deposit*(1+rate)
在上面的表達(dá)式中,deposit是存儲(chǔ)存款額度的變量,rate是存儲(chǔ)銀行年利率的變量,數(shù)字1是字面值,符號“*”是乘法運(yùn)算符,表達(dá)式中的括號和數(shù)學(xué)四則運(yùn)算的括號意義相同,用于提高括號內(nèi)子表達(dá)式的運(yùn)算優(yōu)先級。
觀察發(fā)現(xiàn),1+rate也是一個(gè)表達(dá)式,它符合表達(dá)式的定義,在當(dāng)前表達(dá)式中,該表達(dá)式為子表達(dá)式,因此一個(gè)復(fù)雜的表達(dá)式由多個(gè)子表達(dá)式構(gòu)成。
在C語言中,表達(dá)式中的運(yùn)算符號稱為運(yùn)算符,運(yùn)算符作用的變量、常量、字面值、子表達(dá)式稱為操作數(shù)。例如:運(yùn)算符號“*”兩邊的操作數(shù)為變量deposit和子表達(dá)式(1+rate);運(yùn)算符號“+”兩邊的操作數(shù)為字面值1和變量rate。
運(yùn)算符若需要N個(gè)操作數(shù)參與運(yùn)算,則稱為N目運(yùn)算符。例如:加法、乘法、除法等運(yùn)算符都需要兩個(gè)操作數(shù)參與運(yùn)算,稱為雙目運(yùn)算符;自增、自減運(yùn)算符需要單個(gè)操作數(shù)參與運(yùn)算,稱為單目運(yùn)算符。
表達(dá)式左側(cè)一般是待賦值的變量,該表達(dá)式返回的結(jié)果為浮點(diǎn)類型,計(jì)算結(jié)果賦值給表達(dá)式左側(cè)的變量。
例如:
total = deposit*(1+rate)
表達(dá)式的計(jì)算結(jié)果賦值給變量total。
【 例3-1 】表達(dá)式的運(yùn)算符在運(yùn)算類型屬于算術(shù)運(yùn)算符,其作用和數(shù)學(xué)中的運(yùn)算符相同,下表列出了C語言支持的算術(shù)運(yùn)算符。
表中的加、減、乘、除運(yùn)算符比較容易理解和掌握,下面重點(diǎn)介紹取余、自增、自減運(yùn)算符。
取余運(yùn)算符
取余運(yùn)算符是雙目運(yùn)算符,需要兩個(gè)操作數(shù)。可以用來計(jì)算兩個(gè)數(shù)之間的余數(shù),它可以用在整數(shù)和浮點(diǎn)數(shù)之間,但是最終結(jié)果只能是整數(shù)。運(yùn)算結(jié)果是運(yùn)算符左邊的操作數(shù)除以運(yùn)算符右邊的操作數(shù)后所得的余數(shù)。
假設(shè) a % b =c(余數(shù)為d),其中a和b均為整數(shù),則余數(shù)d為a % b的結(jié)果。
取余運(yùn)算符可以解決一些簡單的數(shù)學(xué)問題。例如:可以使用取余運(yùn)算符來檢查一個(gè)數(shù)是否為偶數(shù),如果一個(gè)數(shù)除以2的余數(shù)是0,那么它就是偶數(shù);也可以用來檢查一個(gè)數(shù)是否是3的倍數(shù),如果一個(gè)數(shù)除以3的余數(shù)是0,那么它就是3的倍數(shù)。
自增自減運(yùn)算符
自增自減是單目運(yùn)算符,只需要一個(gè)操作數(shù)參加運(yùn)算。自增和自減從字面上理解就是自身增加或減少,增加或減少多少呢?自增是自身做加1操作,自減是自身做減1操作。在c語言中,并不是所有變量都可以使用自增自減操作符;可以使用自增自減操作符的數(shù)據(jù)類型有:int、float、double 、char、long。
自增(++):將變量的值加1,分前綴式(如++a)和后綴式(如a++)。前綴式是先加1再使用;后綴式是先使用再加1。
例如:
int count=10;
printf("count=%d",count++);
上述程序段執(zhí)行后,輸出結(jié)果是10還是11呢?count++是后綴式,后綴式是先使用再加1,因此先輸出count的當(dāng)前數(shù)值,然后count再做加1操作,輸出結(jié)果是10。
int count=10;
printf("count=%d",++count);
上述程序段執(zhí)行后,輸出結(jié)果是11。因?yàn)?+count是前綴式,前綴式是變量先自增再使用,變量count先做加1操作,然后再輸出變量count的值。
自減(--):將變量的值減1,也分前綴式(如--a)和后綴式(如a--)。前綴式是先減1再使用;后綴式是先使用再減1。
2、賦值運(yùn)算符
我們回顧一下數(shù)學(xué)運(yùn)算符號“=”,在數(shù)學(xué)中該符號是表示相等的符號,讀作“等于”。等號表示兩端的數(shù)字、算式是相等的。如:2+3=5,就是表示等號左邊的2加上3與右邊的5是相等的,7-2=2+3表示左右兩邊算式相等。
在C語言中,也用到了符號“=”,不過和數(shù)學(xué)中的等號意義完全不同,C語言中的“=”是賦值的意思,該符號是賦值運(yùn)算符,它是一個(gè)雙目運(yùn)算符,它的作用是將右側(cè)的值賦值給左側(cè)的變量。
例如:
int a,b;a = 30;b = a+20;
上述代碼執(zhí)行后,a的值為30,b的值為50。賦值運(yùn)算符“=”左側(cè)的操作數(shù)必須是變量,右側(cè)的操作數(shù)可以字面值、變量、常量或表達(dá)式,若賦值運(yùn)算符右邊的操作數(shù)為表達(dá)式,編譯器會(huì)先計(jì)算表達(dá)式的值,然后再將值賦值給運(yùn)算符左側(cè)的變量。
可以在聲明變量時(shí)為變量賦值:
int a=30,b=a+20;
上面的語句在定義變量b時(shí)用到了變量a,因?yàn)樽兞縜在變量b之前已被定義,因此上面的語句是合法的。
為了簡化計(jì)算,C語言還提供了復(fù)合賦值運(yùn)算符,復(fù)合賦值運(yùn)算符是賦值運(yùn)算符和算術(shù)運(yùn)算符合并成一個(gè)新的運(yùn)算符,該運(yùn)算符稱為復(fù)合賦值運(yùn)算符。使用復(fù)合賦值運(yùn)算符時(shí),被賦值的變量首先使用算術(shù)運(yùn)算符與右側(cè)的數(shù)值或算術(shù)表達(dá)式進(jìn)行運(yùn)算,然后將運(yùn)算結(jié)果再賦值給變量。
賦值運(yùn)算符可以和所有的算術(shù)運(yùn)算符結(jié)合構(gòu)成復(fù)合賦值運(yùn)算符,運(yùn)算效果等同于上圖的“+=”復(fù)合賦值運(yùn)算符。表3-2列出了“+=、-=、*=、/=、%=”復(fù)合賦值運(yùn)算符的描述及例子。
在復(fù)合賦值運(yùn)算符表格中,“例子”一欄中a是變量。運(yùn)算順序是先執(zhí)行算術(shù)運(yùn)算,然后再執(zhí)行賦值運(yùn)算。運(yùn)算符右側(cè)的操作數(shù)可以是數(shù)值、也可以是算術(shù)表達(dá)式,算術(shù)表達(dá)式的運(yùn)算順序同數(shù)學(xué)運(yùn)算順序一致。
下面給出復(fù)合賦值運(yùn)算符“+=”的解釋說明,其它復(fù)合賦值運(yùn)算符的運(yùn)算過程基本相同。
復(fù)合賦值運(yùn)算符“+=”,表示的意思是先將運(yùn)算符左邊操作數(shù)指向的變量值和右邊的操作數(shù)執(zhí)行相加操作,然后再將相加的結(jié)果賦值給左邊的操作數(shù)指向的變量。例如下面語句:
int a = 10;
a += 20;
此時(shí),變量a等于30,其過程是變量a先與數(shù)值20相加,因?yàn)樽兞縜的值是10,因此與數(shù)值20相加的結(jié)果是30,再將30賦值給變量a,此時(shí)變量a的值為30。
3、關(guān)系運(yùn)算符
人們在網(wǎng)上挑選商品時(shí),一般會(huì)使用電商的商品價(jià)格排序功能,將商品按照價(jià)格從低到高排列,然后再看商品的評論多少和評論內(nèi)容來篩選商品,這樣就會(huì)大概率買到質(zhì)優(yōu)價(jià)廉的商品。
電商的商品價(jià)格排序功能的核心就是比較商品間的價(jià)格高低,也就是比較多個(gè)數(shù)值的大小,并對數(shù)值按從小到大或從大到小排序。
比較兩個(gè)數(shù)值的大小,也就是要弄清兩個(gè)數(shù)之間的大小關(guān)系。兩個(gè)數(shù)之間的大小主要存在六種關(guān)系,分別是大于關(guān)系、大于等于關(guān)系、小于關(guān)系、小于等于關(guān)系、等于關(guān)系、不等于關(guān)系。例如,對于35和26兩個(gè)數(shù)來說:35大于26就是大于關(guān)系;26小于35就是小于關(guān)系。
用于比較兩個(gè)數(shù)大小的運(yùn)算符稱為關(guān)系運(yùn)算符,關(guān)系運(yùn)算符是雙目運(yùn)算符,用在關(guān)系表達(dá)式中。用于判斷兩個(gè)數(shù)據(jù)之間的關(guān)系,例如:大于、等于、不等于,比較的結(jié)果是一個(gè)整型數(shù)值1或 0,1表示“真”,0表示“假”。當(dāng)條件成立時(shí),運(yùn)算結(jié)果為1;當(dāng)條件不成立時(shí),運(yùn)算結(jié)果為0。下表列出了C語言支持的比較運(yùn)算符,表中例子假設(shè)A和B不相等且A小于B。
表3-3的A和B是兩個(gè)整數(shù)類型的變量,且A小于B。運(yùn)算符“==”檢查A和B的值是否相等,因?yàn)锳和B不相等,因此關(guān)系表達(dá)A==B返回0(假),關(guān)系表達(dá)式A!=B則返回1(真)。
4、條件結(jié)構(gòu)
我們通過一個(gè)編程案例來引入條件結(jié)構(gòu)。
編程案例:要求用戶輸入兩個(gè)不相等的整數(shù),如果這兩個(gè)數(shù)的和大于100,則顯示“兩數(shù)和大于100”,否則顯示“兩數(shù)和小于等于100”
應(yīng)用我們前面學(xué)過的C語言知識,類似這樣的編程要求很難實(shí)現(xiàn),因?yàn)槌绦蛐枨笊婕暗搅藯l件判斷,并根據(jù)條件判斷結(jié)果選擇不同的執(zhí)行分支。在生活中,也常常會(huì)遇到許多需要判斷的情況,在這種情況下,需要根據(jù)一些條件作出決定和選擇。例如,在我們打算出門時(shí),需要判斷天氣怎么樣,如果下雨了,就要帶上雨傘;外出旅行時(shí),需要根據(jù)不同情況,選擇不同的交通工具。
下面我們來學(xué)習(xí)一種新的程序結(jié)構(gòu)——條件結(jié)構(gòu)。
前面編寫的程序都是“順序流程”,每條語句順序執(zhí)行。但是在很多情況下,程序并不是按既定的順序執(zhí)行,而是根據(jù)不同請況進(jìn)行判斷,然后執(zhí)行不同的操作,這種流程稱為“條件分支流程”,其結(jié)構(gòu)也稱為“條件結(jié)構(gòu)”。
條件結(jié)構(gòu)的核心是條件判斷,在C語言中,條件判斷可以使用關(guān)系表達(dá)來實(shí)現(xiàn),關(guān)系表達(dá)式的計(jì)算結(jié)果返回邏輯真或邏輯假,在C語言中非0數(shù)值表示邏輯真,數(shù)值0表示邏輯假。若關(guān)系表達(dá)式返回邏輯真,則執(zhí)行分支語句塊A,否則執(zhí)行分支語句塊B,這里的分支語句塊A和分支語句塊B是不同的執(zhí)行語句塊,在條件結(jié)構(gòu)中,A語句塊和B語句塊永遠(yuǎn)不能同時(shí)執(zhí)行。
在C語言中,提供了if-else語法結(jié)構(gòu)來實(shí)現(xiàn)條件結(jié)構(gòu)。
其中if和else是C語言的關(guān)鍵字,<條件>是一個(gè)關(guān)系表達(dá)式、變量或字面值。變量或字面值的類型應(yīng)為整數(shù)、浮點(diǎn)類型。C語言規(guī)定非0的數(shù)值為邏輯真,數(shù)值0為邏輯假。<條件>執(zhí)行后,若返回邏輯真執(zhí)行<分支語句塊A>,否則執(zhí)行<分支語句塊B>。
在一些情況下,可能只需要執(zhí)行滿足條件的<分支語句塊A>,而不需要執(zhí)行不滿足條件的<分支語句塊B>,在這種情況下,就可以把else和<分支語句塊B>省略掉。
現(xiàn)在,我們已經(jīng)了解了C語言的條件結(jié)構(gòu)和語法,下面探討一下如何在條件結(jié)構(gòu)中使用關(guān)系表達(dá)式。
例如:要測試兩個(gè)整數(shù)類型的變量值num1和num2是否相等,可以編寫num1 == num2,然后將其放入一個(gè)條件結(jié)構(gòu)中,如下所示:
if ( num1==num2 )
{
……
}
else
{
……
}
如果num1和num2的數(shù)值相等,則條件為真,執(zhí)行if后面的語句塊,否則條件為假,執(zhí)行else后面的語句塊。
下面我們來實(shí)現(xiàn)前面的程序需求,編寫程序前,先繪制程序流程圖。
在程序流程圖中,條件結(jié)構(gòu)使用菱形圖形符號表示,該圖形符號有一個(gè)輸入和兩個(gè)輸出分支,分別對應(yīng)條件判斷的邏輯真和邏輯假。
程序清單
#include
void main()
{
int x,y;
// 提示用戶輸入兩個(gè)整數(shù)
printf("請輸入兩個(gè)整數(shù)數(shù):n");
// 獲取用戶的輸入
scanf("%d",&x);
scanf("%d",&y);
// 條件結(jié)構(gòu)
if ((x+y) > 100)
printf("x+y >100");
else
printf("x+y<=100");
}
5、邏輯運(yùn)算符
在數(shù)學(xué)中,表示一個(gè)數(shù)值的范圍時(shí),經(jīng)常用不等式來表述。例如:假設(shè)一個(gè)數(shù)值取值范圍為0到100,設(shè)該數(shù)值為x,不等式0
例如:要判斷學(xué)生的考試成績是否在90至100范圍內(nèi),就需要使用邏輯運(yùn)算符連接兩個(gè)關(guān)系表達(dá)式來完成條件判斷。
下表列出了C語言支持的邏輯運(yùn)算符,表中假設(shè)整型變量A為真(數(shù)值為1),整型變量B為假(數(shù)值為0)。
假如考試成績用變量score表示,下面的語句可以判斷score是否在90至100范圍內(nèi)。
score >=90 && score <=100
當(dāng)score的值在90至100范圍內(nèi)時(shí),上面語句的運(yùn)算結(jié)果為邏輯真(1)。因?yàn)檫\(yùn)算符“&&”兩邊的關(guān)系表達(dá)式的運(yùn)算結(jié)果都為邏輯真(1);當(dāng)score的值不在90至100范圍內(nèi)時(shí),上面語句的運(yùn)算結(jié)果為邏輯假(0)。因?yàn)檫\(yùn)算符“&&”兩邊的關(guān)系表達(dá)式的運(yùn)算結(jié)果都為邏輯假(0),或有一個(gè)關(guān)系表達(dá)式的運(yùn)算結(jié)果為邏輯假(0)。
例如下面的代碼段執(zhí)行完成后,bJudge的值是1還是0呢?
int a = 10;
int b = 20;
int c = 15;
int bJudge = c > a && c < b;
上述代碼段的最后一條語句同時(shí)出現(xiàn)了賦值運(yùn)算符、關(guān)系運(yùn)算符和邏輯運(yùn)算符,C編譯器會(huì)先執(zhí)行哪個(gè)運(yùn)算操作呢?同數(shù)學(xué)的四則運(yùn)算一樣,運(yùn)算符也有優(yōu)先級,運(yùn)算順序由高優(yōu)先級到低優(yōu)先級下表列出了運(yùn)算符的優(yōu)先級。表中優(yōu)先級欄,數(shù)字越小優(yōu)先級越高,運(yùn)算符每個(gè)運(yùn)算符用中文頓號分割。
表中小括號‘()’優(yōu)先級最高,表達(dá)式含有小括號的,優(yōu)先執(zhí)行小括號的內(nèi)容,如果包含多個(gè)小括號,執(zhí)行順序是從左到右。
例如,假設(shè)變量a的值為12,下述語句的執(zhí)行會(huì)有不同的結(jié)果:
(1)執(zhí)行 a + 18 % 4 ,因?yàn)檫\(yùn)算符%的優(yōu)先級高于運(yùn)算符+,該語句先執(zhí)行取余運(yùn)算,再執(zhí)行加法運(yùn)算,其結(jié)果為14;
(2)執(zhí)行( a + 18 ) % 4 ,因?yàn)樾±ㄌ柕膬?yōu)先級最高,該語句先執(zhí)行小括號里的表達(dá)式a+18,再執(zhí)行取余運(yùn)算,其結(jié)果為2;
(3)執(zhí)行 a * ( ( a + 18 ) % 4 ),該語句括號內(nèi)嵌套括號,執(zhí)行順序是先執(zhí)行內(nèi)層括號的運(yùn)算,再執(zhí)行外層括號的運(yùn)算,其運(yùn)算結(jié)果為24。
了解了運(yùn)算符的優(yōu)先級,現(xiàn)在可以確定下述語句:
int bJudge = c > a && c < b;
bJudge的值為數(shù)值1(邏輯真)。
邏輯與運(yùn)算符“&&”連接了2個(gè)關(guān)系表達(dá)式,分別是c > a和c < b,如果這兩個(gè)表達(dá)式計(jì)算結(jié)果都為真,則bJudge為1(真),否則bJudge為0(假)。此時(shí)bJudge的值為1(真)。該運(yùn)算符還有一個(gè)特點(diǎn),當(dāng)左側(cè)的關(guān)系表達(dá)式或變量為0(假)時(shí),則直接返回結(jié)果0(假),不再執(zhí)行運(yùn)算符右側(cè)的表達(dá)式。
邏輯或運(yùn)算符“||”,用于判斷運(yùn)算符兩邊的條件表達(dá)式或整型變量是否有一個(gè)為真,如果有一個(gè)為真,返回結(jié)果為1(真),否則返回0(假)。
邏輯非運(yùn)算符“!”,用于判斷運(yùn)算符兩邊的條件表達(dá)式或整型變量是否有一個(gè)為1(真),如果有一個(gè)為1(真),返回結(jié)果為1(真),否則返回0(假)。
6、位運(yùn)算
位運(yùn)算在嵌入式開發(fā)編程中是常用的一種運(yùn)算,單片機(jī)的控制方式都是通過寄存器完成的,寄存器操作一般采用位運(yùn)算或移位運(yùn)算。
C語言提供了六種位運(yùn)算操作符,分別是按位與(&)、按位或(|)、按位異或(^)、按位取反(~)、左移(<<)、右移(>>)。
注意:下面案例使用的數(shù)字8和14均為unsigned char類型,因?yàn)橛蟹栒麛?shù)進(jìn)行位運(yùn)算后,其符號位可能會(huì)改變。
按位與(&)
按位與的運(yùn)算符是“ & ”,它是一個(gè)雙目運(yùn)算符,它對運(yùn)算符兩邊的操作數(shù)按位進(jìn)行邏輯與運(yùn)算,其運(yùn)算規(guī)則是:0&0=0; 0&1=0; 1&0=0; 1&1=1,即:兩位同時(shí)為1,結(jié)果才為1,否則為0。
例如:8 & 14 的結(jié)果是8。
數(shù)字8的二進(jìn)制數(shù)是0000 1000,數(shù)字14的二進(jìn)制數(shù)是00010 1110,兩個(gè)二進(jìn)制數(shù)每位進(jìn)行邏輯與運(yùn)算,結(jié)果是0000 1000。
按位與運(yùn)算符在嵌入式開發(fā)中應(yīng)用非常廣泛,它可以用來判斷寄存器中的某一位是否為 1,也可以用來對寄存器某些位進(jìn)行清零操作。
假設(shè)一個(gè)8位寄存器AH的值為0x12,對應(yīng)的二進(jìn)制數(shù)為0001 0010,若需要判斷第2個(gè)二進(jìn)制位(從低位到高位)是否為1,可將AH與0x02進(jìn)行與運(yùn)算,若運(yùn)算結(jié)果為0x02,則第2個(gè)二進(jìn)制位為1,否則為0。
void main()
{
unsigned char AH = 0x12;
if( 0x02 == (AH & 0x02) )
{
printf("AH寄存器第2個(gè)二進(jìn)制位為1");
}
else
{
printf("AH寄存器第2個(gè)二進(jìn)制位為0");
}
}
上述代碼段的條件判斷也可以使用下面的語句:
if( AH & 0x02 )
因?yàn)?x02的二進(jìn)制數(shù)位0000 0010,只有第2個(gè)二進(jìn)制位為1,其它二進(jìn)制位都為0,與AH進(jìn)行與運(yùn)算后,若AH第2個(gè)二進(jìn)制位為1,則運(yùn)算結(jié)果為0x02,否則運(yùn)算結(jié)果為0,在C語言中,不為0的數(shù)值都為邏輯真。
按位或(|)
按位或的運(yùn)算符是“|”,它是一個(gè)雙目運(yùn)算符,它對運(yùn)算符兩邊的操作數(shù)按位進(jìn)行邏輯或運(yùn)算,其運(yùn)算規(guī)則是:0|0=0; 0|1=1; 1|0=1; 1|1=1,即:兩位只要有一個(gè)為1,其值為1,其它都為0。
例如:8 | 14 的結(jié)果是14。
按位異或(^)
按位異或的運(yùn)算符是“^”,它是一個(gè)雙目運(yùn)算符,它對運(yùn)算符兩邊的操作數(shù)按位進(jìn)行邏輯異或運(yùn)算,其運(yùn)算規(guī)則是:0^0=0; 0^1=1; 1^0=1; 1^1=0,即:如果兩個(gè)相應(yīng)位為“異”(值不同),則該位結(jié)果為1,否則為0。
例如:8 ^14 的結(jié)果是6。
按位取反(~)
按位取反的運(yùn)算符是“~”,它是一個(gè)單目運(yùn)算符,它對操作數(shù)按位進(jìn)行邏輯非運(yùn)算,其運(yùn)算規(guī)則是::~0=1; ~1=0;,即:0變?yōu)?,1變?yōu)?。
例如:~8的結(jié)果是247。
左移(>>)
左移運(yùn)算符是“>>”,它是雙目運(yùn)算符,它可以將運(yùn)算符左邊的操作數(shù)向左移動(dòng)指定的位數(shù),移動(dòng)的位數(shù)由運(yùn)算符右邊的操作數(shù)給出,移動(dòng)方向?yàn)閺淖蟮接遥苿?dòng)到左邊界之外的多余二進(jìn)制位會(huì)被丟棄,并從右邊移入0。
例如:8 >>2 的結(jié)果是32。
從計(jì)算結(jié)果可以看出,左移 n 位相當(dāng)于將這個(gè)數(shù)乘以 2 的 n 次方。
右移(<<)
右移運(yùn)算符是“<<”,它是雙目運(yùn)算符,它可以將運(yùn)算符左邊的操作數(shù)向右移動(dòng)指定的位數(shù),移動(dòng)的位數(shù)由運(yùn)算符右邊的操作數(shù)給出,移動(dòng)方向?yàn)閺挠业阶?,移?dòng)到右邊界之外的多余二進(jìn)制位會(huì)被丟棄,并從左邊移入0(無符號整數(shù)),對于有符號數(shù)整數(shù),需要注意符號位的處理,如果移位的操作數(shù)是正數(shù),右移時(shí)會(huì)在左邊填充 0,如果是負(fù)數(shù),右移時(shí)會(huì)在左邊填充 1。
例如:8 >> 2 的結(jié)果是2。
從計(jì)算結(jié)果可以看出,右移 n 位相當(dāng)于將這個(gè)數(shù)除以 2 的 n 次方。
位運(yùn)算可以應(yīng)用到位掩碼技術(shù),位掩碼用于操作和檢測一組二進(jìn)制數(shù)據(jù)中的特定二進(jìn)制位,通過掩碼,我們可以方便地設(shè)置、清除或者翻轉(zhuǎn)一組二進(jìn)制數(shù)據(jù)中的特定二進(jìn)制位。例如,我們可以定義一個(gè)掩碼來提取一個(gè)字節(jié)的低4位。
#include
void printf_binary(unsigned char n);
void main()
{
unsigned char AH = 0xab;
unsigned char mask = 0x0f;
printf_binary(AH);
printf_binary(AH&mask);
}
void printf_binary(unsigned char n)
{
char i=0;
for(i=0; i< 8; i++ )
{
if(n&(0x80 > >i)){
printf("1");
}else
{
printf("0");
}
}
printf("n");
}
在上面的程序代碼中,定義了printf_binary()函數(shù),該函數(shù)將傳入的參數(shù)n轉(zhuǎn)換為二進(jìn)制數(shù)并輸出,函數(shù)內(nèi)用到了循環(huán)語句,它可以重復(fù)執(zhí)行相同的代碼段,循環(huán)語句的語法后面還會(huì)講述。
變量mask是我們定義的掩碼 ,變量的值為0x0f,它的二進(jìn)制表示為 00001111,mask與變量AH進(jìn)行位與運(yùn)算,運(yùn)算的結(jié)果為變量AH的低4位。程序的輸出結(jié)果見下圖。
位運(yùn)算一般在嵌入式開發(fā)中應(yīng)用,用于配置單片機(jī)的寄存器,也會(huì)使用到一些高效的程序算法中。
7、運(yùn)算符的優(yōu)先級
C表達(dá)式可能存在多個(gè)運(yùn)算符,運(yùn)算符之間存在優(yōu)先級的關(guān)系,級別高的運(yùn)算符先執(zhí)行運(yùn)算,級別低的運(yùn)算符后執(zhí)行運(yùn)算算,下表列出了運(yùn)算符的優(yōu)先級。表中優(yōu)先級欄,數(shù)字越小優(yōu)先級越高,運(yùn)算符每個(gè)運(yùn)算符用中文頓號分割。
表中小括號‘()’優(yōu)先級最高,表達(dá)式含有小括號的,優(yōu)先執(zhí)行小括號的內(nèi)容,如果包含多個(gè)小括號,執(zhí)行順序是從左到右。
在C語言中,運(yùn)算符的優(yōu)先級決定了表達(dá)式中運(yùn)算執(zhí)行的順序。高優(yōu)先級的運(yùn)算符將在低優(yōu)先級的運(yùn)算符之前被執(zhí)行。例如,乘法和除法運(yùn)算符的優(yōu)先級高于加法和減法運(yùn)算符。
以下是如何判斷C語言運(yùn)算符優(yōu)先級的步驟:
(1)了解C語言中的運(yùn)算符類型。C語言中有多種運(yùn)算符,包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符等。每種運(yùn)算符都有不同的優(yōu)先級。
(2)確定運(yùn)算符的優(yōu)先級。C語言中,運(yùn)算符的優(yōu)先級由高到低分為七個(gè)級別,下面列出了這些級別,以及相應(yīng)的運(yùn)算符:
- 后綴運(yùn)算符:++、--
- 一元運(yùn)算符:++、--、+、-、~、!
- 乘法 / 除法 / 取余:*、/%、
- 加法 / 減法:+、-
- 移位運(yùn)算符:<<、>>
- 關(guān)系運(yùn)算符:<、>、<=、>=
- 等于不等于:==、!=
- 位與運(yùn)算符:&
- 位異或運(yùn)算符:^
- 位或運(yùn)算符:|
- 邏輯與運(yùn)算符:&&
- 邏輯或運(yùn)算符:||
- 條件運(yùn)算符:? :
- 賦值運(yùn)算符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=
(3)根據(jù)優(yōu)先級確定表達(dá)式的執(zhí)行順序。在復(fù)雜的表達(dá)式中,根據(jù)優(yōu)先級確定運(yùn)算執(zhí)行的順序非常重要。例如,在表達(dá)式a = b + c * d
中,乘法運(yùn)算將在加法運(yùn)算之前執(zhí)行,因?yàn)槌朔ǖ膬?yōu)先級高于加法。
以下是一段根據(jù)C語言自增、自減、關(guān)系運(yùn)算符、算術(shù)運(yùn)算符優(yōu)先級的示例代碼,代碼中包含了對這些運(yùn)算符的用法的注釋,并附帶了示例和預(yù)期的輸出結(jié)果。
#include
int main() {
int a = 5; // 初始化變量a為5
int b = 3; // 初始化變量b為3
// 算術(shù)運(yùn)算符優(yōu)先級: 加法 > 減法 > 乘法 > 除法 > 取余
// 關(guān)系運(yùn)算符優(yōu)先級: < > <= >= == !=
// 自增自減運(yùn)算符優(yōu)先級: ++ --
// 算術(shù)運(yùn)算符示例
printf("a + b = %dn", a + b); // 輸出: a + b = 8
printf("a - b = %dn", a - b); // 輸出: a - b = 2
printf("a * b = %dn", a * b); // 輸出: a * b = 15
printf("a / b = %dn", a / b); // 輸出: a / b = 1
printf("a % b = %dn", a % b); // 輸出: a % b = 2
// 關(guān)系運(yùn)算符示例
printf("a > b? %sn", a > b ? "Yes" : "No"); // 輸出: a > b? No
printf("a < b? %sn", a < b ? "Yes" : "No"); // 輸出: a < b? Yes
printf("a >= b? %sn", a >= b ? "Yes" : "No"); // 輸出: a >= b? Yes
printf("a <= b? %sn", a <= b ? "Yes" : "No"); // 輸出: a <= b? No
printf("a == b? %sn", a == b ? "Yes" : "No"); // 輸出: a == b? No
printf("a != b? %sn", a != b ? "Yes" : "No"); // 輸出: a != b? Yes
// 自增自減運(yùn)算符示例
printf("a++ + b = %dn", a++ + b); // 輸出: a++ + b = 8 (這里,a先自增,然后和b相加,所以原來的a=5+1=6)
printf("a + b = %dn", a + b); // 輸出: a + b = 8 (這里,a先和b相加,然后自增,所以原來的b=3)
printf("a-- + b = %dn", a-- + b); // 輸出: a-- + b = 11 (這里,a先自減,然后和b相加,所以原來的a=6--)
printf("a + b = %dn", a + b); // 輸出: a + b = 14 (這里,a先和b相加,然后自減,所以原來的b=3)
return 0;
}
上述代碼展示了C語言中的算術(shù)運(yùn)算符、關(guān)系運(yùn)算符以及自增自減運(yùn)算符的優(yōu)先級和用法,每行代碼前添加了詳細(xì)的注釋,運(yùn)行這段代碼應(yīng)該沒有錯(cuò)誤,并會(huì)按照預(yù)期的方式輸出結(jié)果。
評論