識別子のスコープとは、特定のオブジェクト(変数、関数、定数)がその名前でアクセス可能なプログラムの部分です。C言語では、このメカニズムは大規模なモジュールプログラムの作成、テスト、および保守を容易にするために実装されました。
問題の背景:
スコープの出現は、プログラムを構造化し、変数がコードの異なる部分に及ぼす影響を制限する必要性と関連しています。これにより、名前の衝突や予測不可能な動作を避けることができます。
問題:
グローバル変数のみを使用すると、重複や偶然の値の変更といった「古典的な」エラーに陥りやすいです。一つのスコープで宣言された変数は、他のスコープの変数にアクセスできなかったり、衝突したりすることがあり、これがエラーを引き起こしたり、デバッグを難しくしたりします。
解決策:
C言語にはいくつかのスコープレベルがあります。
コードの例:
static int file_var = 0; // ファイル内でのみ見える int global_var = 1; // すべてのファイルで見える void func() { int block_var = 2; // func内でのみ見える for (int i = 0; i < 3; i++) { // iはこのfor内でのみアクセス可能 } }
主な特徴:
staticなしでヘッダーファイルに宣言された変数はどうなりますか?
変数がstaticなしで.hに宣言され、複数のファイルでこのヘッダーがインクルードされると、リンクエラーが発生します:Multiple definition。ヘッダーファイルでは常にexternを使用するか、プライベートのためにstaticを使用してください。
ブロックを出るとローカル変数はどうなりますか?
ローカル変数は「消え」、そのメモリは解放され、値は失われます。その後のアクセスはエラーになります。
if (1) { int temp = 5; } // printf("%d", temp); // エラー:tempはスコープ外
関数をstaticとして宣言できますか、それは何をもたらしますか?
はい、static関数を宣言すると、その関数は現在のファイル内でのみ見えるようになります。これは、ユーティリティ関数のカプセル化に役立ちます。
ヘッダーファイルでstaticなしに変数を定義し、複数の.cファイルでそのヘッダーをインクルード:
// myheader.h int count = 0; // 悪い
利点:
欠点:
スコープ管理のためにexternとstaticを使用:
// myheader.h extern int count; // 良い // myfile.c static void helper() { } int count = 0;
利点:
欠点: