如何解决extern 关键字似乎没有任何意义
我在文件 a.c 中有以下程序:
#include<stdio.h>
#include"b.c"
int main(void){
extern int a;
a+=2;
printf("%d\n",a);
return 0;
}
文件b.c如下:
int a=1;
现在我使用 extern 关键字来声明变量 a,但没有定义它。 因此,我可以更改其内容,打印它会打印 3。
我不明白的是,如果我从 a.c 中删除 extern int a;
行,程序也会运行并且输出仍然是 3。
我认为要更改 b.c 中的变量,您必须使用 extern 关键字。
这里发生了什么?
解决方法
以这个程序为例:
#include<stdio.h>
void main()
{
extern int y;
printf("%d",y);
}
int y=10;
输出结果是:
10
extern
是声明,而不是定义。
它没有定义一个变量,这意味着它没有给它任何内存。它只声明变量以便您可以使用它。
在您的示例中,您不必声明 a
,原因很简单,因为它已经定义,因为 #include
基本上是将粘贴代码复制到您的程序中。
如果你移动
#include"b.c"
在程序的底部,您需要该 extern
语句,因为尚未定义 y
。
旁注:extern
可以是一个定义,如果它有一个等号,如 @John Bollinger 所说。但是,在您的示例中,情况并非如此。
- 当您包含该文件时,编译器正在编译一个文件。
事实上你正在编译:
#include<stdio.h>
int a = 1;
int main(void){
extern int a;
a+=2;
printf("%d\n",a);
return 0;
}
您只有一个编译单元,而 a
未在另一个编译单元中定义。
当您从声明中删除 extern
时,您定义了未初始化的局部自动变量 a
。然后你使用它,它具有无法确定的价值。它可以是任何东西。
#include<stdio.h>
int a = 5;
int main(void){
int a;
a+=2;
printf("%d\n",a);
return 0;
}
这个程序不太可能输出7
:https://godbolt.org/z/GeGvbd
当编译器编译 main
例程时,它已经在您包含的 int a=1;
中看到了 b.c
,因此 extern int a;
不会告诉它任何新内容。因此它什么都不做。
extern int a;
表示“a
是 int
的名称,而 int
是在别处定义的。”但是,通过包含 b.c
,您包含了定义 int a=1;
的 a
。所以编译器已经知道 a
被定义为一个 int
。
我认为要更改 b.c 中的变量,您必须使用 extern 关键字。
要通过名称引用对象,您需要提供该名称的声明。您包含的 int a=1;
是一个声明(它是一个定义)。
您不需要 extern
来表示我将按名称引用一个对象,但您确实需要它说“我不是在这里定义对象,只是告诉您在某处定义的对象。 ”使用它的正确方法不是在 b.c
中包含 a.c
,而是:
- 在
b.c
中,用a
定义int a=1;
。 - 在
b.h
中,使用a
声明extern int a;
。 - 在
a.c
中,使用#include "b.h"
包含声明。 - 在
a.c
中,您不需要自己编写extern int a;
,因为当您包含b.h
时,您就会明白这一点。 - 在
b.c
中,使用#include "b.h"
检查声明。 (当您在b.h
中包含b.c
时,编译器会在同一次编译过程中看到声明和定义,如果有错误导致声明冲突,它会发出警告。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。