我知道C中的全局变量有时有extern关键字。什么是extern变量?申报是什么样的?它的范围是什么?
这与跨源文件共享变量有关,但这究竟是如何工作的呢?我在哪里使用extern?
我知道C中的全局变量有时有extern关键字。什么是extern变量?申报是什么样的?它的范围是什么?
这与跨源文件共享变量有关,但这究竟是如何工作的呢?我在哪里使用extern?
当前回答
extern变量是在另一个翻译单元中定义的变量的声明(感谢sbi的更正)。这意味着变量的存储空间被分配到另一个文件中。
假设您有两个.c文件test1.c和test2.c。如果你定义一个全局变量int test1_var;在test1.c中你想访问test2.c中的这个变量你必须使用extern int test1_var;在test2.c。
完整的示例:
$ cat test1.c
int test1_var = 5;
$ cat test2.c
#include <stdio.h>
extern int test1_var;
int main(void) {
printf("test1_var = %d\n", test1_var);
return 0;
}
$ gcc test1.c test2.c -o test
$ ./test
test1_var = 5
其他回答
我使用了一个非常简短的解决方案,允许头文件包含对象的extern引用或实际实现。实际包含该对象的文件只是#define GLOBAL_FOO_IMPLEMENTATION。然后,当我向这个文件添加一个新对象时,它也会显示在那个文件中,而不需要我复制和粘贴定义。
我在多个文件中使用这种模式。因此,为了保持内容尽可能自包含,我只是在每个头文件中重用单个GLOBAL宏。我的标题是这样的:
//file foo_globals.h
#pragma once
#include "foo.h" //contains definition of foo
#ifdef GLOBAL
#undef GLOBAL
#endif
#ifdef GLOBAL_FOO_IMPLEMENTATION
#define GLOBAL
#else
#define GLOBAL extern
#endif
GLOBAL Foo foo1;
GLOBAL Foo foo2;
//file main.cpp
#define GLOBAL_FOO_IMPLEMENTATION
#include "foo_globals.h"
//file uses_extern_foo.cpp
#include "foo_globals.h
我喜欢把extern变量看作是你对编译器做出的承诺。
当遇到一个extern时,编译器只能找出它的类型,而不能找出它“居住”的位置,因此它不能解析引用。
你告诉它:“相信我。在链接时,这个引用将是可解析的。”
首先,extern关键字不用于定义变量;相反,它用于声明变量。我可以说extern是一个存储类,而不是数据类型。
extern用于让其他C文件或外部组件知道这个变量已经在某处定义。例如:如果你正在构建一个库,不需要在库本身的某个地方强制定义全局变量。库将直接编译,但在链接文件时,它将检查定义。
declare | define | initialize |
----------------------------------
extern int a; yes no no
-------------
int a = 2019; yes yes yes
-------------
int a; yes yes no
-------------
声明不会分配内存(必须为分配内存而定义变量),但定义会。 这只是对extern关键字的另一种简单看法,因为其他答案真的很棒。
Extern关键字与变量一起使用,以将其标识为全局变量。
它还表示可以使用使用extern声明的变量 关键字在任何文件中,尽管它在其他文件中声明/定义。