2017-02-08 14 views
7

私はいくつかのコードを書いていましたが、システム全体を混乱させるプログラムのある部分で予期せぬ出力を得ていました。論理式Cの誤解

基本的な論理式に問題を抽出して簡略化することができました。さんが言ってみましょう:

int i = 1, j = 1, k = 0; 

printf("%d\n", ++i || ++j && k); 
printf("%d, %d, %d\n", i, j, k); 

return 0; 

このプログラムの出力は次のとおりです。

1

210

私はjの値が短いために2に増分されていなかったことを考えています||オペレータの回路特性。しかし、私は最初の"%d"の値が1である方法を混乱させる。 ステートメントが1を返すために、kの値は0でないべきですか?または、++i || ++j0でないため、このステートメントはまったく実行されないため、1を返しますか?

  • 私は&&論理、及びexpr1の & & expr2のあるexpr1と & & expr2のの値が両方非ゼロである場合、値1を有していることを知っています。

この説明の基本的な性質については、ご理解ください。

答えて

7

&&は、||よりも高い優先度を持ちます。まず、オペレータが6.5.14p4通り、truthyある場合 (https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B参照) よう

++i || ++j && k 

++i || (++j && k) 

|| shortcircuitsあります。

gccまたはclangにあり、コードを-Wallでコンパイルしている場合、コンパイラはそれらの括弧をそこに配置するように微調整します。そのアドバイスに耳を傾けることはおそらく良い考えです。何人かの人々が優先順位(私が聞く)によって混乱するようになります。

+0

残念ながら私はVS2015を使用しています。私はすぐに 'gcc'を使い始めるつもりです。私はあなたがそうするように勧めていると仮定していますか?私はいつもVSを学生のために推奨しているので使用しています...(または私は考えました) –

+2

@Rizzo gccは、開発者の利便性と生成されるコードのスピードの両方において、間違いなく素晴らしいコンパイラだと思います。 ;) – PSkocik

2

++i || ++j && kは、iが2(++ 1)、(++ j &、& k)が1と評価されるため、短絡が発生するため評価されません。 C標準(6.5.14論理OR演算子)から

3

3 ||オペランドのいずれかが と0と等しくない場合は1を返します。それ以外の場合は0が返されます。結果にはint型があります。

この式

++i || ++j && k 

++i || (++j && k) 

++iがゼロに等しくないので、式は整数値1を返し、標準からの引用によると同等です。サブ式(++j && k)は評価されません。

1

演算子の優先順位。 &&は、||よりも高い優先順位を持ちます。

あなたの式は同じです:++i || (++j && k)

++iがカッコはもはや評価されていない、TRUEです。