[英]Why is “if (i++ && (i == 1))” false where i is an int holding the value 1?
{
int i = 1;
if (i++ && (i == 1))
printf("Yes\n");
else
printf("No\n");
}
根據我的理解,在if
條件中,首先計算表達式( i==1
),它應該返回1
,然后它在邏輯上用1
,這是i
的值,所以表達式應該返回1 && 1 == 1
,但執行了else
部分。
有人可以解釋為什么else
部分被執行?
在C中,在&&
運算符的LHS評估與RHS評估之間存在一個序列點 ,必須在評估RHS之前完成增量並完成。 因此, i++
(相當於i++ != 0
)被執行並且增量完成(並且表達式的計算結果為true),所以在評估RHS時, i == 2
因此整體表達式為false而你得到'不'打印。 如果&&
運算符的LHS評估為false(0),則由於&&
運算符的“短路”屬性,不會對RHS進行求值。
只有少數運算符具有在LHS和RHS的評估之間具有序列點的屬性: &&
, ||
和,
(作為一個經營者,而不是作為一個參數列表分隔符) -這里面的? :
? :
也是,這不是一個二元運算符,但是在評估條件之后和之后的表達式之前有一個序列點?
或者評估:
之后的表達式(總是評估其中一個或另一個,但不是兩者)。
&&
和||
運營商是唯一具有“短路”特性的運營商。 僅當LHS評估為真時才評估&&
的RHS; ||
的RHS 僅在LHS評估為false時進行評估。
Iwillnotexist Idonotexist正確斷言 :
C11標准沒有取消序列點,只有C ++ 11標准。
C ++ 11(ISO / IEC 14882:2011)說:
1.9程序執行
¶13 之前排序的是由單個線程(1.10)執行的評估之間的非對稱,傳遞,成對關系,這導致這些評估之間的部分順序。 給定任何兩個評估A和B ,如果A在B之前被排序,那么A的執行應該在B的執行之前。 如果A不B之前測序,B不是A之前測序,則A和B是未測序 。 [ 注意:未經測試的評估的執行可能會重疊。 - 注完 ]評價A和B當任一A被B之前測序或A之前B被測序的測序不定 ,但它是未指定的哪個。 [ 注意:不確定順序的評估不能重疊,但可以先執行。 - 結束說明 ]
術語“序列點”根本不出現在C ++ 11中(唯一的近似匹配是'序列指針')。
C11(ISO / IEC 9899:2011)說:
5.1.2.3程序執行
¶3 之前排序的是由單個線程執行的評估之間的非對稱,傳遞,成對關系,這導致這些評估之間的部分順序。 給定任何兩個評估A和B ,如果A在B之前被排序,那么A的執行應該在B的執行之前。 如果A不是之前或B之后測序(相反地,如果A是B之前測序,則B為A 之后進行測序 。),則A和B是未測序 。 當A在B之前或之后進行測序時,評估A和B是不確定的 ,但是未指定哪一個。 13)表達式A和B的評價之間的序列點的存在意味着,與A相關聯的每一個值的計算和副作用與B相關聯的每一個值的計算和副作用之前測序。 (序列點的摘要見附件C.)
13)未經測試的評估的執行可以交錯。 不確定順序的評估不能交錯,但可以按任何順序執行。
因此,C11確實保留了序列點,但使用與C ++ 11基本相同的術語添加了“之前排序”和相關術語。
在這里,一個簡單的解釋
這就是為什么這種情況會變成'假'
當在表達式中使用&&
,保證從左到右計算其參數。 所以i
將具有的值2
時(i==1)
進行了評價。 因此,表達式為false, else
部分將被執行。
但是,請注意完整性,如果左參數的計算結果為false或0,則根本不評估右參數。
我認為1 && 1 = 1和1 && 0 = 0對您來說很清楚。 Michael L的回答對我來說似乎很好。但我仍然會嘗試詳細說明一下。 這是提供運營商優先級列表的鏈接:
http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
如果您訪問此鏈接並參考該表,那么您將會知道&&已經從左到右關聯。所以首先我將在左邊部分變為2(Sruit嘗試使用圖表顯示這個);然后對於右邊部分我== 1檢查已完成。我們可以通過編寫如下所示的代碼來檢查:
該代碼解釋了當執行流程達到i == 1 part時i = 2。
#include <stdio.h>
int main() {
int i = 1;
if (i++ && (printf("%d\n",i)))
printf("Yes\n");
else
printf("No\n");
return 0;
}
所以輸出是:
2
是
所以2 == 1出來是假的,最終答案給人驚喜! 右側支架給出0和左側1,因此1 && 0 = 0。 我認為這很公平,可以理解。
你很困惑,因為在循環語句中, i ++用於后增量。 例如
for (i=0;i<1;i++)
在上面的循環程序中, i
將首先獲得初始值並檢查條件。 if
條件為真,因此它遞增i並將i計算為循環體的舊值,但在循環體外它具有新值1 。
在你的問題你正在使用if
和老值范圍i
在遇到邏輯運算符將結束它會自動獲得新的價值和增量2這樣的條件返回false。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.