なぜ,大域変数は使わない方が良いか, 次のようなプログラムを例にとって,解説しよう.
int data[N], a[N], b[N]; /* 大域変数 */
int total; /* 大域変数 */
...........................
...........................
この間に,他の大域変数や関数の宣言定義
...........................
...........................
void sum()
{
int i;
for (i = 0; i < N; i++) {
total += data[i];
}
}
...........................
...........................
void set()
{
int i;
for (i = 0; i < N; i++) {
data[i] = a[i] + b[i];
}
}
...........................
...........................
数百行のプログラムコード
...........................
...........................
main()
{
...........................
...........................
...........................
set();
...........................
...........................
...........................
sum()
...........................
...........................
...........................
}
さて,ここでこの sum() が,はたして何をしているのか? といことを,この関数呼び出しの部分だけを見て,想像することができるであろうか.「何か総和を求めているらしいが,何の総和なのか,求めた結果がどこにあるのか,さっぱり分からない.
sum の関数定義を探し出し,それを見ると,どうやら大域変数の配列 data の総和を求めて,それを同じく大域変数の total にしまい込んでいるらしい.でも, data の数値はどこで定義されているのか,分からない.
プログラム全体を通して見て,やっと set という関数で定義されているらしい,ということが分かる.
このようなプログラムの分かりにくさの原因は,関数が使用する変数が関数の引数に与えられることなく,関数が大域変数を直接使用している,ということである。
ところが,set や sum に次のような引数があったらどうであろう.
main()
{
int data[N], a[N], b[N];
int total;
...........................
...........................
...........................
set(data, a, b);
...........................
...........................
...........................
sum(data, &total);
...........................
...........................
...........................
}
これならば,set や sum が何をしているのかが,その関数呼び出しを見ただけで想像できるし,少なくとも,それらの関数が何を使っているのかは明瞭となる.
ここまで読んで分かるかと思うが,大域変数を使うそのこと自体が悪いのではなくて,関数で使用するものを引数に与えない,ということが悪いのである。 つぎのことを良く憶えておこう
関数で使用するものは,すべて引数で与えるべきである。