我不明白两者的意义。
当前回答
宣言
声明告诉编译器a 程序元素或名称存在。一个 声明引入一个或多个 命名到程序中。声明可以 在一个程序中出现一次以上。 因此,类,结构, 枚举类型等 用户定义的类型可以声明为 每个编译单元。
定义
定义指定哪些代码或数据 名称描述。名称必须为 在使用之前声明。
其他回答
你不能用最一般的术语说,声明是一个没有分配存储空间的标识符,而定义实际上是从声明的标识符分配存储空间吗?
一个有趣的想法是:只有类或函数与类型信息链接起来,模板才能分配存储空间。那么模板标识符是声明还是定义呢?它应该是一个声明,因为没有分配存储空间,您只是在对模板类或函数进行“原型化”。
为了理解声明和定义之间的区别,我们需要查看程序集代码:
uint8_t ui8 = 5; | movb $0x5,-0x45(%rbp)
int i = 5; | movl $0x5,-0x3c(%rbp)
uint32_t ui32 = 5; | movl $0x5,-0x38(%rbp)
uint64_t ui64 = 5; | movq $0x5,-0x10(%rbp)
double doub = 5; | movsd 0x328(%rip),%xmm0 # 0x400a20
movsd %xmm0,-0x8(%rbp)
这只是定义:
ui8 = 5; | movb $0x5,-0x45(%rbp)
i = 5; | movl $0x5,-0x3c(%rbp)
ui32 = 5; | movl $0x5,-0x38(%rbp)
ui64 = 5; | movq $0x5,-0x10(%rbp)
doub = 5; | movsd 0x328(%rip),%xmm0 # 0x400a20
movsd %xmm0,-0x8(%rbp)
正如你所看到的,没有任何变化。
声明与定义不同,因为声明提供的信息仅供编译器使用。例如uint8_t告诉编译器使用asm函数movb。
看到:
uint def; | no instructions
printf("some stuff..."); | [...] callq 0x400450 <printf@plt>
def=5; | movb $0x5,-0x45(%rbp)
声明没有等价的指令,因为它不是要执行的东西。
此外,声明告诉编译器变量的作用域。
我们可以说,声明是编译器用来确定正确使用变量的信息,以及某些内存属于某个变量多长时间。
声明:“在某处,存在一个foo。”
定义:“…就是这儿!”
变量的声明是为了通知编译器以下信息:变量的名称,它持有的值的类型和初始值(如果有的话)。也就是说,声明给出了关于变量属性的详细信息。然而,变量的定义说的是变量存储在哪里。也就是说,变量的内存是在定义变量时分配的。
这听起来很俗气,但这是我能把这些条款直接记在脑子里的最好方法:
宣言:想象托马斯·杰斐逊发表演讲……“我在此声明这个foo在这个源代码中存在!!”
定义:想象一本字典,你正在查找Foo和它的实际意思。