声明、定义和初始化如何工作?我已经说明了我是如何理解的,并希望得到纠正
How does declaration, definition and initialization work? I've stated how I understand it and would like to get corrected
我了解了声明、定义和初始化。好像听懂了,但还是没那么自信
所以我假设声明是在代码中放置(以及声明)日期类型或函数(或其他我可能不知道的东西),并且在大多数情况下它也将是一个定义。基本上所有占用内存的东西都可以看作是声明和定义。
故意让它不成为定义可能是一个挑战。例如,我们需要将 extern
说明符放在一个数据类型中,该数据类型会很明显地说:它。存在。不。做。任何事物。而且由于函数不占用内存,所以实际上可以声明而不定义,比如void function()
。当我们在函数后面打开花括号时,它也被正式认为是一个定义。
初始化用于初始化数据类型后输入的第一个值。因此,如果值为 int thing = 3
,第一个值将被初始化为 3。但是如果我们决定重用 thing
变量,同时保留先前的值并分配一个值,例如 4 (int thing = 4
), 然后 thing
将执行值为 4.
我对这个概念的理解对吗?我花了很长时间才看到别人是怎么形容他们的,所以我想知道我在这里说的是对还是错。
感谢您抽出宝贵时间。我个人不认为这是重复的,因为我正在复习我的知识。
是的,简单来说你是对的。 standard draft 用了一页左右的篇幅介绍 par 中的声明和定义。 6.1.我喜欢它描述声明的方式(我强调):
A declaration (Clause 10) may introduce one or more names into a translation unit or redeclare names
introduced by previous declarations.
标准对这些名称的性质含糊不清(特别是它没有提到“objects”、“变量”或“类型”!),因为种类繁多:类、函数、枚举声明符、普通旧变量、参数、静态 class 成员等
该标准对这种“介绍”的性质也含糊不清,因为它也各不相同。共同点是声明为编译器提供了足够的关于名称的信息以使用它,尽管可能只是以一种受限的方式。例如,在 class (class MyClass;
) 的前向声明之后,编译器只知道名称指定类型;但这足以定义指向它的指针(因为所有指向 object 的指针都是相同的)。创建该类型的 object 或调用方法是不够的:数据和函数成员毕竟是未知的。
可以说 声明 通常指定外在属性 — 足以以某种方式使用名称 — 而 定义 指定内部工作原理,即使用时发生的情况。
例如,最常见的“纯”声明可能是函数声明,通常在 headers 中。它们通知编译器如何调用它们以及必须生成哪些代码才能调用它们。相比之下,函数 定义 指定调用函数 时发生的情况 。
对于变量声明与定义类似:*如何使用与使用时会发生什么(操作哪个内存)。
然后该标准用半页的篇幅列出了不是定义的声明;其中大约 10% 对我来说是未知的术语(不确定这是否对标准或我有不良影响)。但是对于变量,正如您所说,声明通常是一个定义,除非它带有 extern
说明符并且没有初始化。
我了解了声明、定义和初始化。好像听懂了,但还是没那么自信
所以我假设声明是在代码中放置(以及声明)日期类型或函数(或其他我可能不知道的东西),并且在大多数情况下它也将是一个定义。基本上所有占用内存的东西都可以看作是声明和定义。
故意让它不成为定义可能是一个挑战。例如,我们需要将 extern
说明符放在一个数据类型中,该数据类型会很明显地说:它。存在。不。做。任何事物。而且由于函数不占用内存,所以实际上可以声明而不定义,比如void function()
。当我们在函数后面打开花括号时,它也被正式认为是一个定义。
初始化用于初始化数据类型后输入的第一个值。因此,如果值为 int thing = 3
,第一个值将被初始化为 3。但是如果我们决定重用 thing
变量,同时保留先前的值并分配一个值,例如 4 (int thing = 4
), 然后 thing
将执行值为 4.
我对这个概念的理解对吗?我花了很长时间才看到别人是怎么形容他们的,所以我想知道我在这里说的是对还是错。
感谢您抽出宝贵时间。我个人不认为这是重复的,因为我正在复习我的知识。
是的,简单来说你是对的。 standard draft 用了一页左右的篇幅介绍 par 中的声明和定义。 6.1.我喜欢它描述声明的方式(我强调):
A declaration (Clause 10) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.
标准对这些名称的性质含糊不清(特别是它没有提到“objects”、“变量”或“类型”!),因为种类繁多:类、函数、枚举声明符、普通旧变量、参数、静态 class 成员等
该标准对这种“介绍”的性质也含糊不清,因为它也各不相同。共同点是声明为编译器提供了足够的关于名称的信息以使用它,尽管可能只是以一种受限的方式。例如,在 class (class MyClass;
) 的前向声明之后,编译器只知道名称指定类型;但这足以定义指向它的指针(因为所有指向 object 的指针都是相同的)。创建该类型的 object 或调用方法是不够的:数据和函数成员毕竟是未知的。
可以说 声明 通常指定外在属性 — 足以以某种方式使用名称 — 而 定义 指定内部工作原理,即使用时发生的情况。
例如,最常见的“纯”声明可能是函数声明,通常在 headers 中。它们通知编译器如何调用它们以及必须生成哪些代码才能调用它们。相比之下,函数 定义 指定调用函数 时发生的情况 。
对于变量声明与定义类似:*如何使用与使用时会发生什么(操作哪个内存)。
然后该标准用半页的篇幅列出了不是定义的声明;其中大约 10% 对我来说是未知的术语(不确定这是否对标准或我有不良影响)。但是对于变量,正如您所说,声明通常是一个定义,除非它带有 extern
说明符并且没有初始化。