c语言之优先级 结合性与自增运算,C语言之优先级、结合性与自增运算
優(yōu)先級(jí)、結(jié)合性這些概念在初學(xué)的時(shí)候并沒(méi)有放在心上,今天又碰到這個(gè)問(wèn)題,查了不少資料,再次做個(gè)總結(jié)。
在標(biāo)準(zhǔn)C語(yǔ)言的文檔里,對(duì)操作符的結(jié)合性并沒(méi)有做出非常清楚的解釋。一個(gè)滿分的回答是:它是仲裁者,在幾個(gè)操作符具有相同的優(yōu)先級(jí)時(shí)決定先執(zhí)行哪一個(gè)。
每個(gè)操作符擁有某一級(jí)別的優(yōu)先級(jí),同時(shí)也擁有左結(jié)合性或右結(jié)合性。優(yōu)先級(jí)決定一個(gè)不含括號(hào)的表達(dá)式中操作數(shù)之間的“緊密”程度。例如,在表達(dá)式a*b+c中,乘法運(yùn)算的優(yōu)先級(jí)高于加法運(yùn)算符的優(yōu)先級(jí),所以先執(zhí)行乘法a*b,而不是加法b+c。
但是,許多操作符的優(yōu)先級(jí)都是相同的。這時(shí),操作符的結(jié)合性就開(kāi)始發(fā)揮作用了。在表達(dá)式中如果有幾個(gè)優(yōu)先級(jí)相同的操作符,結(jié)合性就起仲裁的作用,由它決定哪個(gè)操作符先執(zhí)行。像下面這個(gè)表達(dá)式:
int a,b=1,c=2;
a=b=c;
我們發(fā)現(xiàn),這個(gè)表達(dá)式只有賦值符,這樣優(yōu)先級(jí)就無(wú)法幫助我們決定哪個(gè)操作先執(zhí)行,是先執(zhí)行b=c呢?還是先執(zhí)行a=b。如果按前者,a=結(jié)果為2,如果按后者,a的結(jié)果為1。
所有的賦值符(包括復(fù)合賦值)都具有右結(jié)合性,就是在表達(dá)式中最右邊的操作最先執(zhí)行,然后從右到左依次執(zhí)行。這樣,c先賦值給b,然后b在賦值給a,最終a的值是2。類似地,具有左結(jié)合性的操作符(如位操作符“&”和“|”)則是從左至右依次執(zhí)行。
結(jié)合性只用于表達(dá)式中出現(xiàn)兩個(gè)以上相同優(yōu)先級(jí)的操作符的情況,用于消除歧義。事實(shí)上你會(huì)注意到所有優(yōu)先級(jí)相同的操作符,它們的結(jié)合性也相同。這是必須如此的,否則結(jié)合性依然無(wú)法消除歧義,如果在計(jì)算表達(dá)式的值時(shí)需要考慮結(jié)合性,那么最好把這個(gè)表達(dá)式一分為二或者使用括號(hào)。
例:
a=b+c+d
=是右結(jié)合的,所以先計(jì)算(b+c+d),然后再賦值給a
+是左結(jié)合的,所以先計(jì)算(b+c),然后再計(jì)算(b+c)+d
C語(yǔ)言中具有右結(jié)合性的運(yùn)算符包括所有單目運(yùn)算符以及賦值運(yùn)算符(=)和條件運(yùn)算符。其它都是左結(jié)合性。
在C語(yǔ)言中有少數(shù)運(yùn)算符在C語(yǔ)言標(biāo)準(zhǔn)中是有規(guī)定表達(dá)式求值的順序的:
1:&& 和 || 規(guī)定從左到右求值,并且在能確定整個(gè)表達(dá)式的值的時(shí)候就會(huì)停止,也就是常說(shuō)的短路。
2:條件表達(dá)式的求值順序是這樣規(guī)定的:
test ? exp1:exp2;
條件測(cè)試部分test非零,表達(dá)式exp1被求值,否則表達(dá)式exp2被求值,并且保證exp1和exp2兩者之中只有一個(gè)被求值。
3:逗號(hào)運(yùn)算符的求值順序是從左到右順序求值,并且整個(gè)表達(dá)式的值等于最后一個(gè)表達(dá)式的值,注意逗號(hào)','還可以作為函數(shù)參數(shù)的分隔符,變量定義的分隔符等,這時(shí)候表達(dá)式的求值順序是沒(méi)有規(guī)定的!
判斷表達(dá)式計(jì)算順序時(shí),先按優(yōu)先級(jí)高的先計(jì)算,優(yōu)先級(jí)低的后計(jì)算,當(dāng)優(yōu)先級(jí)相同時(shí)再按結(jié)合性,或從左至右順序計(jì)算,或從右至左順序計(jì)算。
說(shuō)完了優(yōu)先級(jí)和結(jié)合性,下面說(shuō)說(shuō)自增運(yùn)算符++
首先明白自增運(yùn)算符的兩種使用情況:
(1)、單獨(dú)使用:i++;或者++1;這種情況下兩者是沒(méi)有區(qū)別的,i的值都會(huì)增加1;
(2)、在表達(dá)式中使用:a = i++;此時(shí)先取i的值賦給a,然后i的值自增,相當(dāng)于a = i;i=i+1
a = ++i;此時(shí)先讓i自增,然后將自增后的值賦給a,相當(dāng)于i = i + 1;a = i
明白了自增的這兩種情況,然后再來(lái)看看自增和結(jié)合性的混合情況:*p++ (*p)++ *(p++)三者的區(qū)別
對(duì)于*p++,首先*和++的優(yōu)先級(jí)相同,然后看他們的結(jié)合性;由于優(yōu)先級(jí)相同,那么他們的結(jié)合性必然也相同,都是右結(jié)合(從右至左)。
那么*p++ 就相當(dāng)于*(p++),即根據(jù)右結(jié)合,p與++先結(jié)合形成(p++),然后再與*結(jié)合。
需要注意的一點(diǎn)(本文想著重說(shuō)明的一點(diǎn)):雖然*(p++)中,p++被放在了括號(hào)內(nèi),此時(shí)應(yīng)根據(jù)自增運(yùn)算符++的兩種情況來(lái)考慮(而不需要考慮結(jié)合性了,此時(shí)與結(jié)合性已經(jīng)無(wú)關(guān)),顯然這是上述的第二種情況,即在表達(dá)式中使用自增。所以是先取p的值與*結(jié)合,然后p值再自增,相當(dāng)于*p,p++;千萬(wàn)不要被括號(hào)迷惑,認(rèn)為括號(hào)中的東西先運(yùn)算。
明白了上面一點(diǎn),則對(duì)于*(++p)就很好理解,p先自增,然后與*結(jié)合。
對(duì)于下面的例子也不難理解:
例一:char q[5] = "am";char *p = q;
那么,
(*p)++后,p就變成了"bm";因?yàn)槭沁M(jìn)行對(duì)其首元素進(jìn)行加1運(yùn)算
*(p++)后,p就變成了"m",因?yàn)橥瓿扇≈颠\(yùn)算后,p++指向下一個(gè)元素,即m,
*p++與*(p++)一樣。
如果只是征對(duì)這3個(gè)語(yǔ)句賦值給其他變量的話,3個(gè)的結(jié)果都是a,在這里。
char o = (*p)++;
char m = *(p++);
char n = *p++;
都是a。
例二:
int i = 0,a,b;
a = (i++)+(i++)+(i++);
b = (++i)+(++i)+(++i);
cout<
輸出結(jié)果(gcc編譯器):0 16 6
解釋:這里特別注明是gcc編譯器,在其他編譯器下的值可能不同。
對(duì)于int a=(i++)+(i++)+(i++);先取出i值進(jìn)行加運(yùn)算,然后再執(zhí)行i的三次自增;?在其他編譯器下(如tc3.0),可能是0+1+2=3;
對(duì)于int b=(++i)+(++i)+(++i);每次i先自增,然后參與運(yùn)算,所以是4+5+6=16.
總結(jié)
以上是生活随笔為你收集整理的c语言之优先级 结合性与自增运算,C语言之优先级、结合性与自增运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 毅佰联合公会会员企业积极参与2023年中
- 下一篇: 2k显示器和1080p显示器(2k和10