当全局变量和局部变量具有相同名称时访问全局变量

时间:2012-06-08 07:42:16

标签: c extern

我对以下代码有疑问

  #include<stdio.h>
   int i=6;
    int main()
     {
      int i=4;
      {
       extern int i;
       printf("%d",i); //prints 6
      }
      printf("%d",i); //prints 4
     }

我们知道extern关键字表示编译器,变量位于外部。所以问题是extern关键字访问全局i变量而不是主函数内的i变量的原因?我认为必定存在矛盾,因为两个变量都可用作内部括号作为全局变量。那么extern关键字访问函数外部的变量,或者它也访问大括号外的变量。

5 个答案:

答案 0 :(得分:5)

extern并不意味着在当前范围之外,它意味着具有外部链接的对象。自动变量永远不会有外部链接,因此您的声明extern int i不可能引用它。因此它隐藏了它,就像隐藏全局的自动变量一样。

答案 1 :(得分:3)

在打印6的printf之前,您要求编译器使用i之后定义的#include。然后,右大括号告诉编译器extern不再有效,因此它使用i设置为4的范围。

答案 2 :(得分:1)

int i = 4 不是全局变量,如果您尝试访问另一个函数中main的 var i ,编译器将抛出 var的错误我是未宣布的。这段代码说明了这一点。

void func() {
    printf("i is %d\n",i);
}

main() {
    int i=10;
    func();
}

而main之外的i是全局变量,您可以在所有函数中访问它。

答案 3 :(得分:1)

我想你在问你是否正确认为extern int i声明会导致第一个printf解析i4因为int i=4 extern 1}}语句位于声明extern的作用域的父作用域中。

答案是否定的,因此你所看到的行为。函数中的{{1}}声明用于声明外部变量的存在,并且不会解析为 local 变量(声明为 函数内部。)

答案 4 :(得分:1)

/ * Ed Heal所说的* / 然而,我认为最好用另外的例子来说明它。我修改了你的例子做了一点。代码中的注释充分说明了它:

#include <stdio.h>
int i = 6;
int main(void)
{
    int i = 4;
    printf("%d\n", i); /* prints 4 */
    {
        extern int i; /* this i is now "current". */
        printf("%d\n", i); /* prints 6 */
        {
            int *x = &i; /* Save the address of the "old" i,
                          * before making a new one. */
            int i = 32; /* one more i. Becomes the "current" i.*/
            printf("%d\n", i); /* prints 32 */
            printf("%d\n", *x); /* prints 6 - "old" i through a pointer.*/
        }
        /* The "previous" i goes out of scope.
         * That extern one is "current" again. */
        printf("%d\n", i); /* prints 6 again */
    }
    /* That extern i goes out of scope.
     * The only remaining i is now "current". */
    printf("%d\n", i); /* prints 4 again */
    return 0;
}