序列點是程式執行序列中一些特殊的點。 當有序列點存在時,序列點前面的表示式必須求值完畢,並且***也已經發生, 才會計算序列點後面的表示式和其***。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)
(其中a
、b
、c
是不同的變數), 不管++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 首先它是乙個函式,只不過這個函式的返回值是乙個位址值。函式返回值必須用同型別的指標變數來接受,也就是說,指標函式一定有函式返回值,而且,在主調...