C語言中的序列點



TAG: C, 序列點 
DATE: 2013-08-07

序列點是程序執行序列中一些特殊的點。 當有序列點存在時,序列點前面的表達式必須求值完畢,並且副作用也已經發生, 才會計算序列點后面的表達式和其副作用。

什么是副作用?舉例子來說明。

int a = 5;
int b = a ++;

在給b賦值的語句中,表達式a++就有副作用,它返回a當前的值5后,要對a進行加1的操作。

哪些符號會生成序列點呢?

","會生成序列點。

","用於把多條語句拼接成一條語句。 例如:

int b = 5;
++ b;

可由","拼接成

int b = 5, ++b;

因為","會產生序列點,所以","左邊的表達式必須先求值,如果有副作用,副作用也會生效。然后才會繼續處理","右邊的表達式。

&&||會產生序列點

邏輯與 && 和邏輯或 || 會產生序列點。

因為&&支持短路操作,必須先將&&左邊的表達式計算完畢,如果結果為false,則不必再計算&&右邊的表達式,直接返回false

||&&類似。

?:中的"?"會產生序列點

三元操作符 ?:中的"?"會產生序列點。 如:

int a = 5;
int b = a++ > 5? 0 : a;

b的結果是什么?因為"?"處有序列點,其左邊的表達式必須先求值完畢。 a++ > 5在和5比較時,a並沒有自增,所以表達式求值為false。 因為"?"處的序列點,其左邊表達式的副作用也要立即生效,即a自增1,變為6。 因為"?"左邊的表達式求值為false,所以三元操作符?:返回:右邊的值a。 此時a的值是6,所以b的值是6。

序列點之間的執行順序

奇怪的C代碼中給出的例子。

int i = 3;
int ans = (++i)+(++i)+(++i);

(++i)+(++i)+(++i)之間並沒有序列點,它們的執行順序如何呢? gcc編譯后,先執行兩個++i,把它們相加后,再計算第三個++i, 再相加。而Microsoft VC++編譯后,先執行三個++i,再相加。 兩者得到的結果不同,誰對誰錯呢?

誰也沒有錯。C標准規定:兩個序列點之間的執行順序是任意的。 當然這個任意是在不違背操作符優先級和結合特性的前提下的。 這個規定的意義是為編譯器的優化留下空間。

知道這個規定,我們就應該避免在一行代碼中重復出現被遞增的同一個變量, 因為編譯器的行為不可預測。 試想如果(++i)+(++i)+(++i)換成(++a)+(++b)+(++c)(其中abc是不同的變量), 不管++a++b++c的求值順序誰先誰后,結果都會是一致的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM