C中的声明或定义

来自外部变量Wiki :

如果extern关键字和初始化值都不存在,则该语句可以是声明或定义。 由编译器来分析程序的模块并做出决定。

我无法完全理解关于C的这个陈述的含义。例如,它是否意味着:

int i; 

不一定是声明(正如我直到现在所假设的那样),但也可以是一个定义(根据同一网页上的定义和声明的定义,没有双关语)?

简而言之,就是上面的陈述:a。 只是声明,或b。 声明+定义?

参考: 变量声明和定义

收到的答复摘要:

  Declaration Definition Tentative Definition Initialized int i; (inside a block) Yes Yes No No int i=5; (inside a block) Yes Yes No Yes(to 5) int i; (otherwise) Yes No Yes Yes(to 0) extern int i; Yes No No No All definitions are declarations but not vice-versa. 

假设它在文件范围内,它是一个“暂定”。 从6.9.2 / 2“外部对象定义”:

具有文件范围而没有初始化程序且没有存储类说明符或存储类说明符为静态的对象的标识符声明构成暂定定义。 如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,那么行为就像翻译单元包含该标识符的文件范围声明一样,复合类型为翻译单元的结尾,初始化程序等于0。

这意味着在翻译单元中也有以下内容:

 int i = 42; 

因为该声明具有显式初始化器,所以它是变量i的定义。

如果声明属于块范围,则标准说明如下(6.2.2 / 2“标识符链接”):

没有链接的标识符的每个声明表示唯一的实体。

(第6段)以下标识符没有链接:…没有存储类说明符extern声明的对象的块范围标识符。

所以在块范围内,声明也是一个定义。

C标准说

标识符的定义是该标识符的声明 :对于对象,导致为该对象保留存储(…)

定义包含声明,即每个定义必然是一个声明,所以说这是没有意义的

 int i; 

不是声明。 这一个恰好是定义的声明。 或者,它是一个定义,因此是一个声明。

在变量的上下文中:

  • 变量声明是一个描述此变量外观的语句。 所以:

     extern int x; 

    在全局范围内转换为:“代码中的某处,有一个名为x的变量,它具有int和extern链接。在引用x之前必须声明。(同样适用于函数声明。)

  • 定义是一个创建此变量实例的语句。 所以:

     int x; 

    在全局范围内,使用extern链接创建int类型的单个变量。 因此,如果您将该行放在标题中,则包含该标题的每个翻译单元都会尝试创建自己的x副本,这是不可取的 – 这就是我们只在头文件中声明的原因。 function也是如此:如果你提供function体,它就是一个定义。

此外,正式地说,每个定义都是一种声明,因为它还必须指定此变量/函数的外观 – 因此,如果定义已存在于给定范围中,则不需要任何其他声明来使用它。

从C99规范:

具有文件范围而没有初始化程序且没有存储类说明符或存储类说明符为静态的对象的标识符声明构成暂定定义。 如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,那么行为就像翻译单元包含该标识符的文件范围声明一样,复合类型为翻译单元的结尾,初始化程序等于0。

所以这是一个没有初始化程序的简单声明可以作为声明的情况。

由于C使用以下术语:

“定义”创造了某种东西(占据某种记忆)。 它还描述了一些东西。 这意味着“定义”也是“声明”。

“宣言”只是描述了一些东西。 这个想法是编译器需要知道如何构建使用其他地方定义的东西的代码。 之后,链接器将使用链接到某个东西。

声明允许您编译代码并将其链接(稍后)作为单独的步骤。