當前位置:學問君>學習教育>考研>

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

學問君 人氣:7.65K

序列點是一個時間點(在整個表達式全部計算完畢之後或在||、&&、? : 或逗號運算符處, 或在函數調用之前), 此刻塵埃落定, 所有的副作用都已確保結束。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。