简介
extern 是一个关键字,可以放置于变量或函数前,以表示变量或函数的定义在别的文件中。提示编译器遇到此变量或函数时,在其他模块中寻找其定义。extern 也可以来进行链接指定。
简言之,extern 有以下特点:
- 当变量或函数具有外部链接时使用 extern 声明符。
- extern 是声明并非定义,可以用于声明变量、函数。
- extern “C” 用于 C++ 中,用于将 C++ 的一些代码用 C 语言的方式进行编译。
正文
那么现在用一些实例来说明:
test.c文件中:
int a = 10;
void test1(){
printf("%s %d\n", __FILE__, a);
}
test2.c文件中:
int a = 10;
void test2()
{
printf("%s %d\n", __FILE__, a);
}
main.c文件中:
void test1();
void test2();
int main()
{
test1();
test2();
system("pause");
return 0;
}
在上面的 test.c 和 test2.c 中,我们分别定义了两个相同的变量 a,此时运行当然不会通过,运行结果如下:
因为一个工程中定义了两个相同的变量,导致不能通过
那么此时将 test.c 中的内容修改为:
extern int a;
void test2()
{
printf("%s %d\n", __FILE__, a);
}
程序将正常执行,执行结果如下:
再将test.c 和 test2.c 中 a 只定义不初始化, main.c 中的内容修改如下:
extern int a = 4;
void test1();
void test2();
int main()
{
test1();
test2();
system("pause");
return 0;
}
输出结果为:
那么综上可见,这些文件中的 a 变量是同一个变量,也就印证了第一条:extern 可以访问其他文件中的变量。同理也可以对函数使用。
此处还需注意,extern 是声明变量,并不是定义,所以并不会给 extern 修饰的变量分配内存空间。
那如果在其中一个文件给变量前加上 static 呢?
static 和 extern 可以说是一对冤家,使用 extern 可以调用其他文件中的变量或者函数,而 static 恰恰相反,static 让本文件的变量或函数不能在别的问件中被调用。就好像爸爸和妈妈一样,static 就像妈妈总是害怕孩子出去受委屈,所以保护孩子不被他人使用。而 extern 就像爸爸一样,想让孩子去外面闯闯一样,所以可以在其他文件中被调用。
extern "C"
extern 还有一个用法,就是在extern “C”,他的具体用处就是在 C++ 工程中使用,使得相应的代码以 C 语言风格进行编译。
那么还是用一些例子进行说明:
首先在我们的 main.cpp 文件中写如下代码:
int Add(int left, int right);
int main()
{
Add(1, 2);
return 0;
}
编译报错如下:
这里括号里的内容(?Add@@YAHHH@Z),这是 C++ 底层命名修饰规则,因此这是以 C++ 的编译规则来编译这段代码的。
那我们再加上 extern “C” 试一试:
extern "C" int Add(int left, int right);
int main()
{
Add(1, 2);
return 0;
}
编译报错如下:
这里的 _Add 是 C 底层的命名修饰规则,足以见得编译器将这段代码以 C 语言编译规则进行编译的。
extern “C” 使用场景:
- 可以修饰单一语句。
extern "C" int Add(int left, int right);
- 可以在后面跟上大括号,修饰括号里的内容。
extern "C"
{
test1();
test2();
}
- 可以修饰头文件,相当于头文件的所有内容都以 C 编译规则进行编译。比如我们自己写的头文件希望用C语言风格来编译,可以将整个头文件用extern "C"来修饰。
extern "C"
{
#include "test.h"
}