两者的意义都让我无法理解。
定义意味着实际编写的功能,而声明意味着简单地声明函数。例如:
void myfunction(); //this is simple declaration
and
void myfunction()
{
some statement;
}
这是函数myfunction的定义
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)
声明没有等效的指令,因为它不是要执行的内容。
此外,声明告诉编译器变量的作用域。
我们可以说声明是编译器用来确定变量正确使用以及某些内存属于特定变量的时间长度的信息。
经验法则:
声明告诉编译器如何在内存中解释变量的数据。每次访问都需要这个。
定义保留内存以使变量存在。在第一次访问之前,必须恰好发生一次。
声明表示“这个东西在某个地方存在”
int sampleFunc(); // function
extern int car; // variable
定义指“这件事物存在于这里;为其分配内存”
int sampleFunc() {} // function
int car; // variable
初始化是对象定义时的可选项,它表示“这个东西的初始值在这里”:
int car = 0; // variable
你能用最通俗易懂的方式阐述一下声明是指没有分配存储空间的标识符,而定义则实际上从已声明的标识符中分配存储空间吗?
有一个有趣的想法——在类或函数与类型信息链接之前,模板无法分配存储空间。那么模板标识符是声明还是定义呢?它应该是一个声明,因为没有分配存储空间,你只是在“原型设计”模板类或函数。
template<class T> struct foo;
是一个模板声明,这个template<class T> void f();
也是如此。模板定义以同样的方式反映类/函数定义。 (请注意,_模板名称_不是_类型_或_函数名称_。您可以看到其中一个地方是当您无法将模板作为另一个模板的类型参数传递时。如果您想传递模板而不是类型,则需要使用模板模板参数。) - sbi声明向编译器展示符号名称。定义是分配符号空间的声明。
int f(int x); // function declaration (I know f exists)
int f(int x) { return 2*x; } // declaration and definition
从C++标准文档(第3.1节声明和定义)添加定义和声明示例:
定义:
int a; // defines a
extern const int c = 1; // defines c
int f(int x) { return x+a; } // defines f and defines x
struct S { int a; int b; }; // defines S, S::a, and S::b
struct X { // defines X
int x; // defines non-static data member x
static int y; // DECLARES static data member y
X(): x(0) { } // defines a constructor of X
};
int X::y = 1; // defines X::y
enum { up, down }; // defines up and down
namespace N { int d; } // defines N and N::d
namespace N1 = N; // defines N1
X anX; // defines anX
声明:
extern int a; // declares a
extern const int c; // declares c
int f(int); // declares f
struct S; // declares S
typedef int Int; // declares Int
extern X anotherX; // declares anotherX
using N::d; // declares d