[英]conditional operator usage
請考慮以下聲明。 b中存儲的值是多少?
int a=1;
int b = a+=1 ? a+=1 : 10;
我得到了答案4.有人可以解釋它是如何工作的。
它與優先權有關。 如果您檢查以下代碼(為簡單起見,最右邊a+=1
更改):
#include <iostream>
int main (void) {
int a=1;
int b = a+=1 ? 7 : 10;
std::cout << b << std::endl;
return 0;
}
你會看到輸出是8
,而不是7
或10
。
那是因為聲明:
int b = a+=1 ? 7 : 10;
被解釋為:
int b = (a += (1 ? 7 : 10));
現在,將其應用於您的案例,我們得到:
int b = (a += (1 ? a += 1 : 10));
並且,按執行順序:
a += 1
(因為1
為真)將a
設置為2
。 a += 2
( 2
是上一步的結果)將a
設置為4
。 b = 4
( 4
是上一步的結果)。 請記住,您不一定要依賴評估順序。 即使有一個序列點?
(以便在繼續之前完全評估1
),最右邊的a += ...
和最左邊的a += ...
之間沒有序列點。 並且在沒有插入序列點的情況下修改單個變量兩次是未定義的行為,這就是gcc -Wall
將為您提供非常有用的消息的原因:
warning: operation on ‘a’ may be undefined
它給你4
事實純屬巧合。 它可以很容易地給你3
, 65535
,甚至格式化你的硬盤給你一個教訓:-)
如其他答案中所述,由於C ++的語法規則決定了必須如何解析復合表達式,因此這兩個代碼片段是等效的。
int a=1;
int b = a+=1 ? a+=1 : 10;
和
int a=1;
int b = (a += (1 ? (a += 1) : 10));
雖然在條件表達式中存在序列點,但它在第一個表達式( 1
)的求值與第二個和第三個表達式中的任何一個的求值的評估之間(在這種情況下, a += 1
)。 在評估第二或第三表達式之后沒有明確的額外序列點。
這意味着a
在b
的初始值設定項中被修改兩次而沒有插入序列點,因此代碼具有未定義的行為 。
裝配分析:
int main()
{
int a=1;
int b = a+=1 ? a+=1 : 10;
return 0;
}
為上述代碼生成的匯編代碼(使用MinGW)如下所示。 當然,評論是我的! 閱讀評論也!
call ___main //entering into main()
movl $1, 12(%esp) //int a = 1; means 12(%esp) represents a;
incl 12(%esp) //a+=1 ; a becomes 2
movl 12(%esp), %eax //loading 'a' onto a register(eax); eax becomes 2
addl %eax, %eax //adding the register to itself; eax becomes 4
movl %eax, 12(%esp) //updating 'a' with the value of eax; 'a' becomes 4
movl 12(%esp), %eax //this step could be optimized away; anyway it loads value of 'a' onto the register(eax); eax becomes 4, in fact even earlier it was 4 too! needless step!
movl %eax, 8(%esp) //loading the value of eax at another memory location which is 8(%esp); this location represents b;
movl $0, %eax //making eax zero! the return value of main()!
leave //now main() says, please leave me!
12(%esp)
表示的存儲器位置a
,並且在從它的距離4字節,即, 8(%esp)
表示b
。 最后,這兩個內存位置的值都是4。
因此,b = 4.At = 4。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.