Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C/C++でグローバル変数と静的変数がデフォルト値(0)で初期化される理由

グローバル変数や静的(static)変数がデフォルト値である「0」で自動的に初期化されるのは、CおよびC++の標準規格でそのように定められているためです。コンパイル時にゼロで初期化しておく処理はほぼ無償で行えるため、実行時のパフォーマンスへの影響もありません。また、静的変数とグローバル変数は、生成されるオブジェクトコード上ではまったく同じように扱われます。

これらの変数は実行ファイル内の.bssセクションに配置されます。.bssセクションは、明示的に初期化されていないデータを格納するための領域であり、プログラムのロード時にOSがメモリを割り当ててゼロクリアします。この仕組みにより、実行ファイルのサイズを肥大させることなく、効率的な初期化が実現されています。

サンプルコード

#include <stdio.h>
int a;
static int b;
int main() {
    int x;
    static int y;
    int z = 28;
    printf("グローバル変数aのデフォルト値 : %d", a);
    printf("\nグローバル静的変数bのデフォルト値 : %d", b);
    printf("\nローカル変数xの値 : %d", x);
    printf("\nローカル静的変数yのデフォルト値 : %d", y);
    printf("\nローカル変数zの値 : %d", z);
    return 0;
}

実行結果

グローバル変数aのデフォルト値 : 0
グローバル静的変数bのデフォルト値 : 0
ローカル変数xの値 : 0
ローカル静的変数yのデフォルト値 : 0
ローカル変数zの値 : 28

上記のプログラムでは、main()関数の外側でグローバル変数aと静的変数bを宣言し、関数内で3つのローカル変数x、y、zを宣言しています。このうちyは静的なローカル変数、zは28で明示的に初期化された通常のローカル変数です。

int a;          // グローバル変数
static int b;   // グローバル静的変数
….
int x;          // ローカル変数
static int y;   // ローカル静的変数
int z = 28;     // 明示的に初期化されたローカル変数

それぞれの変数の値をprintf()で出力すると、グローバル変数・静的変数はすべて0で初期化されていることが確認できます。

printf("グローバル変数aのデフォルト値 : %d", a);
printf("\nグローバル静的変数bのデフォルト値 : %d", b);
printf("\nローカル変数xの値 : %d", x);
printf("\nローカル静的変数yのデフォルト値 : %d", y);
printf("\nローカル変数zの値 : %d", z);

注意:通常のローカル変数は初期化されない

ここで重要な注意点があります。静的変数やグローバル変数と異なり、通常のローカル変数(自動変数)は初期化が保証されません。ローカル変数xの値は不定(未定義動作)であり、実行環境によっては0以外のゴミ値が入る可能性があります。サンプルの出力でxが0になっているのは偶然であり、保証された動作ではない点に留意してください。安全なコードを書くためには、ローカル変数は必ず明示的に初期化することが推奨されます。

  1. C++のローカル変数とグローバル変数はデフォルトでどのように初期化されるのか?

    C++における変数の初期化には、ローカル変数とグローバル変数のどちらにも共通する重要なルールがあります。基本的に、変数を宣言すると、明示的に指定しない限り、コンパイラがそのデフォルトコンストラクタを呼び出します。言語レベルの型(組み込み型)の場合ポインタ、int、float、bool などの言語レベルの型(プリミティブ型)の場合、その「デフォルトコンストラクタ」は実質何もしません。宣言された時点でメモリの内容はそのまま放置されます。つまり、これらの変数にはほぼ何でも入り得ます。なぜなら、そのメモリ領域に以前何が格納されていたのか、あるいはそのメモリ自体がどこから確保されたものなのか、通常は保証

  2. Javaのインターフェース変数が暗黙的にstaticかつfinalになる理由を解説

    Javaにおいて、インターフェース内で宣言された変数は、明示的に修飾子を指定しなくても、自動的に public static final として扱われます。なぜこのような仕様になっているのか、その理由を詳しく見ていきましょう。 インターフェースとは何か インターフェースは「振る舞いのプロトコル(契約)」を定義するものであり、具体的な実装方法を規定するものではありません。インターフェースを実装するクラスは、そのインターフェースで定められたプロトコルに従うことを約束します。 つまり、インターフェースはオブジェクトの設計図としての役割を持ち、実装の詳細ではなく「何ができるか」を宣言する場所です。こ