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

问题描述 投票:1回答:4
#include<stdio.h>
static int a=5;
main()
{
     static int a=15;
     printf("%d\n",a);
}

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

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

c
4个回答
1
投票
#include<stdio.h>
static int a=5;
int main()
{
    printf("%p\n",(void *)&a);
    static int a=15;
    printf("%p\n",(void *)&a);
    return 0;
}

上层程序的输出是

0x564e6b67a030
0x564e6b67a034

所以你可以看到它们都存储在不同的地址中。一个是全局变量,另一个是本地变量。


1
投票

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

编译器以同样的方式区分这些 - 按范围;当同一名称空间中的两个相同符号同时在范围内时,具有最大限制范围的符号是可见的(即可以通过名称访问)。

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


0
投票

事情是范围不要让他们陷入困境。第一个具有文件范围,另一个具有块范围。 (它们是不同的变量 - 它们存储在不同的存储器中。)

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

如果它在某个其他函数中 - 如果它没有找到任何名为a的东西 - 搜索在文件范围内结束,它找到名称a。这就是故事的结局。

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

在这里,如果您使用-Wshadow选项进行编译 - 它将警告您关于变量的阴影。你用那个街区的内部遮住了外面的a。而已。


0
投票

讽刺的答案是它们存放在不同的地方。

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

最后,一旦在a中遇到另一个声明,C就无法访问全局范围的main,因为它是static。 (你可以使用extern不是静态的。)见How can I access a shadowed global variable in C?

© www.soinside.com 2019 - 2024. All rights reserved.