web-dev-qa-db-ja.com

変数の初期化、定義、宣言の違い

question を読んだ後、宣言と定義の違いを知っています。定義は宣言と初期化に等しいということですか?

60
Tony

宣言

宣言は、一般的に、プログラムに新しい名前を導入することを指します。たとえば、「署名」を記述することにより、新しい関数をdeclareできます。

void xyz();

または不完全な型を宣言します:

class klass;
struct ztruct;

最後になりましたが、オブジェクトを宣言するには:

int x;

C++標準では、§3.1/ 1で次のように記述されています。

宣言(7項)は、1つ以上の名前を翻訳単位に導入したり、以前の宣言で導入された名前を再宣言したりする場合があります。

定義

定義は、以前に宣言された名前の定義です(または、定義と宣言の両方にすることもできます)。例えば:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

特に、C++標準では、§3.1/ 1で次のように定義されています。

宣言は、関数の本体(8.4)を指定せずに関数を宣言し、extern指定子(7.1.1)またはlink-specification25(7.5)を含み、初期化子も関数本体も含まない限り、定義です。クラス定義の静的データメンバ(9.2、9.4)、クラス名宣言(9.1)、不透明エヌム宣言(7.2)、テンプレートパラメータ(14.1)、パラメータ-関数定義の宣言子ではない関数宣言子の宣言(8.3.5)、またはtypedef宣言(7.1.3)、エイリアス宣言(7.1.3)、使用宣言(7.3。 3)、static_assert-declaration(7項)、attribute宣言(7項)、empty宣言(7項)、またはusingディレクティブ(7.3.4)。

初期化

初期化とは、構築時の値の「割り当て」を指します。タイプTの汎用オブジェクトの場合、多くの場合、次の形式になります。

T x = i;

ただし、C++では次のようになります。

T x(i);

あるいは:

T x {i};

c ++ 11で。

結論

定義は宣言と初期化に等しいということですか?

場合によります。あなたが話していることについて。たとえば、オブジェクトについて話している場合:

int x;

これは初期化なしの定義です。代わりに、次は初期化を伴う定義です。

int x = 0;

特定のコンテキストでは、「初期化」、「定義」、および「宣言」について話すのは意味がありません。たとえば、関数について話している場合、initializationはあまり意味がありません。

したがって、答えはnoです。定義は、宣言と初期化を自動的に意味するわけではありません。

76
Shoe

宣言は「このことはどこかに存在する」と言っています:

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

定義は「このことはここに存在します;それのためにメモリを作ります」と言います:

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

オブジェクトの定義の時点では初期化はオプションであり、「これはこのことの初期値です」と述べています。

int bar = 0;     // variable
int T::baz = 42; // static member variable

代わりに、宣言の時点で可能な場合があります。

struct T
{
   static int baz = 42;
};

…しかし、それはより複雑な機能に入り込んでいます。

Cの場合、少なくともC11 6.7.5に従って:

宣言は、一連の識別子の解釈と属性を指定します。識別子のdefinitionは、その識別子の宣言です。

  • オブジェクトの場合、ストレージがそのオブジェクト用に予約されます。

  • 関数の場合、関数本体が含まれます。

  • 列挙定数の場合、識別子の(唯一の)宣言です。

  • typedef名の場合、識別子の最初の(または唯一の)宣言です。

C11 6.7.9.8-10に準拠:

初期化子は、オブジェクトに格納されている初期値を指定します...自動ストレージを持つオブジェクトが明示的に初期化されていない場合、その値は不定です。

したがって、大まかに言って、宣言は識別子を導入し、それに関する情報を提供します。変数の場合、定義はその変数にストレージを割り当てる宣言です。

初期化は、オブジェクトに格納される初期値の指定です。これは、明示的にassignに値を最初に指定したときと必ずしも同じではありません。変数は、明示的に値を指定するかどうかにかかわらず、定義時に値を持ちます。値を明示的に指定せず、変数に自動ストレージがある場合、変数には初期値がありますが、その値は不定です。静的ストレージがある場合、型に応じて暗黙的に初期化されます(たとえば、ポインター型はNULLポインターに初期化され、算術型はゼロに初期化されます)。

そのため、次のような初期値を指定せずに自動変数を定義する場合:

int myfunc(void) {
    int myvar;
    ...

あなたはそれを定義しています(したがって、定義は宣言なので、宣言しています)が、初期化はしていません。したがって、定義は宣言と初期化に等しくありません。

4
Paul Griffiths

「つまり、定義は宣言と初期化に等しいことを意味します。」

必ずしも、あなたの宣言は次のように初期化される変数なしであるかもしれません:

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
1
TREMOR