Programming組み込みC開発者

C言語におけるローカル変数とグローバル変数の違いと動作の保証について説明してください。寿命、スコープ(可視性)および初期化の観点から何が異なり、異なる種類の変数を扱う際に典型的に遭遇するエラーは何ですか?

Hintsage AIアシスタントで面接を突破

回答。

問題の背景:

C言語では、メモリ管理とコードの可視性の制御のために、グローバル変数とローカル変数が導入されました。グローバル変数は、モジュラープログラミングが登場する前の関数間のデータ交換の主要な方法でしたが、ローカル変数は相互作用を減らし、コードの隔離を促進しました。

問題:

グローバル変数とローカル変数の違い、すなわち寿命、スコープ(可視性)、初期化のルールとタイミングについての誤解がしばしば生じます。グローバル変数は同期の問題や可読性の低下を引き起こし、ローカル変数は必要なデータにアクセスできなくなることがあります。これらの違いに対する理解の誤りはバグを引き起こし、コードのスケーラビリティを難しくします。

解決策:

グローバル変数はすべての関数の外部で宣言され、externを使用することで全ファイルからアクセス可能です。その寿命はプログラム全体であり、初期化は静的変数の場合は暗黙的にゼロで行われ、ユーザーの指定値で明示的に行います。ローカル変数は関数内で宣言され、その寿命は関数の呼び出しに限られ、自動的に初期化されることはありません。

コードの例:

int g_var = 42; // グローバル変数 void foo() { int l_var = 5; // ローカル変数 }

主な特徴:

  • グローバル変数:寿命 — プログラム全体、スコープ — すべてのファイル(extern使用時)、初期化は指定がない限り自動的にゼロ。
  • ローカル変数:寿命 — 関数(またはブロック)の本体、スコープ — ブロック内のみ、デフォルトでは初期化されません。
  • 名前の衝突、偶発的なアクセス、不定な内容のローカル変数に起因するエラーが発生します。

トリッキーな質問。

ローカル変数は初期値が指定されていない場合、自動的にゼロで初期化されますか?

いいえ。グローバル変数や静的変数だけがデフォルトでゼロで初期化されます。ローカル変数は、明示的に初期値を与えない限り、「ゴミ」(不定値)を含みます。

例:

void test() { int a; printf("%d ", a); // 未定義の動作 }

異なるファイルから常にグローバル変数にアクセスできますか?

いいえ。関数の外でstaticとして宣言された変数は、そのソースファイル内でのみ見えます。グローバルな可視性が必要な場合はexternを使用してください。

関数内でグローバル変数を宣言することはできますか?

いいえ。関数内のすべての宣言はローカルです。グローバル変数は関数の外でのみ作成できます。

一般的なエラーとアンチパターン

  • 初期化されていないローカル変数の使用。
  • グローバル変数の過剰な使用 — メンテナンスの困難や同期エラーを引き起こす。
  • 名前の誤りは変数の隠蔽を招く。

実生活の例

ネガティブなケース

グローバル変数を使用して関数間でデータを交換します:

int error_code; void f1() { error_code = 1; } void f2() { if (error_code) ... }

利点:

  • パラメータを渡す必要がないので、迅速かつ簡単です。

欠点:

  • 初期化を忘れる可能性が高く、偶発的な上書きが可能であり、マルチスレッドが危険になります。

ポジティブなケース

すべての変数がローカルで、データは関数のパラメータを介して渡されます:

void f1(int *err) { *err = 1; } void f2(int err) { if (err) ... }

利点:

  • エラーハンドリングが安全で、モジュール性とテスト可能性が向上します。

欠点:

  • 値を明示的に渡す必要があり、場合によってはコードが少し長くなります。