「C言語/データ型と変数」の版間の差分

削除された内容 追加された内容
「C言語/データ型と変数の高度な話題」に分離した話題を除去。
C言語/関数 にローカル変数の話題を移動したので、こちらでは削除。
336 行
参照する際、変数があらかじめ初期化や代入されているよう注意せよ。
 
== ローカル変数とグローバル変数 ==
 
<source lang=c>
//例 グローバル変数とローカル変数
 
int g;//gはグローバル変数
 
int main(void)
{
int l;//lはローカル変数
}
</source>
 
C言語では通常、変数をある関数ブロックの内部で宣言した際、その変数は、その関数ブロックの中でしか通用しない。
ある関数ブロックの内側でしか通用しない変数を'''ローカル変数'''と呼ぶ。いっぽう、(プログラム冒頭部(include文の直後など)などの)関数外で宣言した変数をグローバル変数と呼び、すべてのブロック内で通用する。
 
変数は宣言する場所によってローカル変数とグローバル変数とに分かれる。<ref>ローカル変数とグローバル変数という用語はよく使われるが、『JISX3010:2003』には出てこない。</ref>
 
ともかく、関数ブロック内で宣言した変数は、原則的にすべてローカル変数になるので、その変数はその関数の中でしか通用しない。
 
ローカル変数の存在意義は、(誤って他のブロック内の変数を書き換えられてしまうような)バグを未然に防ぐためである。このように変数の仕組みを、その変数を宣言したブロック内でしか通用しないという仕組みにすることにより、他ブロックを書き換えてしまうようなバグを未然に防ぐ・・・というのがローカル変数の意義である。
 
 
たとえ、他の関数ブロックで同名の変数が使用されていようが、それぞれの関数ブロックごとに、変数のアドレスは別々である。つまり、人間に例えるなら、同姓同名の別人のようなものである。
 
なので、通常、ある関数ブロックの中で宣言した変数は、すべてローカル変数である。たとえmain関数内で変数を定義をしても、その(main関数ないで宣言された)変数ですら、main関数内でしか通用しない。
 
もし、ある関数が、他の関数と値のやりとりをしたい場合は、関数の返却値(「返し値」、「戻り値」ともいう)を仲介して、値を別関数ブロックに送る必要がある。
 
 
ローカル変数はその定義により、性質として、その変数を宣言したブロックからのみアクセスでき、
他のブロックで宣言したローカル変数とは一切関係がない(ブロック有効範囲)。<ref name="識別子の有効範囲">『JISX3010:2003』p.21「6.2.1 識別子の有効範囲」</ref>
記憶域クラス指定子staticを持たないローカル変数は、
ブロックに入るときに作成され、
ブロックが終了するときに破壊される(自動記憶域期間)。<ref name="オブジェクトの記憶域期間">『JISX3010:2003』p.24「6.2.4 オブジェクトの記憶域期間」</ref>
 
 
つまり、そのブロックを含む同じ関数が再び呼び出されても、
前の値は保存されていない。
また、初期化していないローカル変数の値は不定であり、その値をそのまま参照してはならない。
(値を代入した後になら参照してもよい。)
 
一方、すべてのブロックの外側で宣言された変数をグローバル変数と呼ぶ。
グローバル変数は全てのブロックからアクセスできる(ファイル有効範囲)。<ref name="識別子の有効範囲"/>
グローバル変数はプログラムが開始されたときに作成され、
プログラムが終了したときに破壊される(静的記憶域期間)。<ref name="オブジェクトの記憶域期間"/>
また、グローバル変数は、定数式でのみ初期化することができ、
明示的に初期化しない場合、0で初期化される。
 
<pre>
notice!
グローバル変数の乱用は避けるべきです。
理由は、どこからでもアクセスできることでバグの発見が困難になったり、
プログラムの実行中ずっと存在することでメモリの使用効率が落ちたりするからです。
</pre>
 
== 脚注 ==