web-dev-qa-db-ja.com

C ++での変数の初期化

私の理解では、int変数は0に自動的に初期化されます。ただし、そうではありません。以下のコードは、ランダムな値を出力します。

int main () 
{   
    int a[10];
    int i;
    cout << i << endl;
    for(int i = 0; i < 10; i++)
        cout << a[i] << " ";
    return 0;
}
  • 初期化にはどのようなルールが適用されますか?
  • 具体的には、変数はどのような条件下で自動的に初期化されますか?
41
skydoor

次の場合に自動的に初期化されます

  • デフォルトのコンストラクターがすべてのプリミティブ型を初期化するクラス/構造体インスタンスです。お気に入り MyClass instance;
  • 配列初期化構文を使用します。 int a[10] = {}(すべてゼロ)またはint a[10] = {1,2};(最初の2つの項目を除くすべてゼロ:a[0] == 1およびa[1] == 2
  • 同じことは、非集約クラス/構造体にも適用されます。 MyClassインスタンス= {}; (これに関する詳細情報は here にあります)
  • グローバル/外部変数です
  • 変数はstaticに定義されます(関数内またはグローバル/ネームスペーススコープ内であっても)-Jerryに感謝

自動的に初期化されるプレーンタイプ(int、longなど)の変数を信頼しないでください! C#などの言語で発生する可能性がありますが、CおよびC++では発生しません。

67
AndiDog

intはゼロに初期化されません。 int i;と言うとき、あなたがしているのは整数用のスペースを確保することだけです。その場所の値は初期化されません。 int i = 0;(またはint i = 5;(この場合、値は5に初期化されます)と言うだけで完了です。いずれにしても、変数を既知の値に初期化することをお勧めします。それ以外の場合、iは、スペースが予約されたときにそのメモリ位置にあったランダムな値を保持します。これがcoutがランダムな値を出力する理由です。

デフォルト値は、言語の実装に依存します。一部の言語では、「正気」の値(おそらく0など)に初期化されます。経験則として、私は常に変数を適切な値に初期化します(使用する前に他の何かに初期化することを知っている場合を除き確かに)。前述したように、assumeが値が正気になることは賢明ではありません。 (言語、またはその言語のインタープリター/コンパイラーの実装に応じて)異なる場合があります。

11
Vivin Paliath

セクション4.9.5 C++プログラミング言語の初期化を参照してください。

変数がローカルであるか、静的であるか、ユーザー定義であるか、constであるかに応じて、デフォルトの初期化が行われます。

POD(Plain Old Datatypes)を使用しているため、auto変数はデフォルト値に初期化されません。

5
Nick Presta

この投稿はそれを最もよく言っています: http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=1

非クラス型には「デフォルト」コンストラクターはありませんが、デフォルト(ゼロ)初期化があります。残念ながら、Cとのブレインデッド互換性のために、デフォルトの初期化は次の状況でPODタイプに対して行われません:

クラスまたは関数にローカルな裸の(つまり、初期化子なしで宣言された)変数。

動的に割り当てられたインスタンス。

ただし、他の場所(特に静的変数)および空の初期化パラメーターが指定されている場合(有効な場合)、デフォルト(ゼロ)の初期化を取得します。

4
Will

POD(これはintがそうです)の初期化を強制するには、コピー初期化構文を使用できます:

#include <iostream>

int main() {
  int i = int();
  int j;

  std::cout << "i: " << i << std::endl;
  // warning: undefined behavior
  std::cout << "j: " << j << std::endl;
}

これは、「使用したものに対してのみ支払う」に該当します。後で変数に値を割り当てる場合、またはまったく使用しない場合は、初期化する作業を行う理由はありません。それを得るには、その作業を行うよう明示的に依頼する必要があります。

4
Logan Capaldo

C++では、明示的に値が与えられるまで、自動変数は未定義です。おそらく、C#または他の.Net言語、またはJavaを考えています。

3
Jakob Borg

異なるオペレーティングシステム(つまり、OS XとUbuntu Linux)は、C++の初期化されていない変数と初期化された変数に対して異なる反応を示します。私の経験では、gccのOS Xバージョンは、以下のコードの両方のバージョンに対して2をコンパイルして出力します。 Ubuntu Linuxマシンで作業している場合と同様に、最初のコードブロックは、変数が参照するメモリ位置で発生したものをすべて出力します(ループ後の+ 2)。

    int c;

    for( int i = 0; i < 3; i++ )
    {
        c++;
    }

    cout << c << endl; 

どこで、それらはすべてあなたに同じ結果を与えます:

    int c = 0;

    for( int i = 0; i < 3; i++ )
    {
        c++;
    }

    cout << c << endl; 
3
t. fochtman

ローカル変数は、自分で実行しない限り初期化されません。表示されているのは、メソッドが呼び出される前にスタックにあったゴミです。

2
Anon.

オブジェクトに初期化子が指定されていない場合、オブジェクトはデフォルトで初期化されます。初期化が実行されない場合、自動または動的ストレージ期間を持つオブジェクトは不定の値を持ちます。

パー。 8.5、最近のC++ 0xドラフトN3092.pdfのセクション11、

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/

2
eel ghEEz

最近の発見は好ましくないかもしれませんが(他の言語が処理する変数を初期化する必要があるかもしれません)、CPUサイクルが少なくなり、コードが高速になります。

0
phlip