C 错误:外部声明';i';在声明之后没有链接

C 错误:外部声明';i';在声明之后没有链接,c,declaration,C,Declaration,在下面的程序中,我认为extern inti将更改以下i以引用在main外部定义的i: #include <stdio.h> extern int i=1; // warning: 'i' initialized and declared 'extern' int main() { int i=2; printf("%d\n", i); extern int i; // error: extern declaration of 'i' follows de

在下面的程序中,我认为
extern inti将更改以下
i
以引用在
main
外部定义的
i

#include <stdio.h>

extern int i=1; // warning: 'i' initialized and declared 'extern'

int main()
{
    int i=2;
    printf("%d\n", i);
    extern int i; // error: extern declaration of 'i' follows declaration with no linkage
    printf("%d\n", i);
    return 0;
}
#包括
外部内部i=1;//警告:“i”已初始化并声明为“extern”
int main()
{
int i=2;
printf(“%d\n”,i);
extern int i;//错误:“i”的extern声明跟在声明后面,没有链接
printf(“%d\n”,i);
返回0;
}
“错误:i”的外部声明跟随无链接声明”的原因是什么,其中“无链接声明”指
int i=2

在我删除
main
中的
int I=2
之后

  • 错误消失了
  • extern int i=1上的警告“warning:'i'初始化并声明为'extern'”也会消失。为什么呢
谢谢你的解释

#包括
#include <stdio.h>

int i=1;  // external variable

int main()
{
    int i=2;            // local variable
    printf("%d\n", i);  // print local variable i==2

    {
    extern int i;       // point to external variable
    printf("%d\n", i);  // print external variable i==1
    }

    return 0;
}
int i=1;//外部变量 int main() { int i=2;//局部变量 printf(“%d\n”,i);//打印局部变量i==2 { extern int i;//指向外部变量 printf(“%d\n”,i);//打印外部变量i==1 } 返回0; }
main
函数中定义名为
i
的变量后,文件范围内的
i
将被屏蔽,无法访问(除非您有其地址)

稍后添加声明
extern int i
时,这与同一范围内名为
i
的局部变量冲突,因为局部变量不能具有外部链接。它不允许您访问全局
i


删除本地
i
时,
extern int i
声明与文件范围的定义匹配,因此没有错误。关于
extern int i=1的警告,这在gcc 4.1.2中对我来说并没有消失,所以这取决于编译器。

问题:“错误:在没有链接的声明之后是'i'的外部声明”,其中“没有链接的声明”指的是int i=2
答:如果一个程序中只有一个文件,并且同一程序中没有其他文件,或者同一文件中没有定义变量int i的其他位置,那么我们不需要在第3行使用extern关键字。我们可以在C中使用extern关键字有两个主要原因:
1.当我们想要显式/全局地声明一个变量但没有定义时。
2.使变量从多文件程序中的任何其他文件或同一文件的其他位置全局可见(有关此方案,请参阅Ihdina的exmaple)。
在我的系统上编译代码时出现以下错误,
错误:“i”的外部声明遵循非外部声明。 这完全有道理,编译器在第9行检测到extern是第7行相同变量inti的重复声明

问题:在我删除main中的int I=2之后, 错误消失了, extern int i=1上的警告“warning:'i'初始化并声明为'extern'”;也消失了。为什么会这样?
答:移除int i=2后;错误已在我的系统上消失,但仍有以下警告消息:
警告:“extern”变量具有初始值设定项[-Wextern初始值设定项]
基本上,我的系统(Apple LLVM版本8.1.0(clang-802.0.42))不喜欢使用extern关键字进行显式初始化。因此,您应该根据Ihdina的答案修改代码,该答案编译时不会出错

extern-int i错误:在同一范围内重复标识符。尝试
{extern int i;printf(“%d\n”,i);}
替换extern int i=1;int i=1;在
main()
中已经有一个局部变量
i
;你不可能在全球范围内。局部变量隐藏全局变量。这不是C++,在这里您可以使用范围解析操作符来帮助。对全局变量进行阴影处理是不好的做法(如果您指定
-Wshadow
,GCC将发出警告)。想要在一个函数中同时访问这两个函数是更糟糕的做法。@JonathanLeffler很高兴知道这是一个糟糕的做法。我的例子更多的是为了研究范围和链接目的。@JonathanLeffler,是的,我缺少块范围链接。现在它可以工作了。Re“locals can't have external linkage”:链接是标识符的属性,块范围内的标识符当然可以有外部链接。原因
int i=2;外部国际一级
有冲突是C 2018(以及2011和更早版本)6.7 3给出了一个约束,即如果标识符没有链接(在
int i-2;
i
满足该链接),则在同一范围和命名空间中,该标识符的声明不得超过一个,typedef名称和标记除外。