[英]C Increment operators
我已經在代碼塊中編譯了以下代碼,它顯示了輸出0 ... 0。 但是我認為它的輸出應該為0 ... 1,因為“ if”語句在此處不正確,因此不會執行“ if”之后的語句。然后j增加1(因為“ if”語句中的j ++),但是我仍然為0。因此,最后一個printf()應該為0 ... 1。
#include <stdio.h>
int main()
{
int i =0,j=0;
if(i && j++)
printf("%d..%d\n",i++,j);
printf("%d...%d",i,j);
return 0;
}
由於i
為0
(虛假),因此沒有理由執行j++
。 這就是所謂的短路。
在if(a < v.size() && v[a] == 5) // do something
類的檢查中很有用if(a < v.size() && v[a] == 5) // do something
參見C11 6.5.13邏輯AND運算符p4 (我強調)
與按位二進制&運算符不同,&&運算符保證從左到右的求值; 如果對第二個操作數求值,則在第一個和第二個操作數的求值之間會有一個序列點。 如果第一個操作數比較等於0,則不計算第二個操作數。
您的示例中的第一個操作數是i
。 它比較等於0,所以不評估(執行)第二個操作數( j++
)。 因此,您以后的printf
顯示j
仍為0是正確的。
條件( i
)的第一部分已經為false,因此第二部分( j++
)未執行。
如果沒有應用if條件,則遞增到j的原因是因為該表達式正在短路-即,i永遠不會為非零,因此不需要評估第二個表達式。
而不是使用邏輯與&&
,使用按位與&
,不會短路和工作,你想,只要路上i
和j
是0
或1
:
...
if(i & j++)
printf("%d..%d\n",i++,j);
或如果不是:
if (!!i & !!(j++))
...
由於第一個條件i
( &&
運算符的左側)的求值已經返回false,因此未執行j++
表達式,因此,第二個條件j++
不會求值。
這是編譯器進行的常見優化,通常稱為短路條件評估 ,在某些編譯器中,您可以關閉此優化,以避免這種副作用。
如您在此示例代碼中所看到的,從您的源中未執行第二個IF:
movl i(%rip), %eax
testl %eax, %eax ; <-- if i
je .L2
movl j(%rip), %eax
testl %eax, %eax ; <-- if j Not EXECUTED !!!
setne %dl
addl $1, %eax ; <-- j++
movl %eax, j(%rip)
testb %dl, %dl
je .L2
... ; inner IF
.j2
如其他答案所述。
如您所述,if語句為false則為true。 但是我相信所使用的概念/邏輯是不合適的,原因將隨之而來。
在此之前,讓我們了解&&(Logical AND)運算符的工作原理。 如果聲明與之關聯的兩個操作數均為true,則僅結果為true。 注意:1.對於編譯器,這意味着如果任何一個操作數為假,則編譯器將不會進一步計算,即跳至下一有效代碼行。 2. 0(零)狀態為false-在編程中。
好吧,編譯器首先搜索運算符,然后查找與其關聯的操作數。
因此,一旦編譯器遇到'&&',它就會從運算符的左側開始,因為&&(邏輯AND)的關聯性從左到右,並評估左側操作數的值為0(零)。 現在,請參閱注釋2,然后是1。
因此,編譯器跳到下一個有效的語句printf(“%d ...%d”,i,j);
此處,未對變量“ j”進行增量,因此“ j”的值將保持為0(零)。
注意:為了進一步弄清這個想法,我建議嘗試使用相同的示例使用不同的i和j值,例如i = 1和j = 1或i = 2和j = 1。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.