ホーム » スタッフ » 斉藤徹 » 講義録 » プログラム応用 » 変数の寿命とスコープ

2015年4月
« 3月   5月 »
 1234
567891011
12131415161718
19202122232425
2627282930  

最近の投稿(電子情報)

アーカイブ

カテゴリー

変数の寿命とスコープ

先週のC言語の制御構文のシメとして、switch-case文の説明をしてから、 変数の寿命とスコープの説明を行った。

switch-case文の説明では、以下の例は期待通りの動きをしない…といった例も交えて説明。 ただし、double誤差問題や文字列のポインタ関連なので、以後の授業で改めて説明が必要だろう。

// double誤差問題
double x ;
for( x = 0.0 ; x <= 1.0 ; x += 0.1 )
   switch( x ) {
   case 0.3 : printf( "A" ) ; // 0.299999...と0.3は違う値になるかも
              break ;
   }

// 文字列の比較の問題
char str[ 10 ] ;
scanf( "%s" , str ) ;
switch( str ) { // strの先頭番地と"yes","no"の先頭番地の比較
case "yes" : printf( "はい" ) ; break ;
case "no"  : printf( "いいえ" ) ; break ;
}

変数の寿命とスコープ

最初に、以下の様なプログラムが期待通りに動かない説明をして、 大域変数を共用することの問題を話す。

int i ; // 大域変数(global variable)
void foo() { // Aを2回表示
   for( i = 0 ; i < 2 ; i++ )
      printf( "A" ) ;
}
void main() {
   // foo(Aを2回表示)を2回呼び出すつもり
   for( i = 0 ; i < 2 ; i++ )
      foo() ;
}

こういったトラブルを避けるためには、局所変数を使えば良い。

局所変数を使って、目的の処理…。改良版はココをクリックで表示。

void foo() { // Aを2回表示
   int i ; // 局所変数 foo::i
   for( i = 0 ; i < 2 ; i++ )
      printf( "A" ) ;
}
void main() {
   int i ; // 局所変数 main::i
   for( i = 0 ; i < 2 ; i++ )
      foo() ;
}


最近の構造型プログラム言語であれば、 変数には寿命(変数が、作られる/消える、タイミング)と、 スコープ(変数が使える範囲)がある。

#include <stdio.h>
// 静的大域変数(スコープ全体,寿命:起動から終了)
int x = 123;
void foo() {
   // 動的局所変数(スコープ:foo内部,寿命:foo呼出から戻るまで)
   int y = 234 ;
   // 静的局所変数(スコープ:foo内部,寿命:起動から終了)
   static int z = 345 ;
   x++ ; y++ ; z++ ;
   printf( "%d %d %d¥n" , x , y , z ) ;
}
void main() {
   foo() ;  // 124,235,346が表示
   foo() ;  // 125,235,347が表示
}

関数の引数

関数の引数の受け渡しの説明。

返り値の型 関数名( 仮引数の宣言 ) {
   何らかの処理 ;  // 関数に入ると仮引数が局所変数で作られ、
   return 式 ;   // 実引数が代入される。
}
void main() {
   関数名( 実引数 ) ;  // 実引数は仮引数にコピーされる。
}

値渡し、ポインタ渡しなどの説明をしたいけど、時間なので次週に説明。 残り時間では、BCPL→B言語→C言語(K&R-C→ANSI-C)→C++といった C言語の変遷を簡単に紹介。