我们有两个文件,foo.c和bar.c。
这是foo.c
#include <stdio.h>volatile unsigned int stop_now = 0;extern void bar_function(void);int main(void){
while (1) {
bar_function();
stop_now = 1;
}
return 0;}
现在,这里是bar.c
#include <stdio.h>extern volatile unsigned int stop_now;void bar_function(void){
while (! stop_now) {
printf("Hello, world!\n");
sleep(30);
}}
正如您所看到的,我们在foo.c和bar.c之间没有共享的头,但是bar.c在链接时需要在foo.c中声明一些东西,而foo.c在链接时需要来自bar.c的函数。
通过使用“extern”,您是在告诉编译器,在链接时将找到任何跟随它的东西(非静态的);不要在当前传递中为它保留任何东西,因为以后会遇到它。在这方面,函数和变量受到平等对待。
如果您需要在模块之间共享一些全局的,并且不想将它放在/初始化一个头中,那么它是非常有用的。
从技术上讲,库公共头中的每个函数都是“extern”,但是根据编译器的不同,将它们标记为“extern”几乎没有什么好处。大多数编译器可以自己解决这个问题。正如您所看到的,这些函数实际上是在其他地方定义的。
在上面的示例中,main()只打印Hello World一次,但是继续输入bar_function()。还请注意,在这个示例中,bar_function()不会返回(因为它只是一个简单的示例)。想象一下,当信号被服务(因此是易失性的)时,STOP_NOW被修改,如果这看起来不够实用的话。
Externs对于诸如信号处理程序、不想放入头或结构等的互斥对象非常有用。大多数编译器将进行优化,以确保它们不为外部对象保留任何内存,因为它们知道它们将在定义对象的模块中保留它。然而,在构建公共函数的原型时,用现代编译器来指定它也没有什么意义。
希望有帮助:)