变量的定义分配了变量的存储空间,并有可能赋一个初始值给变量,在程序中变量只能定义一次; (如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.第二种情况:
//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;
}
上面第二个程序,main函数内自己再定义一个int t=3,不会出错,因为内部的定义会屏蔽外部(全局)的定义
extern还可以声明函数,具体用法和声明变量一样
二、也可在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声明