プログラミング コラム

スコープの大切さ

プログラミングの学習を始めて、関数の練習を始めたころ、
「スコープ」という言葉に出会うでしょう。

分岐や反復などの制御文とは違った難しさを感じるかもしれませんが、
まずは「変数の有効範囲」をイメージすると良いでしょう。
初めのうちは意識することなくプログラミングできていても、関数などを駆使して品質の高い作品を作るには非常に重要な仕組みです。

今回は、そんなスコープについてお話ししてみたいと思います。
(C言語のスコープを前提としています)

スコープを変数の有効範囲と考えると、
有効範囲の広い変数、狭い変数があるということになります。

C言語を例に挙げると、関数の外側で宣言された変数は、有効範囲の広い「グローバル変数」になり、
関数(ブロック)の中で宣言された変数は、有効範囲の狭い「ローカル変数」になります。

グローバル変数は、宣言されたファイルの中であれば、どの関数からでも参照することができます。
ローカル変数は、宣言されたブロック外からは参照できません。

スコープの利点は沢山ありますが、まず理解しやすいのは
「変数名の重複を避ける」ではないでしょうか。
スコープが異なるということは、同名の変数であっても異なる変数として扱われます。
短くてわかりやすい変数名が使えるのも、スコープのおかげです。

さて、ここからはもう一つの利点について、私の経験談を交えてお話しします。

私がローカル変数のスコープを知った時は、とても面倒に感じました。
関数同士でデータを共有したかったのですが、スコープのせいで引数と戻り値を使ってデータをやり取りすることしかできず、煩わしさしか感じませんでした。
C言語では構造体を活用して、多数のデータを関数間でスムーズにやり取りできるのですが、当時はそんなスキルもなく、途方に暮れていました。

そこで知ったのがグローバル変数です。

とりあえずファイル内で宣言しておけば、どの関数からでも自由に参照できるため
引数・戻り値から解放され、とても良いものを見つけたと思っていました。

ところが、制作が進むにつれ、エラーに悩まされるようになります。
グローバル変数に意図しない値が入っているのですが、
それが、どの関数から、どのタイミングで代入されたものが、非常に分かりにくくなっていました。

引数と戻り値であれば、この関数からあの関数へと、データの流れをしっかりと追うことができました。
しかし、グローバル変数は どの関数からでも参照できてしまうため、値の把握が困難です。

そのような状況を経験していった私は、徐々に「自由に参照できることの危うさ」を感じていきます。

どの関数からでも参照できることは、一見自由で、便利なものように見えます。
しかし、逆に考えれば「どうにでもできてしまう」ことになります。

面倒に見える引数や戻り値も、データの流れを明確にしてくれる存在に感じました。
ただ不便に感じていたローカル変数も不用意な値の代入を防いでくれる「データの保護」としての重要な役割があると感じました。

プログラミングを始めたころは、ローカル変数のような、何かを制限する存在は利点を感じにくいと思います。
対して、グローバル変数は制作を助けてくれる、魅力的な存在に感じるかもしれません。

しかし、規模の大きな作品でスコープが広い変数を多用すると、収拾がつかくなることもあります。
面倒に感じても、なるべくスコープの狭い変数を使っていきたいですね。
written by Tomoji Onishi / 2022.11.16
コラム一覧