8

Perl と少しの C を試した後、C++ を学ぼうとしていますが、すでに詳細と落とし穴に行き詰まっています。このことを考慮:-

int x = 1;
{ 
  int x = x; // garbage value of x
}
int const arr = 3;
{ 
  int arr[arr]; // i am told this is perfectly valid and declares an array of 3 ints !! 
} 

え、なんで違うの?

明確にするために: 同じ名前の使用が有効な場合と無効な場合があります。

4

2 に答える 2

14

C++ の世界へようこそ! あなたの質問の答えは、「宣言のポイント」と呼ばれる概念にありました。

>>int x = 1;
>>{ int x = x; }  // garbage value of x

セクションから:-3.3.1.1 (C++ 標準ドラフト) 名前の宣言のポイントは、完全な宣言子の直後で、初期化子 (存在する場合) の前です。ただし、以下に示す場合を除きます。

int x = 12;
{ int x = x; }

ここ; 「演算子 =」は初期化子です。「x」の宣言ポイントにはまだ達していないため、「x」の値は不確定であると言えます。

>>int const arr = 3;
>>{ int arr[arr]; } // i am told this is perfectly valid and declares an array of 3 ints !!

なんで?セクションから:-3.3.1.4 (C++ 標準ドラフト) 非ローカル名は、それを隠すローカル名の宣言の時点まで表示されたままになります。ここで、宣言のポイントは ';' に達します。キャラクター。したがって、「arr」の以前に表示された値、つまり = 3 が使用されます。

また、以下が有効であることを知りたい場合があります:-

const int e = 2;
{ enum { e = e }; } // enum e = 2

セクションから:-Chapter-3.3.1.4 (C++ 標準ドラフト):- 列挙子の宣言のポイントは、その列挙子定義の直後です。

しかし、これをしないでください

const int Spades = 1, Clubs = 2, Hearts = 3, Diamonds = 4;
enum Suits
{
  Spades = Spades,     // error
  Clubs,               // error
  Hearts,              // error
  Diamonds             // error
};

なんで?列挙子は、列挙の外側のスコープにエクスポートされるためです。上記の例では、列挙子 Spades、Clubs、Hearts、および Diamonds が宣言されています。列挙子は外側のスコープにエクスポートされるため、グローバル スコープを持つと見なされます。この例の識別子は、グローバル スコープで既に定義されています。そのため、エラーです。

追加の詳細と落とし穴 ( :-) ) については、ドラフト C++ 標準のセクション 3.3「宣言領域とスコープ」を参照してください。興味がある場合は、ここから pdf を入手できます( http://www.research.att .com/~bs/SC22-N-4411.pdf )。

于 2009-09-02T07:29:53.187 に答える
7

まず、現実の世界では混乱を招くため、どちらも使用しないでください。また、この細かい点を理解するのに数秒でも無駄です。

私の答えの残りを破棄します-Abhayはすでにそれを正しく理解しており、さらに詳細に:)

于 2009-09-02T07:37:12.173 に答える