全局和局部具有相同的静态变量名如何存储在 C 内部内存中


#include<stdio.h>
static int a=5;
main()
{
     static int a=15;
     printf("%dn",a);
}

那么,如何将这两个变量a存储在内部存储器中呢?

具有相同变量名称的全局变量和局部变量如何存储在内存内部?

#include<stdio.h>
static int a=5;
int main()
{
    printf("%pn",(void *)&a);
    static int a=15;
    printf("%pn",(void *)&a);
    return 0;
}

上层程序的输出为

0x564e6b67a030
0x564e6b67a034

因此,您可以看到两者都存储在不同的地址中。因为一个是全局变量,另一个是局部变量。

这些名称仅对人类读者和将该代码转换为机器可执行代码的编译器/链接器感兴趣。 最终目标代码将这些解析为地址,并且名称不再存在。

编译器以与您相同的方式区分它们 - 通过作用域;当同一命名空间中的两个相同符号同时在作用域中时,具有最严格作用域的符号是可见的(即可以通过名称访问(。

对于具有外部链接的符号(在您的示例中没有其他符号,只有 main (,编译器保留符号名称以解析单独编译的模块之间的链接。 在完全链接的可执行文件中,符号名称不复存在(调试构建符号元数据除外(。

问题是范围不要让他们搞砸。第一个具有文件范围,另一个具有块范围。(它们是不同的变量 - 它们存储在单独的内存中。

在块中使用它时 - 编译器会检查此引用是否由同一块中的任何内容解析。它得到一个。并完成了。

如果它在其他函数中 - 如果它没有找到任何名为 a 的内容 - 搜索将在文件范围内结束,在那里它找到名称 a .故事到此结束。

两者都是静态的,它们的存储持续时间是相同的。他们一直活到程序存在。但它们的范围是不同的。如果范围也相同 - 编译器会向您显示错误消息。

在这里,如果您使用-Wshadow选项进行编译 - 它会警告您有关隐藏变量的信息。你用内在的那个块上阴影了外a。就是这样。

滑稽的答案是它们存储在不同的地方。

请记住,变量的名称(通常(不构成已编译程序的一部分,因此编译器仅遵循变量阴影的正常规则。所以在你的例子中,你的print函数(顺便说一下,这不是一个标准的 C 函数 - 你的意思是printf?(输出在 main 中声明的a。您使用相同的名称这一事实根本不会打扰编译器。

最后,C 无法amain 中遇到其他声明,因为它static。(它不是静态的,你可以使用extern。请参阅如何在 C 语言中访问阴影全局变量?

最新更新