C++ 初始化、定义和声明变量之间的区别

C++ 初始化、定义和声明变量之间的区别,c++,c,terminology,C++,C,Terminology,读了之后,我知道了声明和定义之间的区别。那么这是否意味着定义等于声明加上初始化?声明 声明通常指在程序中引入新名称。例如,您可以通过描述一个新函数的“签名”来声明它: 或声明不完整的类型: class klass; struct ztruct; 最后但并非最不重要的一点是,声明一个对象: int x; 在C++标准中,在3.3.1中描述为: 声明(第7条)可将一个或多个名称引入翻译单元,或重新声明先前声明引入的名称 定义 定义是以前声明的名称的定义(也可以是定义和声明)。例如: int x;

读了之后,我知道了声明和定义之间的区别。那么这是否意味着定义等于声明加上初始化?

声明 声明通常指在程序中引入新名称。例如,您可以通过描述一个新函数的“签名”来声明它:

或声明不完整的类型:

class klass;
struct ztruct;
最后但并非最不重要的一点是,声明一个对象:

int x;

在C++标准中,在3.3.1中描述为:

声明(第7条)可将一个或多个名称引入翻译单元,或重新声明先前声明引入的名称

定义 定义是以前声明的名称的定义(也可以是定义和声明)。例如:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };
int x;

特别是C++标准定义,在3.3.1,为:

声明是一个定义,除非它在声明函数时没有指定函数体(8.4),它包含外部说明符(7.1.1)或链接规范25(7.5),既不是初始值设定项也不是函数体,它在类定义(9.2,9.4)中声明静态数据成员,它是类名声明(9.1),它是一个不透明的枚举声明(7.2),它是一个模板参数(14.1),它是一个不是函数定义声明器的函数声明器中的参数声明(8.3.5),或者它是一个typedef声明(7.1.3),一个别名声明(7.1.3),一个using声明(7.3.3),一个static_assert-declaration(第7条),属性声明(第7条)、空声明(第7条)或使用指令(7.3.4)

初始化 初始化是指在构造时对值进行“赋值”。对于类型为
T
的泛型对象,其形式通常为:

T x = i;
<>但在C++中可以是:

T x(i);
甚至:

T x {i};
使用C++11

结论
那么这是否意味着定义等于声明加上初始化

视情况而定。你在说什么。如果您正在谈论一个对象,例如:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };
int x;
这是一个没有初始化的定义。以下是带有初始化的定义:

int x = 0;
在某些上下文中,谈论“初始化”、“定义”和“声明”是没有意义的。例如,如果您谈论的是一个函数,那么初始化就没有多大意义


因此,答案是否定的:定义并不自动意味着声明加初始化。

对于C,至少根据C116.7.5:

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

  • 对于对象,导致为该对象保留存储

  • 对于函数,包括函数体

  • 对于枚举常量,是标识符的(唯一)声明

  • 对于typedef名称,是标识符的第一个(或唯一)声明

根据C116.7.9.8-10:

初始值设定项指定存储在对象中的初始值。。。如果 具有自动存储的对象未显式初始化, 它的价值是不确定的

因此,广义地说,声明引入标识符并提供有关它的信息。对于变量,定义是为该变量分配存储的声明

初始化是要存储在对象中的初始值的规范,它不一定与第一次显式为其赋值时相同。定义变量时,无论是否显式为其指定值,变量都有一个值。如果您没有显式地给它一个值,并且变量具有自动存储,那么它将有一个初始值,但该值将是不确定的。如果它有静态存储,它将根据类型进行隐式初始化(例如指针类型初始化为空指针,算术类型初始化为零,等等)

因此,如果定义自动变量而不指定其初始值,例如:

int myfunc(void) {
    int myvar;
    ...
您正在定义它(因此也在声明它,因为定义就是声明),但没有初始化它。因此,定义不等于声明加初始化。

“所以它的意思是定义等于声明加初始化。”

不一定,您的声明可能没有初始化任何变量,如:

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
void helloWorld()//声明或原型。
void helloWorld()
{
std::cout声明说“这东西存在于某处”:

定义是“这个东西存在于这里,为它留下记忆”:

在对象的定义点上,初始化是可选的,并表示“这是该对象的初始值”:

有时,在申报时也可能:

struct T
{
   static int baz = 42;
};

…但这涉及到更复杂的功能。

初始化是针对变量的。定义也可以应用于函数,在函数中定义主体。那么你的意思是对于变量,它是正确的。不完全是:
int x;
是一个定义,也是一个声明。@Angew,谢谢,我添加了一个更完整的定义。我认为问题是OP在他的帖子中提到的定义和声明回答得很好。但最初的问题是
,那么这是否意味着定义等于声明加上初始化
@Tahlil,添加了一个结论。感谢你让我注意到。@Tony我想(如果我错了,请有人纠正我,让我学习)“extern int x”使它只是一个声明,这意味着定义可以在其他地方找到。虽然“int x”实际上定义了它,但它是用随机垃圾值指定的,除非你特别像“int x=5”那样初始化它。解释得很好,只是初始化比这复杂一点。(如果它是简单的,这就不是C++)初始化包括
int bar = 0;     // variable
int T::baz = 42; // static member variable
struct T
{
   static int baz = 42;
};