2012-01-30 27 views
4

我到K & R讀取和i的行爲碰到這個例子有關的不確定性,而像a[i]=i++評估表達; 的C99規格書$ 6.5.2說序列點和評價的順序

一個和下一個順序點之間,對象所儲存的值由表達式求值修改最多一次。此外,先驗值只能讀取以確定要存儲的值。

上述來自K & R的例子在第一條語句中保持良好。請解釋第二次失敗的原因。

是否標準說約子表達式的評價中被捲入的序列點的情況下,爲了什麼。例如。 a[i++] || b[i++]。我知道這些評估是從左到右進行的,但是這怎麼能從上面的陳述中得出,或者是否在標準的某個地方明確地陳述過?

+0

[爲什麼賦值運算符不是序列點的任何好理由?](http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-序列點) – Suma 2012-01-30 08:35:47

+1

可能的重複的[未定義的行爲和序列點](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – Lundin 2012-01-30 13:25:50

+0

@Lundin:這是C++。 – 2012-01-30 13:30:55

回答

4

不標準說約子表達式的評價在序列點的情況下,爲了什麼?

在有條件的運營商&&以及||的情況下,評估的順序是明確的,這就是短路工作的真正原因。

它明確C99標準規定。

參考: C99標準

附件J:J.1未指定的行爲

1以下是未指定的:
.....

在順序哪些子表達式被評估,副作用的發生順序如何,除了函數調用(),01(01)&,||,?:和逗號 運營商(6.5)。
.....

而且在,
6.5.14邏輯或操作

4)不同的是按位|運算符||運營商保證從左到右的評估;在評估第一個操作數之後有一個序列點。如果第一個操作數不等於0,則不計算第二個操作數。

以及針對邏輯AND:

6.5。左到右13邏輯與運算

不同的是按位二進制&運算符,& &運營商保證評價; 如果評估第二個操作數,則在第一個和第二個操作數的評估之間有一個序列點。如果第一個操作數等於0,則不計算第二個操作數。

+1

謝謝,但你能否請你提供一些關於我問的第一個問題的解釋[i] = i ++ ; – Bazooka 2012-01-30 08:01:46

+0

@Parminder賦值運算符不是C中的一個序列點。注意:C++ 11引入了之前/之後的排序概念,並且[i] = i ++是[在C++ 11中很好定義的](http:// www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html)。另請參閱http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-sequence-point – Suma 2012-01-30 08:35:35

+0

真棒答案!這幫助了我'a || b ++ && c'知道是否總是評估「b ++」。它沒有,但是&& - 操作符的更高優先級將會引起很多人的爭論。 – 2012-07-16 09:13:14

0

對於問題的第一部分:

句子適用於對象由表達被改變,即i(和a[i])。因此,i的前值應專門用於確定i的「新」值。

但是表達式「使用」它也用於確定要寫入的數組元素。

背景是否定的,否則不清楚i表示i的值在增量之前或之後。

+0

謝謝,但我對此有另一個疑問。乍一看,像「++ i == i」這樣的表達式似乎是模棱兩可的。但它不是試圖「改變」除我之外的任何東西。那麼這個未定義的行爲呢? – Bazooka 2012-01-30 13:05:19

+0

我不想改變任何左值。我想說的是,在從右向左評估時,我只改變了'i'一次,而當我第二次訪問'i'時,我這樣做是爲了改變'我'本身的價值。這證實了我猜想的第二個陳述。所以有什麼問題 ?這是否是一個具有明確行爲的合法表達? – Bazooka 2012-01-30 13:22:25

+0

沒有重新分配發生,只有增量操作。這是'=='不''',以防萬一你錯過了。 – Bazooka 2012-01-30 13:33:40