以下のプログラムの出力がそうでないのはなぜ0
ですか20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
以下のプログラムの出力がそうでないのはなぜ0
ですか20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
はい、その概念はShort-Circuit (論理演算子式)&&
と呼ばれます。||
任意の論理式 ( , を含む) の場合、コンパイラは||
、&&
結果が評価されるとすぐに評価式を停止します (および実行を保存します)。
短絡の手法は次のとおりです。
!0 || any_expression
==1
なので、any_expression
評価する必要はありません。
そして、あなたの式i
では 0 ではなく 10 なので、if 条件は と(i || (j = i + 10))
同じように考えることができますi
。
論理 OR 演算子:
演算子 は||
左から右への評価を保証します。最初のオペランドの評価の後にシーケンス ポイントがあります。最初のオペランドが と比較unequal
される0
場合、2 番目のオペランドがnot
評価されます。
&& (および演算子):
0 && any_expression
==0
についても同様であるためany_expression
、評価する必要はありません。
あなたの表現では:
(i || (j = i + 10) )
------------
^
| Could evaluate if i is 0,
as i = 10 (!0 = true), so j remains unchanged as second operand is not evaluated
For or ||
operator answer can be either 0, 1. 実行を保存するために、結果が見つかるとすぐに評価が停止します。したがって、最初のオペランドがゼロ以外の場合、式の結果は1
(上記のように) になります。したがって、最初のオペランドi = 10
が 0 と等しくない場合、2 番目のオペランドは(j = i + 10)
評価されないため、コードの出力は.j
0
0
注: 短絡動作は C だけに存在するものではなく、概念は Java、C++、Python などの多くの言語に共通しています。(ただし、VB6 などのすべてではありません)。
C では、論理式の短絡が常に C の機能として保証されています。これは、Dennis Ritchie が C の最初のバージョンを設計および実装したときにも当てはまり、1989 年の C 標準でも当てはまり、C99 標準でも当てはまります。
関連記事: Is short-circuiting boolean operator is mandated in C/C++? そして評価順?
||
は短絡演算子です。左側が true と評価された場合、右側を評価する必要はありません。したがって、あなたの場合i
は true であるため、式j = i + 10
は評価されません。ただし、0に設定i
すると、右側が評価されます。
にはif (i || (j = i + 10))
、評価するブール式が 2 つあります。問題は、最初のものが真であるため、2 番目を計算する必要がないということです。それは純粋に無視されます。
なぜなら||
、短絡演算子だからです (演算子もそうです&&
)。
では(i || j = i+10)
、i
は 10 です。 の左側の部分||
は true です。j = i+10
その結果、式は発生しませんでしたj=0
。