extern关键字对函数和变量的区别
extern 关键字适用于C变量(数据结构)和C函数。根本上来说,extern关键字扩展了C变量和C函数的可见性。这可能就是它被命名为extern的原因。
虽然大多数人可能理解变量或函数的“声明”和“定义”之间的区别,但为了完整起见,还是区分一下它们。
变量或函数可以 声明任意多次 ,但只能 定义一次 。(记住一个基本原则,即同一个变量或函数不能有两个位置)。
现在回到关键字 extern 。首先,我们考虑一下 extern 在函数中的使用。事实上,在声明或定义 函数 时,会隐式地假定 extern 关键字。当我们写:
编译器会将其视为:
由于 extern 关键字将函数的可见性扩展到了整个程序,因此可以在整个程序(项目)的任何文件中使用(调用)函数,只要这些文件包含了函数的声明。(函数声明就绪后,编译器就知道函数的定义存在于其他地方,然后继续编译文件)。这就是关于extern和函数的所有内容。
现在我们考虑extern和变量的使用。首先,如何在不定义变量的情况下声明变量?你可以这样做:
这里声明了一个名为 var 的整型变量(但是还没有定义它,所以到目前为止还没有为var分配内存)。我们想做多少次声明都可以。
如何定义var呢?你可以这样做:
在这一行中,一个名为var的整型变量被 声明和定义 (请记住定义是声明的超集)。因为这是一个定义,所以也为var分配了内存。
所以,区别来了。当我们声明/定义一个函数时,我们看到extern关键字隐式地出现了。但这不是变量的情况。想一下如果是,则永远不会为它们分配内存(后面针对var的内容都是使用它了)。因此,当我们希望 声明变量而不定义它们 时,需要显式地包含extern关键字。此外,由于extern关键字扩展了整个程序的可见性,通过在变量中使用extern关键字,只要包含了变量的声明(该变量在某一处定义),就可以在当前程序中的任何地方使用该变量。
现在我们用例子来理解extern。
示例1:
该程序会编译成功。var是全局定义(和隐式声明)的。
示例2:
该程序会编译成功。这里只声明var。但var从未使用过,所以不会出现问题。
示例3:
这个程序在编译时会抛出一个错误(链接错误),因为var没有在任何地方定义。实际上,var没有被分配任何内存,但程序试图将一个根本不存在的变量的值改为10。
示例4:
假设somefile.h包含var的定义,这个程序将成功编译。
例5:
你认为这个程序会编译成功吗?
这是C语言标准中的一个内容,如果一个变量只是被声明并且同时又被初始化了,那么该变量的内存也将被分配——换句话说,该变量将被认为是已定义的。因此,按照C语言标准,这个程序可以顺利编译并正常执行。
这就是C中extern关键字的一些补充介绍。
简单总结: