我不明白两者的意义。
当前回答
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节:
任何翻译单元都不能包含任何变量、函数、类类型、枚举类型或模板的多个定义。
其他回答
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.
声明意味着给变量命名和类型(在变量声明的情况下),例如:
int i;
或者将名称、返回类型和参数类型赋给一个没有函数体的函数(在函数声明的情况下),例如:
int max(int, int);
而定义意味着给变量赋值(在变量定义的情况下),例如:
i = 20;
或者为函数提供/添加函数体(功能)被称为函数定义,例如:
int max(int a, int b)
{
if(a>b) return a;
return b;
}
许多时间声明和定义可以一起完成:
int i=20;
and:
int max(int a, int b)
{
if(a>b) return a;
return b;
}
在上述情况下,我们定义并声明变量i和函数max()。
声明是在未分配值或对象的情况下创建原语或对象引用变量或方法。 int; Final int a;
定义意味着分别为值或对象赋值 Int a =10;
初始化意味着为各个变量或对象分配内存。
声明引入标识符并描述其类型,可以是类型、对象或函数。声明是编译器接受对该标识符的引用所需要的。这些是声明:
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)在他的回答中找出了实际的章节和诗句。
声明说"这个东西存在于某个地方"
int sampleFunc(); // function
extern int car; // variable
定义说,这个东西存在于这里;为它留下记忆"
int sampleFunc() {} // function
int car; // variable
在定义对象时,初始化是可选的,并表示“这是这个东西的初始值”:
int car = 0; // variable