C語言中的序列點

2021-06-26 17:33:48 字數 1950 閱讀 1758

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的求值順序誰先誰後,結果都會是一致的。

C語言中memcpy用法的注意點

程式設計使用memcpy a,b,num 出現斷言,後研究發現memecpy 函式在使用時要求a,b引數不為null,後進行修改,問題解決。1.判斷輸入指標是否為null。長度可判可不判,因為長度如果 0,後面 也能處理 2.考慮記憶體是否重疊問題。記憶體是否重疊問題,即當dst是src的後半部分時...

C語言中巨集函式定義的注意點

要寫好c語言,漂亮的巨集定義是非常重要的。巨集定義可以幫助我們防止出錯,提高 的可移植性和可讀性等。定義巨集函式handle error value define handle error value if cudastatus value 最近使用到巨集函式定義遇到兩個坑,以後要注意。首先 當巨集...

c語言中的一些注意點

1.指標函式和函式指標的區別 1 指標函式是指帶指標的函式,即本質是乙個函式。函式返回型別是某一型別的指標 型別識別符號 函式名 參數列 int f x,y 首先它是乙個函式,只不過這個函式的返回值是乙個位址值。函式返回值必須用同型別的指標變數來接受,也就是說,指標函式一定有函式返回值,而且,在主調...