我在阅读时遇到了以下问题......只是无法理解这背后的逻辑。
auto int c;
static int c;
register int c;
extern int c;
假设前三个是定义,最后一个是声明..怎么来的?
我在阅读时遇到了以下问题......只是无法理解这背后的逻辑。
auto int c;
static int c;
register int c;
extern int c;
假设前三个是定义,最后一个是声明..怎么来的?
最后一个extern
没有为c
. 它仅表明c
存在某处,并且链接器应该能够将其解析为在c
其他地方定义的某个全局。
如果您编译并链接了单个 .c 文件并尝试使用最后一个文件,c
则会出现链接器错误。对于前 3 c
s,您不会因为它们在当前编译单元中具有实质内容(它们已被定义)。
如果您想了解有关extern
声明与定义的更多信息,这里有一篇关于该主题的好文章。引用那篇文章:
变量/函数的声明只是声明变量/函数存在于程序中的某处,但没有为它们分配内存
关键字extern
引用了变量(或可能函数)的定义在别处的事实;然后编译器将此声明链接到单独文件中定义的主体。前面的三个关键字声明了一个声明——变量没有在别处定义,因此也没有prototypes
。
例如,假设您有一个像这样的项目结构:
..
-- main.c
-- client.c
-- client.h
-- server.c
-- server.h
当gcc
使用头文件编译这些时,头文件通常define
是程序所需的变量。这会分配一个链接到declaration
.c 文件中的符号的符号。这就是编译器如何将各种项目文件与.o
对象链接起来。objdump -d
通过使用(假设您在 Linux 上)调试程序的实际反汇编结构,您可能会对这一切如何出现更感兴趣。
享受和好运!
前 3 个语句实际上为int
.
最后一个没有。它告诉编译器的只是在另一个编译单元的某个地方,将定义一个int
被调用的。c
如果未定义,稍后您将收到链接器错误。不出所料,链接器会说c
未定义。
前三个是定义,因为它将为变量留出存储空间。
最后一个不会为int c
. 它只会使用在别处分配和命名的存储空间。