初始化、定义、声明变量的区别

Posted

技术标签:

【中文标题】初始化、定义、声明变量的区别【英文标题】:The differences between initialize, define, declare a variable 【发布时间】:2014-06-14 06:18:53 【问题描述】:

看完question,我知道声明和定义的区别了。那么定义等于声明加初始化吗?

【问题讨论】:

初始化是针对变量的。定义也可以应用于定义主体的函数。 所以你的意思是变量,没错。 【参考方案1】:

声明

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

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-declaration (Clause 7)、attribute-declaration (Clause 7)、empty-declaration (Clause 7) 或 using-directive (7.3.4)。

初始化

初始化是指在构造时对值的“赋值”。对于T 类型的通用对象,它通常采用以下形式:

T x = i;

但在 C++ 中它可以是:

T x(i);

甚至:

T x i;

使用 C++11。

结论

所以定义等于声明加初始化?

这取决于。关于你在说什么。如果你在谈论一个对象,例如:

int x;

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

int x = 0;

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

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

【讨论】:

不完全是:int x; 既是定义也是声明。 @Angew,谢谢,我添加了更完整的定义 我认为 OP 在他的帖子中提到的问题很好地回答了定义和声明。但最初的问题是So does it mean definition equals declaration plus initialization @Tahlil,添加了一个结论。感谢您让我注意到。 @Tony 我认为(如果我错了,请有人纠正我,以便我学习)'extern int x' 使它只是一个声明,这意味着该定义可以在其他地方找到。虽然'int x'实际上定义了它,尽管它被指定为随机垃圾值,除非你像'int x = 5'那样特别初始化它。【参考方案2】:

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

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;
;

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

【讨论】:

解释得很好,只是初始化比这复杂一点。 (如果它那么简单,这将不是 C++。)初始化包括诸如具有静态生命周期的变量的零初始化、默认构造函数以及您显示的内容。 (更令人困惑的是:在 C 中,初始化可能是第一次分配变量;例如,在“获取未初始化变量的值”之类的语句中。如果其中一些也滑入其中,我不会感到惊讶C++。) 哦,还有一些特殊情况,C++ 允许在声明中指定初始化。 @JamesKanze:为了这些目的,决定让它超级简单 这没有意义,静态成员变量分配内存。【参考方案3】:

对于 C,至少,根据 C11 6.7.5:

声明指定了一组的解释和属性 身份标识。一个标识符的定义是一个声明 标识符:

对于一个对象,导致为该对象保留存储空间;

对于函数,包括函数体;

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

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

根据 C11 6.7.9.8-10:

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

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

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

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

int myfunc(void) 
    int myvar;
    ...

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

【讨论】:

在 C++ 中,初始化有很大不同。 (C 还具有对具有静态生命周期的对象进行零初始化的等价物。) @JamesKanze:是的,不幸的是,这个问题同时被 C 和 C++ 标记,这对于它们不同的地方没有多大帮助。 相当。对于兼容类型,C++ 中的 intent(至少最初是这样)是它们的行为与 C 中的相同;事实上,我认为在语言本身兼容的所有情况下,它们的行为仍然相同。但用于定义这种行为的措辞却大不相同。【参考方案4】:

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

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

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 
    std::cout << "Hello World\n";
  

【讨论】:

以上是关于初始化、定义、声明变量的区别的主要内容,如果未能解决你的问题,请参考以下文章

在C语言中声明和定义的区别?

变量的声明定义初始化(转)

iOS OC声明变量@interface和@property的区别

let和var的区别

c语言中,声明和定义有啥区别

C++中类里面定义 静态成员变量的问题