变量的声明、定义和初始化有什么区别?

问题描述 投票:0回答:4

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

c++ c terminology
4个回答
126
投票

声明

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

void xyz();

或者声明一个不完整的类型:

class klass;
struct ztruct;

最后但并非最不重要的一点是,声明一个对象:

int x;

在 C++ 标准第 §3.1/1 中将其描述为:

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

定义

定义是先前声明的名称的定义(或者它可以是定义和声明)。例如:

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

具体来说,C++ 标准在 §3.1/1 中将其定义为:

声明是一个定义,除非它声明一个函数而没有指定函数体(8.4),它包含 extern 说明符(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)、使用声明(7.3.3)、static_assert 声明(第 7 条)、属性声明(第 7 条)、空声明(第 7 条)或 using 指令(7.3.4)。

初始化

初始化是指在构造时“赋值”一个值。对于

T
类型的通用对象,它通常采用以下形式:

T x = i;

但在 C++ 中它可以是:

T x(i);

甚至:

T x {i};

使用 C++11。

结论

那么定义等于声明加初始化吗?

这要看情况。关于你在说什么。如果你正在谈论一个物体,例如:

int x;

这是一个没有初始化的定义。相反,以下是带有初始化的定义:

int x = 0;

在某些上下文中,谈论“初始化”、“定义”和“声明”是没有意义的。例如,如果您正在谈论一个函数,初始化并没有多大意义。

所以,答案是:定义并不自动意味着声明加初始化。


63
投票

声明说“这个东西存在于某处”:

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

定义说“这个东西存在于此;为它建立记忆”:

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

初始化在对象定义时是可选的,并表示“这是这个东西的初始值”:

int bar = 0;     // variable
int T::baz = 42; // static member variable

有时可以在声明时改为:

struct T
{
   static int baz = 42;
};

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


9
投票

对于 C,至少按照 C11 6.7.5:

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

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

  • 对于函数,包括函数体;

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

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

根据 C11 6.7.9.8-10:

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

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

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

所以,如果你定义了一个自动变量而没有为其指定初始值,比如:

int myfunc(void) {
    int myvar;
    ...

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


1
投票

“那么这是否意味着定义等于声明加初始化。”

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

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
© www.soinside.com 2019 - 2024. All rights reserved.