2

我对全局常量有点困惑。我(初级)的理解是“全局”变量是在块之外定义的并且具有程序范围(来源: 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;
}

在 g++(GCC,最新的 64 位版本)中编译没有任何问题,即使使用 -Wall。

输出:

1) x=1.5
2) x=2.5

这让我很困惑。第一个 cout 评估的事实意味着 main 将“x”识别为“全局”变量(它没有在 main 的范围内定义)。如果是这样,为什么它让我重新定义'x'?

然后,如果您取消注释已注释的第三个声明,g++ 会引发重新声明错误。意思是,从我定义的意义上说,我的第一个声明不可能是“全球性的”:S

编辑:好的,问题与全局变量无关,但范围:例如http://pastebin.com/raw.php?i=V5xni19M中的相同问题

4

6 回答 6

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;

在代码中,您已经将一个名为的对象引入xmain(). 该范围嵌套在全局范围内,因此现在您有两个名为 的对象x

  1. x在类型的全局范围内const double

  2. xmain()类型范围内double

局部x隐藏全局x。如果要访问全局x内部main(),可以将其称为::x.

    std::cout << "2) x=" << x << std::endl;
    double x=3.5;  //uncommented

不,您正在尝试将另一个名为x的对象引入main(). 这是不可能的,x该范围内已经有一个,所以它失败了。

于 2013-10-11T14:18:46.513 回答
1

第二个x不是重新定义。它是hiding全球性的x。这是我们在处理继承时特别要注意的事情:

  struct Base 
  {
      void AwesomeFunction() { }
  };

  struct Derived : public Base
  {
      // This definition 'hides' Base::AwesomeFunction
      void AwesomeFunction() { }
  };

仅允许这种隐藏,因为第二个x的范围比 global 小xx由于第三个和第二个x处于同一范围“级别”,因此您会收到第三个重新定义错误。

于 2013-10-11T14:16:54.253 回答
1

使用 ::x 从程序中访问全局变量。现在你正在制作一个局部变量和一个全局变量。当您第一次打印 x 时,它找不到本地的,所以它假设您的意思是全局的。在您制作本地 x 后,它不再默认为全局。

于 2013-10-11T14:16:54.733 回答
1

在您的代码中发生的情况是,如果局部变量具有相同的名称,则它们优先于全局变量。您可以在整个程序的任何块中使用全局变量,而本地变量将在其块(主)的末尾被处理掉。然而,编译器不会让你在一个块中声明两个同名的局部变量。

于 2013-10-11T14:17:05.920 回答
1

允许内部范围(如 main)的声明隐藏外部范围(如文件范围)的声明。您对 x 的第三个声明与您的第二个声明的范围相同,因此这是一个重新声明错误。

于 2013-10-11T14:17:14.577 回答
1

您没有重新定义全局变量;您正在定义一个具有相同名称的单独局部变量。

C++ 允许您重用一个名称来在更窄的范围内声明其他内容,例如:从技术上讲,内部作用域中的声明隐藏了外部作用域中的声明,因此在声明和函数结尾之间,x引用了局部变量。您仍然可以通过使用名称空间限定它来访问全局变量:::x

第三个声明将尝试在同一范围内重用名称,这是不允许的。

于 2013-10-11T14:17:49.957 回答