なぜ,大域変数は使わない方が良いか, 次のようなプログラムを例にとって,解説しよう.
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
が何をしているのかが,その関数呼び出しを見ただけで想像できるし,少なくとも,それらの関数が何を使っているのかは明瞭となる.
ここまで読んで分かるかと思うが,大域変数を使うそのこと自体が悪いのではなくて,関数で使用するものを引数に与えない,ということが悪いのである。 つぎのことを良く憶えておこう
関数で使用するものは,すべて引数で与えるべきである。