声明与定义

声明:听其言(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() 让编译器知道这个函数的存在;

  • 定义:一般在源文件里,具体就是函数的实现过程写明函数体;

原文地址:https://www.cnblogs.com/mtcnn/p/9423593.html