パソコン活用研究シリコンバレー(C、C++、の活用研究)

バグの温床(演算子の魔界)
(準備中)

演算子のページでC言語の場合
・代入 =
・比較演算 等号 ==
と書きましたが、ここがC言語の場合、注意しないとバグの温床になるポイントでもあります。


入力した値の2倍を答えさせるプログラムです。

#include 

int main(void) {
 int x,x2,y;
 printf("x?:");
 scanf("%d",&x);
 printf("Double of x?:");
 scanf ("%d",&y);
 x2=x*2;
 if (y == x2) {printf("Correct");}
  else {printf("Wrong. Correct answer is %d", x2);}
 return 0; }

値の代入では、x2=x*2 のように = を使います。
比較演算子としては (y == x2) のように == を使います。

実行画面


次にバグった例をあげます。

#include 

int main(void) {
 int x,y,z;
 y=0;z=0;
 printf("x?:");
 scanf("%d",&x);
 printf("y=x:");
 if (y=x) {printf("true\n");}
   else {printf("false\n");}
  printf("z==x:");
 if (z==x) {printf("true\n");}
   else {printf("false\n");} 
 return 0; }

y,zはy=0, z=0の値になっており、
このプログラムの意図としては、xに0を入力するといずれもtrueと表示させたい、というプログラムです。

zに関しては正しく動作しますが、yについてはバグります。
以下の実行例の通り、xに0を入力すると、false となり、1を入力するとtrueになります。

どこでミスっているかというと、
if (y=x) { ...
の行ですね。

本来は y==x とすべきところを y=x と書いています。
ここにy=xと書くと、
@xの値をyに代入する動作が行われ、
Aそのyの値によって if 文の判定が行われる
ということになります。

C言語の場合、
・if 文の比較演算の箇所で、こんな風に代入演算子が普通に動作してしまう点
・if 文の判定は( )の内の値の結果がint型の0ならfalse 0以外ならtrueとして判定する仕様
(C言語は比較演算子を使った場合、比較の結果、falseなら0、trueなら1を返すことになっている)
という仕様のため、うっかり y=x と書くとエラーも出さずに、意図しない動作(バグ)になってしまう
というわけです。

C言語の魔界仕様ですね。
他のプログラム言語では比較演算の等号に=を使う言語が多いので、その習慣でうっかりしてると
ミスりますね




TopPage