为了支持 分离式编译(separate compilation) 机制,C++ 语言将声明和定义分开来,声明(declaration) 使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明;而定义(definition) 负责创建与名字关联的实体。
如果要在多个文件中使用同一个变量,就必须将声明和定义分离。
变量定义
变量定义:负责创建与名字关联的实体,用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。
变量定义的基本形式是:首先是类型说明符(type specifier),随后紧跟由一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。列表中每个变量名的类型都由类型说明符指定,定义时还可以为一个或多个变量赋初值:
int sum = 0, value, units_sold = 0;
Sales_item item; // item 的类型是 Sales_item
std::string book("0-201-78345-X")
变量声明
变量声明:用于向程序表明变量的类型和名字。
如果想声明一个变量而非定义它,就必须在变量名前添加关键字 extern
,但不要显示地初始化变量。
任何包含了显式初始化的声明即成为定义。我们能给由 extern
关键字标记的变量赋一个初始值,但是这么做也抵消了 extern
的作用,extern
语句如果包含初始值就不再是声明,而变成定义了。
extern int i; // 声明而不是定义
int j; // 声明,也是定义,未初始化
extern double pi = 3.14159; // 定义
但是只有当 extern
声明位于函数体外部时,才可以被显式初始化。在函数体内部,如果试图初始化一个由 extern
关键字标记的变量,将引发错误。
#include <iostream>
using namespace std;
int main(void)
{
int a; // 定义一个变量, 不初始化
int b = 10; // 定义一个变量, 同时进行初始化
extern int c; // 声明一个外部 extern 的 int 型变量 c
// 引发错误,因为没有对 c 的定义
cout << a << endl;
cout << b << endl;
cout << c << endl;
extern int d = 10; // 引发错误,不允许在函数体内部对 extern 标记的变量进行初始化
return 0;
}
声明和定义的关系
(1)声明告诉编译器,这个变量或函数已经在程序其他地方存在了,所以我正在把这个信息(该变量的类型和名字)告诉你,下面我要调用的时候请放行,但不要分配任何内存空间,因为已经这个步骤在变量或函数定义的地方进行分配了。
而定义就是要求分配内存空间。
(2)定义也是声明,当定义变量时我们声明了它的类型和名字,此时声明和定义是合而为一的。
int iy; // 定义,也是声明
(3)变量在使用前就需要被定义或者声明。变量能且只能被定义一次,但是可以被多次声明。
#include <iostream>
using namespace std;
extern int a;
int main(void)
{
cout << a << endl; // 正常输出 a 的值:10
return 0;
}
int a = 10;