一、问题
以下是C语言的程序:
sumaa.h:
extern int sumAA(int a, int b);
sumaa.c:
#include <stdio.h>
#include "sumaa.h"
int sumAA(int a, int b)
{
return a+b;
}
two.h:
void sayBye();
two.c:
#include "two.h"
void sayBye()
{
printf("Bye Bye..");
}
main.c:
#include <stdio.h>
#include "sumaa.h"
#include "two.h"
int main(int, char**){
printf("Hello, from aaa!\n");
printf("Hello, %d \n", sumAA(11, 22));
sayBye();
}
输出结果:
Hello, from aaa!
Hello, 33
Bye Bye..
两个头文件中,一个加了extern关键字,一个没加。但从结果看,两个函数都正常调用了。
那么 extern 到底有什么作用呢?
二、extern作用
在C语言中,extern
关键字用于声明一个函数或变量,表示该函数或变量在程序的其他地方已经定义。当你在一个源文件中使用extern
声明一个函数或变量时,你告诉编译器这个函数或变量的定义存在于其他地方,而不是在当前的源文件中。
在上面的例子中,two.h
中的sayBye
函数声明没有使用extern
关键字,但仍然可以正确调用。这是因为默认情况下,当在头文件中包含函数声明时,它实际上隐式地使用了extern
。所以,即使你没有显式地写extern void sayBye();
,编译器也会将其视为外部链接,因为它知道这是一个函数声明而不是定义。
extern
关键字的主要作用在于:
-
明确性:使用
extern
可以使代码更加明确和易于理解。它明确地告诉编译器和其他程序员,这个函数或变量的定义在其他地方。 -
模块化编程:在大型程序中,
extern
允许我们将函数和变量的定义放在单独的源文件中,从而实现模块化编程。这使得代码更易于维护、测试和重用。 -
控制链接:使用
extern
可以控制符号(函数和变量)的链接。当你在头文件中使用extern
时,你实际上是在告诉编译器不要在当前源文件中创建该符号的定义。如果你忘记了extern
,并且又在头文件中包含了函数或变量的定义,那么每个包含该头文件的源文件都会创建该符号的定义,导致链接错误(称为多重定义)。
此例子中,虽然two.h
中没有显式使用extern
,但因为它是一个函数声明而不是定义,所以程序仍然可以正确编译和链接。然而,为了代码清晰性和遵循良好的编程习惯,许多程序员仍然会在函数声明前加上extern
关键字。