//const_sample0.cpp
#include <iostream>
using namespace std;
int main()
{
int suji[5]; //数字
cout << "5個の数字を入力してください。"
<< endl;
for(int i = 0; i < 5; i++)
cin >> suji[i];
//本当のプログラムではここで何かやるはずですが、、、
//簡単のため、単に打ち出すだけにします。
cout << "数字を打ち出します。"
<< endl;
for(int i = 0; i < 5; i++)
cout << suji[i] << "
";
}
#define TOTAL 5
を使うという方法があります。(最後に「;」は付けません。)このように書くと、プログラム中のTOTALが5と解釈されるのです。ここで、TOTALという名前は、プログラマが勝手に付けて良い名前なので、別の名前でも問題ありません
#define KAZU 5
なら、KAZUが5になります。この#defineを使うと、上のプログラムは
//const_sample1.cpp
#include <iostream>
#define TOTAL 5
using namespace std;
int main()
{
int suji[TOTAL]; //数字
cout << TOTAL << "個の数字を入力してください。"
<< endl;
for(int i = 0; i < TOTAL; i++)
cin >> suji[i];
//本当のプログラムではここで何かやるはずですが、、、
//簡単のため、単に打ち出すだけにします。
cout << "数字を打ち出します。"
<< endl;
for(int i = 0; i < TOTAL; i++)
cout << suji[i] << "
";
}
と書けるのです。実行すると、前のプログラムと同じ動作をします。
この書き方の良さは、わかりましたか?つまり、5個の数字を7個の数字にするために、書き換えるところは、ひとつだけなのです。つまり、#defineのところを、
#define TOTAL 7
とすれば良いのですね。とても簡単です。この方法なら、プログラムがどんなに長くても、大丈夫です。これは、Cでよく使われる手法です。
しかし、一般に、C++では別の方法が推奨されています。それを見る前に、こんなプログラムを考えたらどうでしょう。
//const_sample2.cpp
//エラー!!!
#include <iostream>
using namespace std;
int total = 5;
int main()
{
int suji[total]; //数字
cout << total << "個の数字を入力してください。"
<< endl;
for(int i = 0; i < total; i++)
cin >> suji[i];
//本当のプログラムではここで何かやるはずですが、、、
//簡単のため、単に打ち出すだけにします。
cout << "数字を打ち出します。"
<< endl;
for(int i = 0; i < total; i++)
cout << suji[i] << "
";
}
ありゃ。エラーだ。
これは上のプログラムとほとんど同じですが、#defineなどというものを使わずに、intを使おうとしているのです。#defineは便利ですが、論理的なミスを見つけにくいという欠点があるのです。それなら、C++(やC)の一部である変数を使えばよいだろうという発想です。変数であれば、何かミスをしたときには、コンパイラが教えてくれるそうだからです。
変数totalの定義をmainの外でしていますが、このこと自身に問題はありません。これは、あくまでmainという関数の外で(そして、他のどの関数の中でもない場所で)変数を定義しているだけです。
しかし、実際にコンパイルしてみると、エラーになってしまうのです。int suji[total];のように配列を定義するのに、totalが変数であってはいけないのです。コンパイラはここには定数を使えと文句を言っいるのです。(私は初心者の頃、これでとても悩みました。)CやC++ではそのように決められているのです。
ところが、この解決方法は、実は簡単です。int total=5;をconst int total=5;と書き直せばよかったのです。くどいですが、ちゃんと書いて見ましょうか。
//const_sample3.cpp
//エラーでない!!!
#include <iostream>
using namespace std;
const int total = 5;
int main()
{
int suji[total]; //数字
cout << total << "個の数字を入力してください。"
<< endl;
for(int i = 0; i < total; i++)
cin >> suji[i];
//本当のプログラムではここで何かやるはずですが、、、
//簡単のため、単に打ち出すだけにします。
cout << "数字を打ち出します。"
<< endl;
for(int i = 0; i < total; i++)
cout << suji[i] << "
";
}
コンパイルも実行もオッケー
ところで、プログラム中の誤ったコードのおかげで、間違ってデータを書き換えてしまうということがよく起こります。(プログラムをタイプしていて直接データを書き間違うという意味ではなく、「変更したくないデータを書き換えてしまうコード」などを間違って書いてしまうという意味です。)
そんな、ばかな?いえ、本当です。このような、プログラマが意識していない「データの書き換え」はやっかいです。こういうことが起こると悪夢のデバッグ(エラー直し)がはじまるのです。
ところで、このデータは絶対に書き換えないぞ、と思っている場合なら、実は、const宣言してしまえば良いのです。こうしておけば、それは定数として扱われるので、変更ができなくなるのです。そのため、あとで知らずにそのデータを書き換えるようなコードを書くと、コンパイラがわかりやすいエラーメッセージで知らせてくれるのです。(初心者はコンパイル時にでるエラーを恐れたりしますが、実は、コンパイル時に出るエラーなんて、ものの数ではないのです。というか、コンパイル時にエラーになってくれた方が、実行中に突然プログラムが暴走したりするのより、ずっと良いのです。)そういうわけでconstはとても重要なのです。