C中全局变量的定义何时是有条件的?

C中全局变量的定义何时是有条件的?,c,variables,global,C,Variables,Global,如果我说 int i=8; 在每个函数之外,这个全局变量的定义是暂时的吗?为什么 编辑:我将“conditional”更改为暂定,我将其翻译错误。如果您将变量声明在函数范围之外,则默认情况下它具有和。这意味着变量可以在当前翻译单元的任何地方访问(即预处理器生成的当前C文件)。该变量也可以在其他转换单元中访问,但您需要在那里声明为extern int i或asint i。注意,如果将变量定义为static int i=8在文件范围内,则变量将具有,并且您将无法在其他翻译单元中使用它,即使将其声明

如果我说

int i=8;
在每个函数之外,这个全局变量的定义是暂时的吗?为什么


编辑:我将“conditional”更改为暂定,我将其翻译错误。

如果您将变量声明在函数范围之外,则默认情况下它具有和。这意味着变量可以在当前翻译单元的任何地方访问(即预处理器生成的当前C文件)。该变量也可以在其他转换单元中访问,但您需要在那里声明为
extern int i或as
int i。注意,如果将变量定义为
static int i=8在文件范围内,则变量将具有,并且您将无法在其他翻译单元中使用它,即使将其声明为
extern int i

这里没有条件,我不知道你说的这个词是什么意思

编辑


不,您的不是。

如果您如图所示定义了一个全局变量,那么在该变量之前定义的任何函数都不会知道该变量,除非在该函数之前或函数内部进行了某些声明

void foo () {
    extern int i; /* declare presence of global i */
    /* code that uses i */
}

int i=8;

void bar () {
    /* code that uses i, does not need declaration */
}
全局的暂定定义是没有初始值设定项的简单声明

int i; /* tentative definition */

void foo () {
    /* code that uses i */
}

暂定定义允许像在转发声明中一样使用
i
,但是,除非找到
i
的明确外部定义,否则它也将被视为默认的初始化外部定义。

您所说的条件定义是什么?是的。存在于任何其他作用域/函数/命名空间/类之外的是每种拥有它们的语言中的全局定义。“条件定义”???标准C术语不知道这样的概念。你所说的条件定义是什么意思?问题是,我不知道我是否从我的语言中正确地翻译了它,“条件”是我想到的最好的翻译。这是去年一次考试中的一道题,我没有补考。@Nebeski:C语言有一个“暂定定义”的概念。但是,包含初始值设定项的定义从来都不是临时性的。错误:“如果之前的声明不可见,或者之前的声明未指定任何链接,则标识符具有外部链接。”(6.2.2p4)。这在extern上不太正确。除非在翻译单元中明确声明它是
静态的
,否则链接器将允许任何其他翻译单元通过
外部
声明访问它。另外,因为这家伙显然是个初学者:“翻译单位”=“.c文件”在非常笼统的术语中。@BrianMcFarland:更准确地说:翻译单位是每个“.c”-传递给编译器的文件加上所有
#include
d文件-直接或间接。@BrianMcFarland如果不在第二个翻译单元中使用
extern
,您将如何访问它?在你发表评论之前,我还编辑了答案。如果现在有什么问题,请告诉我。@BrianMcFarland,也没有静态链接。有内部联动、外部联动和无联动。然而,对于这个答案的范围,我认为如果我们深入研究standardese,OP的好处不会更大,这就是为什么我没有提到任何关于链接的内容(除了使用
static int I=8;
,这使得链接是内部的)。如果你想要一些血淋淋的细节,你可以查看。对暂定定义的描述不正确;它不“匹配”不同的翻译单位。如果存在
int i=5在另一个单元中,则由于多个定义,它是未定义的行为。(你的链接更详细地描述了这一点)@M.M:我是凭记忆研究事情是如何运作的。但是,是的,我在我的链接文章中描述了这种技术性。你的最后一段与暂定定义的工作原理完全不同。它的行为不像有一个默认的初始值设定项,外部声明没有任何区别(除非它们提供初始值设定项),并且它不会在另一个TU中暗示定义(这将是UB)。如果当前TU中没有给出带有初始值设定项的定义,则它总是在末尾创建一个定义。@M.M:
int a
bare没有初始值设定项。如果创建了实例,它不是默认初始化的吗?如果
extern inta跟随
inta它是否将试探性声明视为另一个外部声明?外部声明不是暗示定义在别处吗?