初始化、定义、声明变量的区别
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";
【讨论】:
以上是关于初始化、定义、声明变量的区别的主要内容,如果未能解决你的问题,请参考以下文章