グローバル変数は、C言語においてプログラムのすべての関数からアクセス可能なデータを保存する手段として、初めから存在しました。これにより、関数の引数を通じて値を明示的に渡すことなく、異なるコード部分間で情報を交換することができます。これらの変数は、別のメモリ領域に保存され、プログラムのライフサイクル全体にわたって存在します。
グローバル変数の過剰かつ制御されていない使用は、コードの保守が困難になる原因となり、バグの発見が難しくなり、名前の衝突のリスクを高めます。大規模なプロジェクトでは、グローバルにアクセス可能なデータがどこで変更されているかを理解することが難しく、デバッグが困難になります。さらに、異なるファイル(モジュール)でのグローバル変数の不適切な宣言は、リンクエラーを引き起こし、データの重複を招く可能性があります。
最適なプラクティスは、1つの.cファイルでグローバル変数を明示的に宣言し、そのプロトタイプをexternキーワードを使ってヘッダーファイルに移動することです。これにより、単一の保存場所が得られ、コンパイラは重複を防ぎます。グローバル変数の最小化のためには、ファイル内のスコープを持つ静的変数を使用します。過剰なグローバル状態の使用は、関数間で渡されるデータ構造に置き換えます。
コード例:
// file.h #ifndef FILE_H #define FILE_H extern int global_counter; #endif // file.c #include "file.h" int global_counter = 0; // main.c #include "file.h" #include <stdio.h> int main() { global_counter++; printf("%d\n", global_counter); return 0; }
主な特徴:
externを使用します。グローバル変数を静的に宣言することはできますか? その場合、通常のグローバル変数とどのように異なるのですか?
はい、staticキーワードを使って宣言されたグローバル変数は、その宣言されたファイル内でのみ見えます。プログラムの実行中は存在し続けますが、別のコンパイル(異なる.cファイル)ではアクセスできなくなります。これは、ファイルレベルでデータをカプセル化するために使用されます。
他のファイルからグローバル変数にアクセスするためにexternを必ず使用する必要がありますか?
はい、他のモジュールで定義されたグローバル変数にアクセスしたい場合、通常、ヘッダーファイルでexternキーワードを使って宣言する必要があります。さもなくば、コンパイラは変数を再定義しているとみなします。
// a.c int global_var = 1; // b.c extern int global_var;
次のコードは動作しますか?
// a.c int var; // b.c int var;
いいえ、このコードはリンクエラーを引き起こします。なぜなら、変数が二重に定義されているからです。グローバル変数の定義は一つだけでなければならず、アクセスするためにはexternを使用する必要があります。
開発者は、アクセス制限なしでグローバル変数に構成パラメータを配置します:
長所:
短所:
グローバル変数は1つのファイルでのみ定義され、extern経由でアクセスされ、厳格に文書化されます。他の場合では、ファイルの静的スコープやパラメータの構造が使用されます:
長所:
短所: