原文链接:http://blog.csdn.net/hangyu628/article/details/3854487
变量的定义分配了变量的存储空间,并有可能赋一个初始值给变量,在程序中变量只能定义一次; (如int i; 或 int i=1;)变量的声明主要声明了变量名和变量类型,没有分配空间定义也是一种声明。当在定义一个变量时,我们指出了其名称与类型。我们不能没定义一个变量就使用extern来声明它,在程序中可以声明多次。 (如extern int i; extern int i;).
只要声明存在初始值,就被认为定义,不管是否有extern(例:extern int i=2是定义)
----引用自:C++primer:还有一点全局变量默认编译器会自动为其赋值为0,而局部变量必须手动赋值
一、一般情况,在a.cpp定义一个t,然后在a_pub.h用extern声明它,在b.cpp include a_pub.h使用,如下情况
1.第一种情况:编译出错
//Out_pub.h extern int t=1; //属于定义 //Out.cpp int t; //定义一个全局变量,默认值为0,也可以改:int t=1; //test.cpp #include <iostream> #include "Out_pub.h" int main() { std::cout<<t<<std::endl; return 0; }
2.第二种情况:
上面第二个程序,main函数内自己再定义一个int t=3,不会出错,因为内部的定义会屏蔽外部(全局)的定义extern还可以声明函数,具体用法和声明变量一样
//Out_pub.h extern int t; //属于声明,可以有多个声明 extern int t; //多加几个也正常. //Out.cpp int t; //定义一个全局变量,默认值为0,也可以改:int t=1; //test.cpp #include <iostream> #include "Out_pub.h" int main() { std::cout<<t<<std::endl; return 0; }
二、也可在a.cpp定义,直接在b.cpp引用它,如下情况
//Out.cpp int t; //定义一个全局变量,默认值为0,也可以改:int t=1; //test.cpp #include <iostream> extern int t; //声明一个外部的,若改为extern int i=2; 则重定义 int main() { std::cout<<t<<std::endl; return 0; }
三、extern的另一个用法:用于C++编译器,来编译extern的C函数时,出现问题的。
原因,C++为了解决多态,会将函数名与参数合一起生成中间函数,此时若用C,也生成中间函数,所以编译时会出错
例:
//Out.h #ifdef __cplusplus //该段代码引用网上的..., extern "C"{ #endif #include <stdio.h> //若 Out.h里 直接#include <stdio.h> extern void aa();// extern void aa(); //出错:unresolved external symbol "void __cdecl aa(void)" (?aa@@YAXXZ),在VC6调试结果 #ifdef __cplusplus } #endif //Out.c #include "Out.h" void aa() { printf("aa is running"); } //Test.cpp #include <iostream> using namespace std; #include "Out.h" int main() { aa(); return 0; }
四、const默认是局部变量,即使是在全局中申明也一样,且在定义时,必须赋予初值。若想在外部引用,必须加extern
例子:
//a.cpp extern const int a=100; //b.cpp extern const int a; //引用a.cpp中的
const 之所以放于head文件,且默认为局部变量:编译时,const变量将被常量表达式所替代。不存储任何空间为const变量。而若const变量不是用常量表达式所初始化的话,则不应该定义在head,而应该定义在cpp,然后用extern在head声明