我不明白两者的意义。


当前回答

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

void  myfunction(); //this is simple declaration

and

void myfunction()
{
 some statement;    
}

这是函数myfunction的定义

其他回答

你不能用最一般的术语说,声明是一个没有分配存储空间的标识符,而定义实际上是从声明的标识符分配存储空间吗?

一个有趣的想法是:只有类或函数与类型信息链接起来,模板才能分配存储空间。那么模板标识符是声明还是定义呢?它应该是一个声明,因为没有分配存储空间,您只是在对模板类或函数进行“原型化”。

从C99标准,6.7(5):

声明指定一组标识符的解释和属性。标识符的定义是该标识符的声明:

对于一个对象,使存储空间为该对象保留; 对于函数,包括函数体; 类的(唯一)声明 标识符。

来自c++标准3.1(2):

声明是定义,除非它声明了一个函数而没有指定函数体,它包含extern说明符或链接规范,但既没有初始化式也没有函数体,它在类声明中声明了静态数据成员,它是类名声明,或者它是typedef声明,using-declaration,或using-directive。

下面是一些例子。

有趣的是(也许不是,但我有点惊讶)typedef int myint;是C99中的定义,但在c++中只是声明。

当您使用extern存储类时,声明和定义的概念将形成一个陷阱,因为您的定义将位于其他位置,而您是在本地代码文件(页面)中声明变量。C和c++之间的一个区别是,在C中,声明通常在函数或代码页的开头完成。在c++中不是这样的。你可以在你选择的地方申报。

c++标准3.1节:

声明将名称引入到翻译单元中,或者重新声明前一个翻译单元中引入的名称 声明。声明指定这些名称的解释和属性。

下一段声明(强调是我的)声明是一种定义,除非……

... 它声明一个函数而不指定函数体:

void sqrt(double);  // declares sqrt

... 它在类定义中声明一个静态成员:

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

... 它声明了一个类名:

class Y;

... 它包含没有初始化式或函数体的extern关键字:

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

... Or是类型定义或using语句。

typedef long LONG_32;  // declares LONG_32
using namespace std;   // declares std

现在,理解声明和定义之间的区别很重要的一个重要原因是:一个定义规则。c++标准第3.2.1节:

任何翻译单元都不能包含任何变量、函数、类类型、枚举类型或模板的多个定义。

声明引入标识符并描述其类型,可以是类型、对象或函数。声明是编译器接受对该标识符的引用所需要的。这些是声明:

extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations

定义实际上实例化/实现了这个标识符。它是链接器为了将引用链接到这些实体所需要的。这些是对应于上述声明的定义:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

定义可以用在声明的地方。

标识符可以根据需要任意声明。因此,以下代码在C和c++中是合法的:

double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);

但是,它必须只定义一次。如果您忘记定义某个已经声明和引用的东西,那么链接器就不知道要链接到什么地方,并抱怨缺少符号。如果定义一个东西不止一次,那么链接器就不知道要链接引用哪个定义,并抱怨重复的符号。


由于在c++中什么是类声明和类定义的争论不断出现(在对其他问题的回答和评论中),我将在这里粘贴一段来自c++标准的引用。 在3.1/2,c++ 03说:

声明是定义,除非它[…是类名声明[…]。

3.1/3然后给出了几个例子。其中:

[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b [...]
struct S; // declares S
—end example

总结一下:c++标准考虑结构体x;是一个声明和结构x {};一个定义。(换句话说,“前向声明”是用词不当,因为在c++中没有其他形式的类声明。)

感谢litb (Johannes Schaub)在他的回答中找出了实际的章节和诗句。