エンジニアの転職お問い合わせ記事には広告を含む場合があります。【C言語】変数のスコープとは?static・ローカル・グローバル変数の違い2024年10月29日おゆ組み込み系プログラマとして5年働いていた元エンジニアです。得意言語はC言語とC++。本サイトでは学生および新人組み込み系プログラマに向けてプログラミング知識をわかりやすく解説しています。C言語やC++を勉強しているとたまに出てくる変数のスコープって何?難しそうだからわかりやすく解説してほしい。ローカル変数とグローバル変数とstatic変数って何が違うの?こんな疑問にお答えします。おゆC言語、C++の理解を深めるために変数のスコープ(有効範囲・寿命)の知識は必須です。この記事では具体例を使ってわかりやすく解説していきます。変数のスコープとは変数の有効範囲(寿命)のこと変数には有効範囲(寿命)があります。変数の有効範囲は宣言の仕方によって異なります。ローカル変数(詳しくは次の項目で解説)の有効範囲は一番内側のスコープ(中カッコ)の中だけです。以下は変数numの値を出力する簡単な例です。printf("num=%d\n",num);}実行結果num=0しかし1の行を中カッコでくくるとコンパイルエラーになります。printf("num=%d\n",num);}エラーnumという変数は宣言されていませんという意味のエラーです。え、直前で宣言してるじゃん!なのに宣言されていないってどういうこと?おゆnumの有効範囲はスコープの範囲内(中カッコの内側)なのに、スコープの外でnumを呼び出しているからです。スコープの外に出ると「numはもう不要なんだ!」と判断されてnumは削除されてしまいます。そのためprintf内でnumを使うように命令しても「numはもう無いよ!」と言われてしまうわけです。}の中で宣言された変数はローカル変数と呼ばれます。ローカル変数の有効範囲は宣言が書かれた一番内側の中カッコ内のみで、中カッコの外に出ると使えなくなります。}//charaの有効範囲はここまで}//num1の有効範囲はここまで実行結果num1=0num2=1chara=A変数には一般的にローカル変数を使います。ローカル変数の利点はメモリを節約できる点です。中カッコを抜けるたびにメモリが解放されるので、解放された分を別の変数のために再利用できます。おゆプログラムが多くのメモリを占領していると、複数のプログラムを同時進行で使うことが難しくなります。たくさんのウィンドウを開いて作業しているとパソコンの動作が重くなるみたいに。変数とメモリの関係については詳しくは以下の記事で解説しています。こんな疑問にお答えします。...続きを見る変数名の使い回しローカル変数のスコープ内では同じ名前の変数を定義できません。以下のコードはコンパイルエラーになります。num=0;}エラー文しかしスコープの外に出て変数が削除された後なら同じ名前の変数を再び宣言できます。num=12つ目のnumは1つ目のnumと同じ名前ですが、全く別の変数です。おゆ同姓同名の別人みたいな感じ。異なる関数の中で宣言された変数名が被るのは問題ありません。num=1おゆ違う関数であれば変数名は被ってもOK。同じ関数内で変数名が被るのは基本的にNGだけど、変数の有効期限が切れた後に再び同じ名前の変数を作るのはOK。ローカル変数=auto変数(自動変数)ローカル変数は頭にautoをつけるのが正式な宣言方法です。そのためローカル変数はauto変数または自動変数とも呼ばれます。printf("num=%d\n",num);}実行結果num=0autoは省略可能なので通常は例1のようにautoなしで宣言します。おゆ下で紹介するstatic変数と明示的に区別したい場合はautoを付けることもあります。グローバル変数グローバル変数とはグローバル変数とは中カッコの外で宣言された変数のことです。グローバル変数は中カッコの外からでも呼び出し可能で、有効期限(スコープ)はプログラムの始まりから終わりまでです。以下の例ではグローバル変数numの値がずっと保持されていることがわかります。num=3通常はグローバル変数の書き換えはほとんどしません。値がわからなくなると困るからです。上はあくまでグローバル変数の特徴を知ってもらうための例です。ほとんどの場合はローカル変数だけでも事足ります。一方でプログラムを通して何度も使う値はいちいち宣言するのが手間ですし、変数の値を変えたい場合に修正漏れが発生する恐れがあります。いう時にはグローバル変数が便利です。グローバル変数の乱用には注意です。数十、数百のファイルから成るプログラムのあちこちでグローバル変数が宣言されている場合を考えてみてください。どの変数名が既に使われているのか、グローバル変数の値はいくつなのかを調べるのが大変なのが想像できると思います。そのため通常はローカル変数を利用し、どうしても必要な変数のみをグローバル変数にします。おゆ組み込みプログラムでは動かす製品のスペック値などをグローバル変数に格納することがあります。グローバル変数は1つのヘッダーファイルにまとめるなど工夫すると管理しやすいです。同じ名前のグローバル変数とローカル変数がある場合グローバル変数と名前のローカル変数を宣言するとどうなるの?おゆその場合はローカル変数が優先されます。以下の例ではグローバル変数とローカル変数それぞれで同じnumという名前の変数を宣言しています。//グローバル変数のnumの値が出力される}実行結果1num=12num=0実行結果を見ると、1ではローカル変数の値が出力されています。ローカル変数のスコープ内ではローカル変数が優先されるからです。スコープを出るとローカル変数のnumは削除されるので、2ではグローバル変数の値が出力されます。このように同じ変数名のグローバル変数とローカル変数が存在した場合はローカル変数が優先されます。static変数(静的変数)static変数とはローカル変数とグローバル変数ほどは使いませんが、static(スタティック)変数もあります。頭にstaticと付けて変数を宣言するとstatic変数になります。static変数もグローバル変数のようにプログラムの終わりまで値が保持されるのが特徴です。グローバル変数とは違って使えるのは宣言した関数の中だけです。以下の例ではprint_num関数の中でstatic変数を宣言しています。num=num+1;}実行結果num=0num=1num=2static変数の初期化は一度だけ行われ、関数を出た後も値は保持されます。よって例ではprint_num関数を呼び出すたびにnumの値が増えています。static変数は宣言された関数内でのみ有効なので、main関数から呼び出すとコンパイルエラーになります。比較としてnumをローカル変数にした場合の結果も載せておきます。numの宣言以外は同じコードですが、ローカル変数は関数を出るとリセットされるので実行結果は異なります。num=num+1;}実行結果num=0num=0num=0static変数はなぜ必要かなんでstatic変数があるんだろう?グローバル変数じゃダメなのかな?おゆ実はグローバル変数は管理が大変で、プログラムミスの元になりやすいんです。関数内だけで使う変数ならstatic変数を使った方が安全です。確かに短いコードであれば変数の管理がしやすいので、値を保持したいならグローバル変数を使っておけば事足ります。実務で使うコードは何百、何千行にも及びます。グローバル変数だとどこからでも書き換えられてしまうので、いちいち書き換えがないかや現在の値はいくつなのかを考えなくてはいけません。複数のファイルから成るプログラムの場合、他のファイルで同じ変数名が使われていないかの確認も行う必要があります。これでは面倒ですしミスが起こりやすいです。static変数なら値を保持したいという要求は満たしつつ、変数を宣言した関数内で書き換えられていないかだけを確認すればよいので圧倒的に管理が楽なんです。おゆプログラミングはミスとの戦いです。プログラマにとっていかにミスをしにくいコードが書けるかは重要です。ローカル変数・グローバル変数・static変数の初期値ローカル変数は値を初期化しないと適当な値が代入されます。一方でグローバル変数とstatic変数は初期化しないと自動的に0が代入されます。コードの読みやすさや予期せぬトラブル回避のためにも明示的に初期化しておくのをおすすめします。まとめ基本的にはローカル変数を使いますが、値を保持したい変数にはstatic変数を使います。static変数では不便な場合は最終手段としてグローバル変数を使います。ローカル変数は宣言された中カッコ内でのみ値が保持されますが、グローバル変数とstatic変数はプログラムの始めから終わりまで保持されます。このように特徴が異なるのは前者と後者がメインメモリの別の場所に保存されるからです。変数とメインメモリの関係について詳しく知りたい方は以下の記事をどうぞ。プログラマとしてレベルアップするには必須の知識です。こんな疑問にお答えします。...続きを見るC言語で行き詰まったら...C言語・C++がわからない時に質問できるサイト・サービス5選C言語を独学で勉強しているけど内容がイマイチわからない。何がわからないのかもわからない。C++のエラーが解決できない。ググってもわからない。わかる人に解説してほしい。...続きを見るブログランキング参加中。クリックしてもらえると励みになります。コメントをキャンセルメールアドレスが公開されることはありません。※サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。上に表示された文字を入力してください。こんな疑問にお答えします。こんな疑問にお答えします。【C言語】while(1)・while(0)の意味とループを抜ける方法プログラムを読むんでいるとたまにwhile(1)、while(0)といった記述を見かけます。while(1)を使うと無限ループを作れます。while(1)でも同じです。...C言語入門講座C言語・C++がわからない時に質問できるサイト・サービス5選C言語を独学で勉強しているけど内容がイマイチわからない。何がわからないのかもわからない。C++のエラーが解決できない。ググってもわからない。わかる人に解説してほしい。【C言語】switch・case・breakで複数条件分岐する方法switchで条件分岐する方法を知りたい。こんなお悩みにお答えします。...【C言語】関数をわかりやすく解説!引数・戻り値とは?呼び出し方は?おゆ組み込み系プログラマとして5年働いていた元エンジニアです。得意言語はC言語とC++。本サイトでは学生および新人組み込み系プログラマに向けてプログラミング知識をわかりやすく解説しています。