バグの温床(演算子の魔界)
(準備中)
演算子のページでC言語の場合
・代入 =
・比較演算 等号 ==
と書きましたが、ここがC言語の場合、注意しないとバグの温床になるポイントでもあります。
入力した値の2倍を答えさせるプログラムです。
#includeint 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) のように == を使います。
実行画面
次にバグった例をあげます。
#includeint 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言語の魔界仕様ですね。
他のプログラム言語では比較演算の等号に=を使う言語が多いので、その習慣でうっかりしてると
ミスりますね