簡體   English   中英

條件運算符的評估順序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM