2010-10-20 58 views
0

可能重複:
In what order does evaluation of post-increment operator happen?以L值使用後綴增量

考慮下面的代碼片斷(在C):


uint8_t index = 10; 
uint8_t arr[20]; 

arr[index++] = index; 

當我編譯此同gcc,它將arr [10]設置爲10,這意味着後綴增量在整個賦值表達式之後纔會被應用錫永。我發現這有點令人驚訝,因爲我期待增量返回原始值(10),然後遞增到11,從而將arr [10]設置爲11.

我見過很多關於增量運算符的其他文章在RValues中,但不在LValue表達式中。

謝謝。

+1

但是,這些其他帖子應該指出你在C中使用的概念來規範這些表達式的有效性,即序列點,否?閱讀完所有這些內容後,您應該能夠發出合格的猜測。 – 2010-10-20 14:06:09

+0

-1爲當天無用的後續問題。看到上面的兩個評論爲我的理由。 – 2010-10-20 14:45:44

回答

4

一些standard語言:

6.5表達式

1表達式是運營商和操作數的序列,可指定一個 值的計算,或者,指定的對象或功能,或產生副作用,或者執行其組合。

2在上一個和下一個序列點之間,對象的存儲值 最多隻能通過評估表達式進行修改。 72)此外,先驗值只能讀取以確定要存儲的值。 73)

3運算符和操作數的分組由語法指示。 74)除以後指定(對於函數調用 ()&&||和逗號運營商),子表達式的評估順序和順序側效果發生都沒有說明。

第2段明確呈現表達式a[i++] = i undefined;之前的值i不只是讀取以確定i++的結果。因此,任何結果都是允許的。

除此之外,您不能依賴++運算符的副作用在評估表達式後立即應用。對於像

a[i++] = j++ * ++k 

的唯一保證一個表達式是,表達j++ * ++k結果被分配給結果表達a[i++];但是,每個子表達式a[i++]j++,和++k可以是以任何順序進行評價,和副作用(分配給a[i],更新i,更新j和更新k)可以以任何順序來施加。

+0

感謝您的詳細解答! – ssfrr 2010-10-20 15:10:50

+0

在這裏,你說我可以按任何順序評估i ++,j ++和++ k。但是'*'的關聯性是否使得++ ++之前需要評估j ++? – 2012-12-30 14:39:24

+1

優先級和關聯性只能保證*表達式被解析*。對於像'a + b * c'這樣的表達式來說,所有的保證就是把'b * c'的*結果*加到'a'的結果上。無法保證評估各個子表達式「a」,「b」和「c」的順序。 – 2012-12-31 11:29:59

1

arr[index++] = index; 

導致未定義的行爲。閱讀C標準瞭解更多詳情。

您應該知道的本質是:您不應該在同一個語句中讀取和更改變量。

+1

爲什麼選擇C++標準? – 2010-10-20 14:01:36

+2

你的文本里有兩個'+'太多了;-) – 2010-10-20 14:02:19

+0

這個問題是關於C的,具體的。 C標準也可能沒有定義行爲,但我不確定在哪裏尋找。 – ssfrr 2010-10-20 14:04:05

1

賦值操作從右向左工作,即首先計算的表達式的右部分,然後將其分配給左部分。

+0

首先,該操作根據第6.5節第2段未定義,因此*任何*結果都是允許的。其次,根據第6.5節第3段,任何兩個序列點之間評估表達式的順序(以及所應用的副作用)均爲*未指定*;除了某些運算符(函數調用'()','&&','||','?:'和逗號運算符,這些運算符都保證從左到右的評估),您無法保證特定的評估順序。 – 2010-10-20 14:39:09