3

我在阅读时遇到了以下问题......只是无法理解这背后的逻辑。

auto int c;
static int c;
register int c;
extern int c;

假设前三个是定义,最后一个是声明..怎么来的?

4

5 回答 5

4

最后一个extern没有为c. 它仅表明c存在某处,并且链接器应该能够将其解析为在c其他地方定义的某个全局。

如果您编译并链接了单个 .c 文件并尝试使用最后一个文件,c则会出现链接器错误。对于前 3 cs,您不会因为它们在当前编译单元中具有实质内容(它们已被定义)。

如果您想了解有关extern声明与定义的更多信息,这里有一篇关于该主题的好文章。引用那篇文章:

变量/函数的声明只是声明变量/函数存在于程序中的某处,但没有为它们分配内存

于 2012-07-16T15:29:26.030 回答
3

关键字extern引用了变量(或可能函数)的定义在别处的事实;然后编译器将此声明链接到单独文件中定义的主体。前面的三个关键字声明了一个声明——变量没有在别处定义,因此也没有prototypes

例如,假设您有一个像这样的项目结构:

..
-- main.c
-- client.c
-- client.h
-- server.c
-- server.h

gcc使用头文件编译这些时,头文件通常define是程序所需的变量。这会分配一个链接到declaration.c 文件中的符号的符号。这就是编译器如何将各种项目文件与.o对象链接起来。objdump -d通过使用(假设您在 Linux 上)调试程序的实际反汇编结构,您可能会对这一切如何出现更感兴趣。

享受和好运!

于 2012-07-16T15:29:43.773 回答
2

前 3 个语句实际上为int.

最后一个没有。它告诉编译器的只是在另一个编译单元的某个地方,将定义一个int被调用的。c

如果未定义,稍后您将收到链接器错误。不出所料,链接器会说c未定义。

于 2012-07-16T15:29:52.133 回答
2

四句是声明,但前三句也是定义。

阅读此处了解声明和定义之间的区别。

autostaticregister是变量的修饰符。阅读有关它们的文档。

extern只是声明,因为您告诉编译器变量或函数的定义在其他地方-在另一个C模块中-。

希望能帮助到你!

于 2012-07-16T15:30:06.067 回答
2

前三个是定义,因为它将为变量留出存储空间。

最后一个不会为int c. 它只会使用在别处分配和命名的存储空间。

于 2012-07-16T15:30:39.450 回答