接下來,通過示例徹底理解自增運(yùn)算符的兩種用法(自減的用法與之類似,只不過是加1變成了減1)。
1、++i和i++的區(qū)別
如清單1(注意代碼中的注釋):
例子輸出結(jié)果:
在例子中,第7和第8行的作用一樣,僅僅是為變量i加1,這時(shí)i的值已經(jīng)增加為9,接下來第10行變量a先獲得i的值(即9),然后i加1,第11行變量i先再加1,然后把得到的值賦給b,所以b的值為11。
稍微復(fù)雜的例子,如清單2:
例子輸出結(jié)果:
在這個(gè)例子中,只不過是通過*p來間接地操作a,其他關(guān)于自增運(yùn)算符的用法與清單1類似。第9行的*p一定要用小括號(hào)括起來,否則含義就不一樣了。而第11行的++(*p)也可以寫成++*p(用GCC驗(yàn)證過),那是因?yàn)閷?duì)操作數(shù)p來說它只有一個(gè)運(yùn)算符*在計(jì)算它,所以無關(guān)乎運(yùn)算符優(yōu)先級(jí)和結(jié)合性的問題。
值得注意的是,由于C語(yǔ)言沒有指定函數(shù)各參數(shù)的求值順序,所以第15行的代碼是不可移植的,用不同的編譯器可能會(huì)產(chǎn)生不同的結(jié)果(對(duì)于這個(gè)例子,GCC是先計(jì)算++(*p),后計(jì)算(*p)++,所以兩者都等于8)。
知識(shí)點(diǎn):
(1)、副作用
在對(duì)表達(dá)式求值的同時(shí),修改了某些變量的值,其中修改值的行為在C語(yǔ)言中被叫作副作用,那是因?yàn)閷?duì)C語(yǔ)言而言,計(jì)算的目的就是對(duì)表達(dá)式求值,如語(yǔ)句int a = 5,它的含義是先求值得到5,然后把5賦值給變量a,后一步的賦值就是此表達(dá)式的副作用。自增和自減運(yùn)算符就是因?yàn)楦弊饔枚皇褂?,除了?或減1之外,還給自身賦值。
(2)、運(yùn)算符的優(yōu)先級(jí)
在C語(yǔ)言中,把運(yùn)算符的優(yōu)先級(jí)分為15級(jí),如下表,從上到下,依次為從最高優(yōu)先級(jí)到最低優(yōu)先級(jí)(為了方便記憶,將15級(jí)分成11類,并對(duì)每類進(jìn)行了命名)。
初等運(yùn)算符 |
包括小括號(hào) ()、中括號(hào) [] 、成員訪問運(yùn)算符 . 和 -> 。 |
一元運(yùn)算符 |
包括自增++和自減--、正負(fù)號(hào)+ 和-、間接運(yùn)算*和取址運(yùn)算& 、類型轉(zhuǎn)換(type)、 sizeof 、邏輯反! 、位取反~等。 |
算術(shù)運(yùn)算符 |
包括兩級(jí),先乘除(*、/、%)后加減(+、-)。 |
位移運(yùn)算符 |
包括左移 << 和右移 >> 。 |
關(guān)系運(yùn)算符 |
包括小于 < 、小于等于 <= 、大于 > 、大于等于 >= 。 |
判等運(yùn)算符 |
包括相等 == 和不相等 != 。 |
位邏輯運(yùn)算符 |
分三級(jí),依次為位與 &、位異或 ^ 和位或 | 。 |
邏輯運(yùn)算符 |
分兩級(jí),依次為邏輯與 && 和邏輯或 || 。 |
條件運(yùn)算符 |
? : |
賦值運(yùn)算符 |
包括= 、+= 、-=、 *=、 /=、 %= 、&= 、^=、 |= 、<<= 、>>= 。 |
逗號(hào)運(yùn)算符 |
, |
(3)、結(jié)合性
對(duì)于同一操作數(shù),在具有兩個(gè)相同優(yōu)先級(jí)的操作符時(shí)決定先執(zhí)行哪個(gè)操作符的問題就是由結(jié)合性決定的。
相同優(yōu)先級(jí)的操作符具有同樣的結(jié)合性。右結(jié)合性就是說表達(dá)式中最右邊的操作最先執(zhí)行,然后從右到左依次執(zhí)行。在C語(yǔ)言中,具有右結(jié)合性的操作符只有相應(yīng)的三類,分別為一元運(yùn)算符、條件運(yùn)算符和賦值運(yùn)算符。
注意:C語(yǔ)言中的優(yōu)先級(jí)和結(jié)合性都是針對(duì)同一操作數(shù)而言的。如表達(dá)式24/8*2,對(duì)于操作數(shù)8而言,/ 和*的優(yōu)先級(jí)相同,所以再根據(jù)它們的左結(jié)合性可知,表達(dá)式是先計(jì)算24/8得到3,然后計(jì)算3*2得到6。
C語(yǔ)言并沒有規(guī)定同一運(yùn)算符相關(guān)的多個(gè)操作數(shù)的計(jì)算順序(&&、|| 、? : 和 , 運(yùn)算符除外),如式子a = 8 * 9 + 20 * 4,對(duì)操作數(shù)9和20而言,根據(jù)優(yōu)先級(jí)就可判斷先乘后加,但表達(dá)式中的兩個(gè)*并不共享同一操作數(shù),所以從左到右的結(jié)合性并不適用它,8 * 9 和20 * 4的計(jì)算順序是不定的,到底先計(jì)算8 * 9還是20 * 4由編譯器決定。
在上面例子中,8 * 9和20 * 4誰(shuí)先執(zhí)行都不影響最后結(jié)果的一致,但有些情況下就未必了,如“ b = 3; a = (b++) * (b++); ”這樣的例子,對(duì)于不同的編譯器最后a的值可能等于9,也可能等于12,甚至可能等于16。因此,在實(shí)際應(yīng)用中不能出現(xiàn)這樣的未確定性,根據(jù)自己的需要,可以把它改成類似“b = 3; c = b++; a = c * c;”這樣的形式。
2、*p++和*++p的區(qū)別
舉例,如清單3: