全局变量值不变?

时间:2013-11-06 14:46:05

标签: c++ global-variables

我有一个程序。

   int i=10;
   main()
   {
         extern int i;
         {
                int i=20;
                {
                     const volatile unsigned i=30;
                     printf("%d ",i);
                }
                printf("%d ",i);
          }
          printf("%d\n",i);
   }

输出:30 20 10

当我看到这个程序时,我认为这个程序会出错。因为,我们无法创建具有相同名称的符号(变量)。即使我们在块下创建符号,它也已创建为全局符号。

编译器如何区分具有相同名称的全局符号和本地符号?

7 个答案:

答案 0 :(得分:3)

您将此与One Definition规则混淆,后者基本上指出在单个翻译单元中,单个对象不能具有多于(或少于)一个定义。

但那不是你在这里做的。你正在做的是创建两个碰巧具有相同名称的对象。即使不是一个好主意,这也是语言所允许和明确定义的。

int i=10;
   main()
   {
         {
                int i=20;
                {
                     const volatile unsigned i=30;
                }
          }
   }

在此代码中,您首先将i定义为全局。然后,在块作用域内定义一个名为i的新变量。在该块范围内,本地定义的i 隐藏全局定义的定义。您仍然可以通过::i引用全球定义的那个。

然后在更深的块中定义另一个名为i的变量。这个也隐藏了前两个具有相同名称的变量。

不要写这样的代码。

答案 1 :(得分:1)

  

因为我们无法创建具有相同名称的符号(变量)。

我们可以在不同的范围内声明具有相同名称的变量。

  

编译器如何区分具有相同名称的全局符号和本地符号?

当块内的声明命名为已经可见因为它有文件范围或因为它在封闭块中声明)的标识符时,新声明暂时隐藏旧的,标识符具有新的含义。在块结束时,标识符恢复其旧的含义。

答案 2 :(得分:1)

  

因为,我们无法创建具有相同名称的符号(变量)。

是的,我们可以,只要它们不在同一范围内。如果在这里,一个是在嵌套范围内,那么它会在外部范围内隐藏声明。

  

编译器如何区分具有相同名称的全局符号和本地符号?

首先查看当前块的范围,然后查看包含该块的块,依此类推,直到找到声明或无法在全局命名空间中找到声明。 (在C ++中,由于类范围和命名空间,事情有点复杂;但一般原则是相同的。)

答案 3 :(得分:0)

我认为编译器会构建一个包含名称空间和块的树,并开始在树的给定级别向其根目录搜索非限定名称。

答案 4 :(得分:0)

编译器总是使用最里面的“scope”(这实际上意味着“阻塞”)的声明。

一旦宣布了一个新的,外部的那些是不可访问的(除非你拿了一个指针)。

答案 5 :(得分:0)

块内的变量有自己的范围,即它在块内部保留的内容 因此,如果我们在块之外创建另一个变量(具有相同的名称),它将拥有自己的范围

答案 6 :(得分:0)

  

因为我们无法创建具有相同名称的符号(变量)。

您的内部变量是本地变量,它的优先级高于全局变量。你可以拥有全局和本地,但是在块中有使用的局部变量。