Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将打印哪个值?_C_Extern - Fatal编程技术网

C 将打印哪个值?

C 将打印哪个值?,c,extern,C,Extern,在上述代码中,int i表示i=0;int i=35表示i=35 那么,如果编译器没有给出重新定义的错误,哪个值会被打印出来呢?在ansi标准中,他们称之为int x;暂定定义 这是ansi标准所说的: 具有文件作用域的对象的标识符声明 没有初始值设定项,也没有存储类说明符或 存储类说明符static构成了一个 释义如果翻译单元包含一个或多个暂定 标识符的定义,并且翻译单元不包含 该标识符的外部定义,则该行为 就好像翻译单元包含一个文件范围声明一样 标识符,具有转换结束时的复合类型 单位,初始值

在上述代码中,int i表示i=0;int i=35表示i=35


那么,如果编译器没有给出重新定义的错误,哪个值会被打印出来呢?

在ansi标准中,他们称之为int x;暂定定义

这是ansi标准所说的:

具有文件作用域的对象的标识符声明 没有初始值设定项,也没有存储类说明符或 存储类说明符static构成了一个 释义如果翻译单元包含一个或多个暂定 标识符的定义,并且翻译单元不包含 该标识符的外部定义,则该行为 就好像翻译单元包含一个文件范围声明一样 标识符,具有转换结束时的复合类型 单位,初始值设定项等于0

举例来说:

void main()
{
    extern int i;
    printf("%d\n",i);
}
int i;//definetion
int i=35;//definition
根据我的理解,你可以对同一个对象有任意多个暂定定义,最多一个带有初始值设定项的定义。如果没有定义,则在文件末尾将暂定定义转换为初始值设定项==0的定义

换句话说,打印的值是35,因为有一个初始值设定项。

来自6.7.5:

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

所以两者都是int i;int i=35;是定义,也是声明,因为所有定义都是声明

区别在于int i=35;还有一个显式初始化器,而int i;仅当没有外部定义时,才会隐式初始化为0(假定全局因此为静态存储持续时间):

从6.2.9.2开始:

具有不带初始值设定项的文件作用域的对象的标识符声明,以及 如果没有存储类说明符或存储类说明符为static,则构成 暂定定义。如果翻译单元包含一个或多个暂定定义 标识符,并且翻译单元不包含该标识符的外部定义 该行为与翻译单元包含该转换单元的文件范围声明完全相同 标识符,复合类型在翻译单元末尾,带有初始值设定项 等于0

注意,这些初步定义在C++中是不可用的。见附录C1.2第3.1条


因此,在这种情况下,将打印值35,因为这是我初始化为的值。

该代码不会编译。你为什么要用void main?!只有一个定义。int i;是一个declaration@KirilKirov; 声明和定义之间存在差异。@haccks-请参阅标准中的3.1声明和定义。int i;这是一个定义。外部国际一级;这是一份声明。inti=35又是定义。如果inti指的是inti=35,那么我们总是可以用intinot替换externinti。如果将int i放入头文件,它将转换为定义,并在每个文件(包括此头文件)的末尾为变量保留一个空间,并且在链接过程中会出现多个定义问题。如果我将int i放在void main之前,并从main中删除extern int i,会怎么样works@learner:如果你把int i;在主管道和拆除外部管道之前;从main开始,它将以与现在相同的方式工作。然而,所有这些都不是经典C开发人员会做的。一个普通的开发者会把extern inti;在头文件的某个地方,正好有一个int i=35;在头文件中放入extern int i会有什么帮助
     int i1 = 1;          /*  definition, external linkage */
     static int i2 = 2;   /*  definition, internal linkage */
     extern int i3 = 3;   /*  definition, external linkage */
     int i4;              /*  tentative definition, external linkage */
     static int i5;       /*  tentative definition, internal linkage */
     int i1;   /*  valid tentative definition, refers to previous */
     int i2;   /*  $3.1.2.2 renders undefined, linkage disagreement */
     int i3;   /*  valid tentative definition, refers to previous */
     int i4;   /*  valid tentative definition, refers to previous */
     int i5;   /*  $3.1.2.2 renders undefined, linkage disagreement */



     extern int i1; /* refers to previous, whose linkage is external */
     extern int i2; /* refers to previous, whose linkage is internal */
     extern int i3; /* refers to previous, whose linkage is external */
     extern int i4; /* refers to previous, whose linkage is external */
     extern int i5; /* refers to previous, whose linkage is internal */