我来说一下,具体原因应该是这个,常变量在定义的时候必须初始化,所以当你在a.cpp中定义extern const double pi=3.14; b.pp中extern const double pi;可以通过编译运行。因为当编译系统发现a.cpp中的全局常变量时,就知道它pi是常量,而换过来的时候,在a.cpp中定义const double pi=3.14; b.pp中extern const double pi;编译系统在编译a.cpp是没有问题的,但到了b.cpp中就会发现,有一个外部常量是没有初始化的,而常量是不能在声明后再进行定义的,所以编译系统会认为找不到它的定义,所以就出错。
对于extern "C"主要是因为c和c++编译器不同,它们对相同的函数名编译后生成的相同的标示不同,故而在引用c的库文件时必须使用extern “C”告诉编译器,它是c的函数,按c的规则编译。通常我们使用的标准头文件已被处理过。 貌似没有用于常量的声明。
转给你个详细的东西:
用例子给你示范
// 1.cpp
int x = 10;
// 2.cpp 注意没有包含1.cpp
#include
using namespace std;
extern int x;
int main ()
{ cout << x << endl; }
//则输出10
两个文件同在一个项目(project)中,你不包含某个文件(cpp)而可以用它内部定义的变量,(里是.pp不是.h, 因为在.h中定义的数据不能在.cpp中用除非这个.cpp包含这个.h文件)
例:
// 1.h
#include
void print()
{
std::cout << "hello!" << std::endl;
}
// 2.cpp
#include
using namespace std;
// 以上两句在这个例子中可以不要
extern void print();
int main ()
{
print();
}
就会出错因为1.h中的void print();在不包含它的文件中是不可调用的,即使在声明了extern 也于事无补,如果你将这个例子中的1.h名字换成1.cpp就对了!
从这些可以看出来,extern在这里起的作用是告诉编译器,你这个print()已经在某个.cpp中已经定义了,这里只不过是声明一下有这个东西,然后拿来用一下。定义只能出现一次,声明却可出现多次,也就是说extern声明可在多个文件中用(包括.h)
还有,你还可以屏蔽extern声明,如第二个例子中的第二个.cpp文件可以改成
#include
using namespace std;
// 这里以上两句不能省略,因为,这里extern void print();函数已经不起作用了,在这里调用的而是本文件中定义的void print()函数,其中用到了cout,endl;他们来源于std::
extern void print();
void print()
{
cout << "world!" << endl;
}
int main ()
{
print();
}
// 输出结果为world!
还有一个extern "C"就不用说了,用这个可以允许C++程序中调用C的函数
在a.cpp中定义extern const double pi=3.14; b.pp中extern const double pi;可以通过编译运行。在a.cpp中定义const double pi=3.14; b.pp中extern const double pi;编译失败。
没有看懂!
变量用extern 表示外部变量。后面没有赋值表示引用其它地方的,叫声明变量,有赋值就是定义一个全局变量与不用extern是一样的。extern "C"加在变量前没有什么意义,函数才有意义。C语言的函数是加下划线到函数名前,如定义一个void func(),实际的函数名就是_func,C++的就很复杂了,而且不同的编译器也不一样,主要是要处理函数重载,它会把参数的类型通过一个的命名规则把它加到函数名上去,加上extern "C"可以强制它与C语言的命名规则来处理。没有什么谁比谁规范的。
对于c++的全局变量声明问题:
在一个源文件中比如a.cpp中,可以在全局作用域中随意定义一个比如:int nData = 0;
要在另外一个比如b.cpp中对此变量进行引用可以这样声明extern int nData;
在c++中const有限定变量作用域的作用,它限制变量只在本编译单元内可以使用,你第一次之所以能够成功,是因为加了extern