ホーム » スタッフ » 斉藤徹 » 変数のスコープと寿命

2013年4月
« 3月   5月 »
 123456
78910111213
14151617181920
21222324252627
282930  

最近の投稿(電子情報)

アーカイブ

カテゴリー

変数のスコープと寿命

先週のC言語の制御構文の話に続き、変数のスコープと寿命について 説明を行う。

大域変数の問題

最初に、局所変数などの利点を分ってもらうために、 以下のコードの誤解について説明する。

// for文の繰り返しが動かない例。
// 2回の繰り返しを2回で4回表示にはならない
int i ;
void foo() {
for( i = 0 ; i < 2 ; i++ )
printf("A") ;
}
void main() {
for( i = 0 ; i < 2 ; i++ )
foo() ;
}

大域変数を多用すると、違う意味で同じ変数を使う 危険性があり、プログラムが動かなくなる。 こういう時には、関数内で局所変数を使い、 同じ名前で違う入れ物の変数を活用する。

局所変数は、通常そのブロックに入る時に、 変数の入れ物が作られ、 そのブロックを抜ける時に、変数が消えてなくなる。 このような、変数が作られる/消えるタイミングを寿命という。

また、局所変数は、そのブロック内でのみ有効であり、 その変数が使える範囲・見える範囲をスコープと呼ぶ。

自動変数と静的変数

以下のような例で、変数の使い方の違いを3種類示す。

int x = 123 ;
// 静的大域変数
// 寿命は、プログラム起動から停止まで
// スコープは、プログラム全体。
void foo() {
int x = 234 ;
// 動的局所変数
// 寿命は、関数に入って抜けるまで
// スコープは、foo() の内部のみ
}
void bar() {
static int x = 345 ;
// 静的局所変数
// 寿命は、プログラム起動から停止まで
// スコープは、bar() の内部のみ
}

関数の仮引数と実引数

関数呼び出しでは、実引数の内容が、仮引数にコピーされるだけ。 以下のコードでは、「foo() の x++」は、仮引数のxが変化するだけ。 mainのxの値が変化することはない。

int foo( int x , int y ) {
// x , y は、仮引数
x++ ;
return x + y ;
// 返り値の方は、関数の前に書く。
}
void main() {
int x = 123 ;
printf( "%d" , foo( x , 10 ) ) ;
printf( "%d" , foo( x , 20 ) ) ;
}

大域変数を使うと、関数を呼び出しても、値の変化が発生するかもしれない。 関数を呼び出した影響が、他の部分に及ぶことは、''副作用''と呼ばれる。