您需要区分两个单独的概念:函数定义和符号声明。“ extern”是一个链接修饰符,它是向编译器提供的有关后面定义的符号定义位置的提示(提示是“ not here”)。
如果我写
extern int i;
在C文件的文件范围(功能块外部)中,则表示“变量可以在其他位置定义”。
extern int f() {return 0;}
既是函数f的声明,也是函数f的定义。在这种情况下,定义优先于外部。
extern int f();
int f() {return 0;}
首先是一个声明,然后是定义。
extern
如果要声明并同时定义文件范围变量,则使用错误。例如,
extern int i = 4;
将给出错误或警告,具体取决于编译器。
extern
如果您明确希望避免定义变量,则使用很有用。
让我解释:
假设文件ac包含:
#include "a.h"
int i = 2;
int f() { i++; return i;}
文件啊包括:
extern int i;
int f(void);
并且文件bc包含:
#include <stdio.h>
#include "a.h"
int main(void){
printf("%d\n", f());
return 0;
}
标头中的extern很有用,因为它在链接阶段告诉编译器“这是一个声明,而不是定义”。如果删除ac中定义i的行,为其分配空间并为其分配值,则程序应无法使用未定义的引用进行编译。这告诉开发人员他已经引用了变量,但尚未定义它。另一方面,如果我省略了“ extern”关键字,并删除了该int i = 2
行,则程序仍会编译-我将使用默认值0进行定义。
如果未为文件作用域变量明确赋值,则隐式定义为默认值0或NULL-与在函数顶部声明的块作用域变量不同。extern关键字避免了此隐式定义,从而有助于避免错误。
对于函数,在函数声明中,关键字确实是多余的。函数声明没有隐式定义。