ホーム » スタッフ » 斉藤徹 » 講義録 » 情報構造論 » file-scope(static)とextern文

2010年10月
« 9月   11月 »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

最近の投稿(電子情報)

アーカイブ

カテゴリー

file-scope(static)とextern文

プロコンの競技部門の学生さんたちが、最後の追い込み。 各パーツに分かれて動作確認が取れてきたし、 1つのプログラムに合成する最後の段階になっている様子。 しかしながら、合成した後プログラムが動かないとの相談。 1度目の処理は動くけど、2回目で動かないという状態なので、 不完全な初期化データを使って動かなくなっているのではと想像する。 といっても、そう簡単に間違いが見つかる訳もないけど、 ひとまずコードを見せてもらう。 すると、覚えたての分割コンパイルで、ヘッダファイルの中に、 static int array[…] ; といった記載が見つかる。

このままでは、array[] が、各C言語ファイル毎に、file-scope の別な実体を持つため、 大域変数渡しの副作用が伝わらなかったり、その結果として未初期化が発生したり。

ファイルスコープ

C言語では、静的変数の局所変数を作りたい場合、関数ブロック内で "static"キーワードを指定すればよい。 しかしながら、関数ブロック外で static キーワードをつけると、 分割コンパイルした場合、file-scope を持つようにコンパイルされる。 つまり、各ファイル毎の大域変数は、たとえ同じ名前の大域変数が別ファイルに あったとしても、別な記憶領域を確保してくれる。

(( aaa.c ))
int x1 ;         // 静的変数・大域変数
static int x2 ;  // 静的変数・大域変数・ファイルスコープを持つ
void foo() {
static int x3 ; // 静的変数で局所変数
:
}
(( bbb.c ))
extern int x1 ;  // aaa.c の x1と同じ実体を参照できる。
static int x2 ;  // aaa.cのx2とは大域変数だけど別の実体をもつ

分割コンパイルして、各ファイルで共通の変数や関数を定義する場合は、 以下のように行う。 ポイントは、extern によって宣言すると、実体は別のところにある変数となる。

(( common.h ))
int foo() ;      // プロトタイプ宣言
extern int bar ; // 実体はどこかで確保される変数として宣言
(( aaa.c ))
#include "common.h"
int bar = 123 ;  // 変数barの実体
int foo() {
// 関数foo()の実体
}
(( bbb.c ))
#include "common.h"
void main() {
bar = 234 ;              // aaa.c の大域変数barに代入
printf( "%d" , foo() ) ; // aaa.c の関数foo()を呼び出し
}