[英]Ternary operator in loop conditional: evaluation order / op. precedence unclear
[英]Order of evaluation for conditional operator
眾所周知,賦值=
和條件?:
運算符都具有正確的關聯性。 在以下代碼示例中:
#include <stdio.h>
int main(void)
{
int a, b, c, d;
a = b = c = d = 1;
1 ? a++ : b ? c++ : d;
printf("%d %d %d %d\n", a, b, c, d);
return 0;
}
分配:
a = b = c = d = 1;
等效於:
a = (b = (c = (d = 1)));
並相應地:
1 ? a++ : b ? c++ : d;
是相同的:
1 ? a++ : (b ? c++ : d);
標准對這最后一種情況怎么說? 它是否保證從左到右評估這樣的組合表達式(因此不評估c++
部分),與賦值相反?
保證?:
的求值順序:首先對第一個操作數求值,然后根據第一個操作數為true求值第二個或第三個操作數。
您主要對運算符優先級/關聯性和評估順序之間的關系感到困惑。 他們扮演着不同的角色。 前者決定如何對運算符進行分組,而后者則決定首先評估哪個子表達式。
考慮表達式a * b + c * d
,優先級規則意味着它等效於(a * b) + (c * d)
。 但是是否可以保證編譯器在c * d
之前對a * b
進行求值? 答案是否定的,在此示例中,運算符+
不保證評估順序。
條件運算符?:
是為數不多的具有指定評估順序的運算符之一。 (其余的&&
, ||
,和,
)。
在你的例子中
1 ? a++ : b ? c++ : d;
1 ? a++ : (b ? c++ : d);
總是等效,在兩個表達式, 1
首先計算,並且因為它是真實的, a++
接下來評價結束。
關聯性和優先級未定義評估順序 。 這些概念是完全無關的。 C語言中的求值順序由排序規則定義,而不是由優先級或關聯性定義。
確實, a = b = c = d = 1;
關聯為a = (b = (c = (d = 1)));
,但這並不意味着應該首先評估d = 1
,尤其是在C語言中,賦值運算符的結果為rvalue。
關聯性只是說c
應該收到轉換為d
類型的值1
(“好像”是從d
讀取的)。 但這並不意味着d = 1
應該首先完成。 在您的示例中,所有變量都具有相同的類型,這意味着整個對象等於a = 1; b = 1; c = 1; d = 1;
a = 1; b = 1; c = 1; d = 1;
以任何順序排列。 a = b = c = d = 1
表達式內部沒有排序。
相同的邏輯適用於?:
運算符。 它的關聯性只是告訴您哪個操作數屬於哪個運算符。 分組的確是1 ? a++ : (b ? c++ : d);
1 ? a++ : (b ? c++ : d);
。 但是關聯性不會告訴您有關評估順序的任何信息。 ?:
運算符中的評估順序是分別和獨立定義的:始終首先評估(排序)條件,然后評估一個(只有一個)分支。 在您的示例1
中,首先對a++
求值,然后對a++
求值,其結果成為整個表達式的結果。 (b ? c++ : d)
部分甚至沒有被觸及。
1 ? a++ : b ? c++ : d;
相當於
if (1) {
a++;
}
else {
if (b) {
c++;
}
else {
d;
}
}
因此,輸出將是
2 1 1 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.