全局变量和extern变量有什么区别?

3
    #include <stdio.h>

    int i;

    int main()

    {

        extern int i;

        if (i == 0)

            printf("scope rules\n");

    }

输出: 作用域规则

外部变量在这里如何工作?

为什么没有像“由于多次声明导致编译时错误”这样的错误?


2
点击这里阅读《理解C语言中的extern关键字》的文章。 - Maroun
请参考@Jonathan Leffler的答案,了解有关extern变量的更好解释https://dev59.com/d3M_5IYBdhLWcg3wThR3 - yat0
2个回答

9

extern并不实际创建变量。它类似于类的前向声明或函数的原型。在起始处,变量"i"创建了一个名为"i"的全局整数,在当前编译单元中存在;而在"int main"下面的"i"是一个声明,表示某个编译单元中存在一个名为"i"的整数,使用"i"名称的任何用法都指向该变量。


5
因为你可以尽可能多次地声明某个东西的存在(只要类型每次都相同),但你只能定义它一次。 extern int i是一个声明,表示i存在,并且是一个int类型。 i存在于文件级别(头文件后面的int i),具有静态存储期。这意味着它被初始化为零,因此您将始终看到输出"scope rules"
声明/定义的区别是微妙的概念,但每个C编程人员最终都应该学好。

@Eric,我的“只要每次类型相同”这句话没有涵盖到吗?如果有更好的建议让它更清晰明了,我非常乐意听取。也许可以通过在第一句话中澄清“something”的定义来说明名称和类型都很重要。 - paxdiablo
我认为没有办法澄清这个问题。我已经删除了我的评论,因为C标准在多个地方以一种方式引用标识符,这意味着标识符只是组成它的字符字符串;无论它是在文件作用域还是块作用域中,它都是相同的标识符。但标准并不一致。在C 2011 6.2.1 4中,它说“每个其他标识符的作用域由其声明的位置确定...”。但显然,在这个例子中的i并没有仅有一个作用域。它是一个具有作用域的声明;标识符具有独立的存在。 - Eric Postpischil
然后有C 2011 6.2.1 5,它说:“除非明确说明,在这个国际标准使用术语“标识符”来引用某个实体(而不是语法结构)时,它指的是在标识符出现点可见的相关名称空间中的声明实体。”所以也许我不应该删除我的评论。此外,根据6.2.7 4,声明不必每次都指定相同的类型;声明可以提供额外的信息,标识符的类型成为两个声明的组合。 - Eric Postpischil
所以,这一切都非常复杂,哦,好吧。 - Eric Postpischil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接