-
第一个文件 叫 add.cpp ,里面定义了一个加法函数,
而另一个主函数文件里要引用这个加法函数,该怎么声明呢,我第一反应是
extern int add(int,int); 经过测试这是可以的。但不加这个extern关键字照样可以。也就是说如下,
我们在主函数文件test_extern_declar.cpp里要引用,就必须加extern int x;来声明
因为,如果不加extern,就成了 int n;
这就直接由声明并定义了一个变量 int n,到时候两个文件一起编译的时候就会出现重复定义的错误。(C语言会有不同,int n 默认的链接属性是external, 当多处出现identifier n时,实际上指向同一个变量实体。C++对这种文件内的 int n 都认为是一个定义,因此多处定义就会在链接时出现 重复定义错误。另外,关键字extern 和static 用于在声明中修改identifier的链接属性)
而声明外部函数为什么不用加extern呢,因为函数的声明和定义语法上明显不一样,而变量的声明和定义很难区分开,除非加上extern关键字 explicitly声明外部的变量,而不是自己再定义一个。
再看一种情况,
看到没,即使用extern 声明了一个变量 int n, 但不排除你还可以在本文件内定义这个变量,也就是
extern 关键字,告诉编译器 int n 这个变量可能在外面某个文件里定义,也可能在本文件内定义。
最后一句话,无论以什么方式声明一个函数或者变量后,只要一旦在函数中引用,(不引用的话有没有定义都没关系),
这时,编译器会在链接阶段从全局目标文件去寻找定义,包括本文件内!
另外 关于 extern "C" 这样的声明,只能在cpp文件里使用,c编译器不认识这个语法。而且这里的extern 关键字 和前面说的extern 完全是两个概念。这里的extern不是外部的意思,而是链接指示符linking specification。告诉C++编译器,这个函数生成符号的时候按照C语言的方式,这样为了便于,外部C语言函数调用C++函数,(完全相同的函数,C编译器和C++编译器生成的符号是不一样,这点不懂的朋友,可以稍微补习一下功课)
总结,在 .c 文件里定义的函数 int add(int a,int b) { returna+b;}
如果想在 .cpp 文件里引用,即 C++语言 调用C语言 函数,只要在 .cpp 文件的头部声明一下这个函数
extern "C" int add(int,int); 就可以引用了,
在 .cpp 文件里定义的函数 int add(int a,int b) {return a+b;},
如果想被 .c 文件里的C语言函数调用,即 C语言函数调用 C++语言 函数,只要在 .cpp 文件里重新定义为C语言格式的,在函数定义前 加上 extern "C"int add(int a,int b) {returna+b;} 也就是,为了方便C语言调用C++语言函数,就要在
.cpp 文件里用链接指示符告诉C++编译器,按照C语言格式处理这个函数的名字(符号)吧,将来方便我兄弟(C语言)来调用我这个函数!
This is it !
extern int add(int,int); 经过测试这是可以的。但不加这个extern关键字照样可以。也就是说如下,
int add(int,int);
后面就可以直接引用了int main()
{
return add(4,5);
}
而假如我们在add.cpp 里定义了一个全局变量,int x = 5;我们在主函数文件test_extern_declar.cpp里要引用,就必须加extern int x;来声明
因为,如果不加extern,就成了 int n;
这就直接由声明并定义了一个变量 int n,到时候两个文件一起编译的时候就会出现重复定义的错误。(C语言会有不同,int n 默认的链接属性是external, 当多处出现identifier n时,实际上指向同一个变量实体。C++对这种文件内的 int n 都认为是一个定义,因此多处定义就会在链接时出现 重复定义错误。另外,关键字extern 和static 用于在声明中修改identifier的链接属性)
而声明外部函数为什么不用加extern呢,因为函数的声明和定义语法上明显不一样,而变量的声明和定义很难区分开,除非加上extern关键字 explicitly声明外部的变量,而不是自己再定义一个。
2. 再进一步,我们接下来的讨论都是针对一个文件test_extern_declar.cpp
#include<iostream.h>
using namespacestd;
extern int add(int,int);
int main(int argc, char*argv[])
{
cout<<add(4,5);
return 0;
}
int add(int a,int b)
{
return a+b;
}
函数声明前虽然加了extern,但依然定义在自己本文件内,照样可以。再看一种情况,
#include <iostream.h>
using namespace std;
extern int n;
int n =5;
int main(int argc, char *argv[])
{
cout<<n;
return0;
}
照样编译运行正常。看到没,即使用extern 声明了一个变量 int n, 但不排除你还可以在本文件内定义这个变量,也就是
extern 关键字,告诉编译器 int n 这个变量可能在外面某个文件里定义,也可能在本文件内定义。
最后一句话,无论以什么方式声明一个函数或者变量后,只要一旦在函数中引用,(不引用的话有没有定义都没关系),
这时,编译器会在链接阶段从全局目标文件去寻找定义,包括本文件内!
另外 关于 extern "C"
总结,在
如果想在 .cpp 文件里引用,即 C++语言 调用C语言 函数,只要在 .cpp 文件的头部声明一下这个函数
extern "C" int add(int,int);
在
如果想被 .c 文件里的C语言函数调用,即 C语言函数调用 C++语言 函数,只要在 .cpp 文件里重新定义为C语言格式的,在函数定义前 加上 extern "C"int