はじめに
こんにちは
自分の経験に基づいて、C/C++で初心者がやりがちなプログラムのミスをまとてみました。
・コード例
・対処法
・解説
に分けて説明します。
基本的には、ビルド時にエラーとならないものが中心です。
暇な時に随時追加していくかもしれません。(今は4つだけ)
注意点
自分自身まだまだ初心者ですので、改善方法について、よりよい方法があるかもしれませんのでご注意お願いします。
本記事の開発環境はVisual Studio 2017となっています。
環境によっては、コンパイル時に警告となるものもあります。
一覧
1. if文で同じ値か判定する時のミス
・コード例
num1とnum2が同じ値か調べたい場合など、以下の様にしてしまうと、違う値ですが”同じ値”が出力されます。
#include <stdio.h>
int main(void)
{
int num1 = 1;
int num2 = 2;
if(num1 = num2)
{
printf("同じ値\n");
}
return 0;
}
・対処法
==にする。
if(num1 == num2)
・解説
if文は0か0でないかで判定されます。
num1 = num2 とした場合、num1の値(2)が最終的に評価されることになるので、結果は真となってしまします。
一度はミスした方も多いのではないでしょうか。
想定外の動作が発生した場合、最終的行き着くのはこのミスだった場合が多々あります。
2. if文で複数のORの条件を比較したい時のミス
・コード例
num変数が1か2か3であることを調べたい場合、以下の様にしてしまうと正しく評価されません。
#include <stdio.h>
int main(void)
{
int num = 0;
if(num == 1 || 2 || 3)
{
printf("1か2か3");
}
return 0;
}
・対処法
以下の様にする
if(num == 1 || num == 2 || num == 3)
もしくは、コードを大幅に変更しないと駄目な可能性はあるが、ロジックを見直す。
比較対象が大量にある場合は、以下のような形が効果的。
#include <stdio.h>
int main(void)
{
int num = 0;
int comp[] = { 1,2,3 };
bool result = false;
for(int i = 0; i < (int)(sizeof(comp) / sizeof(comp[0])); i++)
{
if(num == comp[i])
{
result = true;
break;
}
}
if(result)
{
printf("true");
}
return 0;
}
・解説
==の方が比較の優先順位が高いため、if(num == 1 || 2 || 3)の場合は、if((num == 1) || 2 || 3)
となります。さらに置き換えると if( 偽 || 真 || 真 )になってしまうので、この結果は真になります。
「num変数が、1か2か3」の日本語をそのままプログラムにすると、上記の様な形となるので、初心者は最初の1度だけミスるかもしれません。
3.if文の中括弧を省略した場合のミス
・コード例
結果が真の場合に、hoge1,hoge2を出力させたい場合、以下の様にしてしまうと、結果が偽の場合でもhoge2が出力されてしまいます。
#include <stdio.h>
int main(void)
{
int num = 0;
if(num == 1)
printf("hoge1\n");
printf("hoge2\n");
return 0;
}
・対処法
中括弧をつけましょう。
if(num == 1)
{
printf("hoge1\n");
printf("hoge2\n");
}
・解説
if文は中括弧を省略することができます。
ただし、省略した場合実行されるのは次の1行のみです。
上記の場合などは、hoge2はif文の外側となってしまう為、if文の結果に関わらず実行されることになります。
最初は中括弧を省略していて、後からもう1行のみ追加した場合などにたま~にあるので、if文では中括弧を必ず付けるのがおすすめです。
4. 二重ループでのミス
・コード例
3×3のループ、9回分出力したい場合に、以下の様にしてしまうと正しく出力できません。
(無限ループになります)
#include <stdio.h>
int main(void)
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; i++)
{
printf("出力\n");
}
}
return 0;
}
・対処法
内側のfor文が間違っているので修正する。
for(int j = 0; j < 3; j++)
また、i、jなどの変数名でなく、目的にあった変数名を付けるのもおすすめです。
例:縦3行 横3行の何らかの処理をしたい場合
#include <stdio.h>
int main(void)
{
for(int tate = 0; tate < 3; tate++)
{
for(int yoko = 0; yoko < 3; yoko++)
{
printf("出力\n");
}
}
return 0;
}
・解説
今でも偶にミスリます。
上記のコード例の場合、jに加算されていないので、 j < 3 の条件が偽なることはない為、無限ループになってしまいますね。
以上、他にも挙げだすとキリが無いですが、自分がハマったことのあるミスを紹介しました。