在尝试了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 !!
}
嗯,为什么会有区别?
澄清:使用相同名称在一种情况下有效,在另一种情况下无效。
答案 0 :(得分:14)
欢迎来到C ++世界! 对于您的问题,答案在于一个名为“声明点”的概念。
>>int x = 1;
>>{ int x = x; } // garbage value of x
来自章节:-3.3.1.1(C ++标准草案) 声明的声明就在其完整的声明者之后和初始化者之前(如果有的话),除非如下所述。
int x = 12;
{ int x = x; }
下面; 'operator ='是初始化程序。你可以说'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'的早期可见值,即= =。
此外,您可能希望知道以下内容有效: -
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
};
为什么呢?因为枚举数被导出到枚举的封闭范围。在上面的例子中,宣布了调查员黑桃,俱乐部,心和钻石。因为枚举数被导出到封闭范围,所以它们被认为具有全局范围。示例中的标识符已在全局范围内定义。所以这是一个错误。
有关其他细节和陷阱(:-)),请阅读C ++标准草案第3.3节“声明性区域和范围”,如果感兴趣,您可以从here获取pdf({{ 3}})。
答案 1 :(得分:7)
首先,在现实世界中你不应该使用它,因为它很混乱,甚至几秒钟来理解这个细节也太浪费了。
废弃我的其余答案 - Abhay已经把它弄好了,而且更详细:)