声明:听其言(extern、以及类的前向声明 forward declaration),定义:观其行;
1. 变量
从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存。而定义就是分配了内存(存在客观上的实物)。
考虑下面的代码:
void func() {
int a;
int b = 1;
a = 0;
}
对于第一行代码,编译器不会做任何事?(仅仅是被通知存在 a 这样的一个变量而已),它不会为它在栈中分配一点东西,直到第三句,a = 0; 时,编译器才会将其压入栈中。而对于 int b=0; 这一句,编译器就会生成一条指令,为它赋值。可通过反汇编查看。
编译器也有可能在声明 int a时,编译器就会把一个废值入栈,到第三条再为其赋值,这要看编译器的具体取舍,所以,声明不一定不是定义,而定义一定是定义。但是,下面的声明,一定仅仅是声明:
extern int a;
// 声称(告诉编译器)其他存在一个变量 a,(当然编译器也不会为它做任何分配内存的事)
// 功能类似于类的前向声明,forward declaration
尤其注意全局变量,虽然有时也可以像在函数的局部变量那样,仅仅看似是声明的形式,但编译器仍然会对其进行初始化(默认初始化方式),能够被初始化,显然占据着一定的内存空间。
int a;
// 是定义,默认初始化为 0
int main() {
return 0;
}
2. 更准确地说明
int a;
是一种定义型声明(defining declaration),其实就是定义编译器已经分配了空间,如果连写 2 个 int a; int a;(vs 好像编译通过,运行不通过),
extern int a;
这才是一个纯正的标准的声明,C++允许多个声明同名同类型,试试 extern int a; extern int a; 定义就不行。
3. 函数
声明:一般在头文件里,对编译器说:这里我有一个函数叫 function() 让编译器知道这个函数的存在;
定义:一般在源文件里,具体就是函数的实现过程写明函数体;