當前位置:文思屋>學習教育>考研>

筆試例項:"序列點" 是什麼

文思屋 人氣:7.76K

序列點是一個時間點(在整個表示式全部計算完畢之後或在||、&&、? : 或逗號運算子處, 或在函式呼叫之前), 此刻塵埃落定, 所有的副作用都已確保結束。ANSI/ISO C 標準這樣描述:在上一個和下一個序列點之間, 一個物件所儲存的值至多隻能被表

筆試例項:"序列點" 是什麼

達式的計算修改一次。而且前一個值只能用於決定將要儲存的值。第二句話比較費解。它說在一個表示式中如果某個物件需要寫入, 則在同一表示式中對該物件的訪問應該只侷限於直接用於計算將要寫入的值。這條規則有效地限制了只有能確保在修改之前才訪問變數的表示式為合法。例如i = i+1 合法, 而a[i] = i++ 則非法

拓展:

int i = 3;

i = i++;

cout << i;

結果是什麼?有人可能會說是3,也有人可能會說是4,更多的人在罵出題的人白痴,但這語句究竟有何問題呢?未必每個人都清楚。

有些人也許馬上會說,這是“未定義行為”。沒錯,這是一個典型的未定義行為。i = i++這個表示式合乎C++語法,能夠順利編譯通過,但是執行的結果,標準說“未定義”。為什麼是“未定義”,深究起來,要從序列點說起。

序列點是程式中這樣的一些點:通俗地說,執行至此,之前的語句都已經徹底執行乾淨執行完了,之後的語句還完全沒開始執行;更常見、更嚴謹但略晦澀的說法是,之前的語句對現場環境的改變已經全部完成,之後的語句對現場環境的改變還沒有開始。啥是現場環境呢?就是程式執行到某一點的那個狀態,包括變數的內容、檔案的內容等。

這跟最開始那個例子有什麼關係呢?關鍵的問題來了:標準規定,兩個序列點之間,程式執行的順序可以是任意的。沒錯,正如你猜的那樣,C++標準規定一個完整的表示式結束之後有一個序列點,而例子中i = i++是位於兩個序列點之間的。編譯器可以先算完i++,再寫結果給i,也可以先將i = i,再令i++。按前面的方法算,i先自增變為4,然後i++返回3,於是i被賦值為3;按後一種方法算,i先被賦值為3,隨後自增變成4。標準說了,這兩種處理方法,編譯器你愛選那種就選哪種,隨便。如果誰寫的程式像這樣依賴執行的順序,讓他自己哭去!

等等,有人要問了,++的優先順序難倒不是高於=嗎?顯然應該先執行++啊。這裡有個概念的問題,前一段說的編譯器先算i = i,絕不是說令=的優先順序比++還高了。如果那樣的話,表示式將變成 (i = i)++,也就是ator = (i). operator ++,執行++的主體變成i = i這個表示式的返回值了。上一段所說的先計算i = i,實際上還是先計算i++,只不過是先返回了i的值,然後推遲了將i自增1的操作先去幹別的(i = i)去了,回頭再來給i自增1。