我对全局常量感到有点困惑。我(初学者级别)的理解是'全局'变量是在块之外定义的并且具有程序范围(来源:http://www.learncpp.com/cpp-tutorial/42-global-variables/)。但该计划:
#include <iostream>
const double x=1.5;
int main(){
std::cout << "1) x=" << x << std::endl;
double x=2.5;
std::cout << "2) x=" << x << std::endl;
//const double x=3.5;
return 0;
}
使用-Wall编译g ++(GCC,最新的64位版本),没有任何问题。
输出:
1) x=1.5
2) x=2.5
这让我感到困惑。第一个cout评估的事实意味着main将'x'识别为'全局'变量(它没有在main的范围中定义)。如果是这样的话,为什么让我重新定义'x'?
然后,如果取消注释注释的第三个声明,g ++会引发重新声明错误。意思是,我的第一个宣言不能是'全球',在我定义的意义上:S
编辑:好的,问题与全局变量无关,但是范围:例如http://pastebin.com/raw.php?i=V5xni19M中的同样问题
答案 0 :(得分:8)
#include <iostream>
const double x=1.5;
在代码的这一点上,全局范围内有一个名为x
的对象,它的类型为const double
。
int main(){
std::cout << "1) x=" << x << std::endl;
此时,仍然只有一个x
可见(全局一个),因此这就是x
所指的名称。
double x=2.5;
在代码的这一点上,您已将名为x
的对象引入main()
的范围。该范围嵌套在全局范围内,因此现在您有两个名为x
的对象:
x
中的 const double
类型为x
main()
本地double
隐藏了全局x
。如果您想访问x
内的全局x
,可以将其称为main()
。
::x
您是否尝试将名为 std::cout << "2) x=" << x << std::endl;
double x=3.5; //uncommented
的另一个对象引入x
的范围。这是不可能的,该范围内已有一个main()
,因此失败。
答案 1 :(得分:1)
第二个x
不是重新定义。全球hiding
为x
。
这是值得关注的事情,特别是在处理继承时:
struct Base
{
void AwesomeFunction() { }
};
struct Derived : public Base
{
// This definition 'hides' Base::AwesomeFunction
void AwesomeFunction() { }
};
仅允许隐藏,因为第二个x
的范围小于全局x
。
你得到第三个x
的redfinition错误,因为第三个和第二个x
处于同一范围'level'。
答案 2 :(得分:1)
使用:: x从程序中访问全局变量。现在你正在创建一个局部变量和一个全局变量。当你第一次打印x时,它找不到本地的,所以它假定你的意思是全局的。制作本地x后,它不再默认为全局。
答案 3 :(得分:1)
代码中发生的情况是,如果局部变量占用相同的名称,则它优先于全局变量。您可以在整个程序的任何块中使用全局变量,而本地变量将在其块(主)的末尾处理。但是,编译器不允许在一个块中声明两个同名的局部变量。
答案 4 :(得分:1)
内部作用域(如main)的声明允许在外部作用域(如文件作用域)中进行 shadow 声明。你的第三个x声明与你的第二个声明的范围相同,因此这是一个重新声明错误。
答案 5 :(得分:1)
你没有重新定义全局变量;你要定义一个具有相同名称的单独局部变量。
C ++允许您重用一个名称来在像这样的较窄范围内声明其他内容;从技术上讲,内部作用域中的声明隐藏外部作用域中的声明,以便在声明和函数结尾之间x
引用局部变量。您仍然可以通过使用其命名空间限定它来访问全局变量:::x
。
第三个声明将尝试在同一范围内重用该名称,这是不允许的。