Code Fix

中級

ビット演算子 & の優先順位が比較演算子 == より低いことによる誤動作

a & b == cと書くと、==の方が優先順位が高いため、a & (b == c)として解釈されます。意図した(a & b) == cとは異なる結果になります。

なぜエラーが出ないのか

出力: no
(エラーなし)
Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: no
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int flags = 6;
 5      int mask = 2;
 6      if (flags & mask == mask  ) {
                       ^
 7          printf("yes\n");
 8      } else {
 9          printf("no\n");
10      }
11      return 0;
12  }
出力: no期待: yes

==は&よりも優先順位が高いため、flags & mask == maskはflags & (mask == mask)として解釈されます。ビット演算と比較を混ぜるときは括弧で明示的にグループ化する必要があります。

直し方: flags & mask == mask(flags & mask) == mask にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int bits = 12;
 5      int test = 4;
 6      if (bits & test == test  ) {
                      ^
 7          printf("yes\n");
 8      } else {
 9          printf("no\n");
10      }
11      return 0;
12  }
出力: no期待: yes

bits & test == testはbits & (test == test)、つまりbits & 1と解釈されます。12は偶数なので最下位ビットが0になり、常に0(偽)になってしまいます。

直し方: bits & test == test(bits & test) == test にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int level = 8;
 5      int flag = 8;
 6      if (level & flag == flag  ) {
                       ^
 7          printf("yes\n");
 8      } else {
 9          printf("no\n");
10      }
11      return 0;
12  }
出力: no期待: yes

levelとflagが等しくても、優先順位のせいでlevel & (flag == flag)、つまりlevel & 1が計算されてしまい、期待した比較にはなりません。

直し方: level & flag == flag(level & flag) == flag にします。

この問題を解いてみる →

よくある誤解

算数の感覚では&も==も同じくらいの優先度に見えますが、Cの演算子優先順位表では比較演算子(==, !=, <, >など)はビット演算子(&, |, ^)よりも優先順位が高く設定されています。ビット演算と比較を混ぜるときは、必ず括弧で明示的にグループ化する必要があります。

まとめ

ビット演算子 & の優先順位が比較演算子 == より低いことによる誤動作は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)