我不明白两者的意义。


当前回答

根据GNU C库手册(http://www.gnu.org/software/libc/manual/html_node/Header-Files.html)

在C语言中,声明仅仅提供函数或变量存在的信息并给出其类型。对于函数声明,还可以提供关于其参数类型的信息。声明的目的是允许编译器正确地处理对声明的变量和函数的引用。另一方面,定义实际上为变量分配存储空间,或者说明函数的功能。

其他回答

为了理解声明和定义之间的区别,我们需要查看程序集代码:

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)

声明没有等价的指令,因为它不是要执行的东西。

此外,声明告诉编译器变量的作用域。

我们可以说,声明是编译器用来确定正确使用变量的信息,以及某些内存属于某个变量多长时间。

定义意味着实际编写的函数,声明意味着简单的声明函数 如。

void  myfunction(); //this is simple declaration

and

void myfunction()
{
 some statement;    
}

这是函数myfunction的定义

可执行文件的生成阶段:

(1)预处理器->(2)转换器/编译器->(3)链接器

在第二阶段(译者/编译器),我们代码中的声明语句告诉编译器,这些东西我们将在未来使用,你可以稍后找到定义,意思是:

译者确定:什么是什么?方法声明

(3)阶段(链接器)需要定义来绑定事物

链接器确定:哪里是什么?方法定义

为了理解名词,我们先来看看动词。

声明- - - - - - 宣布:正式宣布;宣告

定义- - - - - - 清晰完整地显示或描述(某人或某事

所以,当你声明某物时,你只需告诉它是什么。

// declaration
int sum(int, int);

这一行声明了一个名为sum的C函数,它接受两个int类型的参数并返回一个int。但是,您还不能使用它。

当你提供它的实际工作方式时,这就是它的定义。

// definition
int sum(int x, int y)
{
    return x + y;
}

c++中有一些有趣的边缘情况(在C中也有一些)。考虑

T t;

它可以是一个定义,也可以是一个声明,取决于T是什么类型:

typedef void T();
T t; // declaration of function "t"

struct X { 
  T t; // declaration of function "t".
};

typedef int T;
T t; // definition of object "t".

在c++中,当使用模板时,还有另一种边缘情况。

template <typename T>
struct X { 
  static int member; // declaration
};

template<typename T>
int X<T>::member; // definition

template<>
int X<bool>::member; // declaration!

最后一个声明不是定义。它声明了X<bool>的静态成员的显式特化。它告诉编译器:“如果要实例化X<bool>::member,那么不要从主模板实例化成员的定义,而是使用在其他地方找到的定义”。要使其成为定义,必须提供初始化式

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.