Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C内存中存储具有相同静态变量名的全局和局部变量? #包括 静态int a=5; main() { 静态积分a=15; printf(“%d\n”,a); }_C - Fatal编程技术网

如何在C内存中存储具有相同静态变量名的全局和局部变量? #包括 静态int a=5; main() { 静态积分a=15; printf(“%d\n”,a); }

如何在C内存中存储具有相同静态变量名的全局和局部变量? #包括 静态int a=5; main() { 静态积分a=15; printf(“%d\n”,a); },c,C,那么,这两个变量a是如何存储在内存中的呢 具有相同变量名的全局变量和局部变量如何存储在内存中?有趣的答案是它们存储在不同的位置 请记住,变量名(通常)不构成已编译程序的一部分,因此编译器只遵循变量阴影的正常规则。因此,在您的情况下,print函数(顺便说一句,这不是标准的C函数-您的意思是printf?)输出main中声明的a。使用相同的名称这一事实对编译器来说一点也不麻烦 最后,当在main中遇到另一个声明时,C无法访问全局作用域a,因为它是static。(这不是静态的,你可以使用extern

那么,这两个变量
a
是如何存储在内存中的呢


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

有趣的答案是它们存储在不同的位置

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


最后,当在
main
中遇到另一个声明时,C无法访问全局作用域
a
,因为它是
static
。(这不是静态的,你可以使用
extern
)看问题是范围,不要让它们搞砸了。第一个具有文件范围,另一个具有块范围。(它们是不同的变量-它们存储在不同的存储器中。)

当您在块中使用它时,编译器将检查该引用是否由同一块中的任何内容解析。它有一个。完成了

如果它在其他函数中,如果没有找到任何名为
a
,搜索将在文件范围内结束,在该范围内找到名称
a
。故事就这样结束了

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

在这里,如果您使用
-Wshadow
选项编译,它将警告您隐藏变量。您在该块上用内部阴影遮挡外部
a
。就这样

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

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

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

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


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

它们具有不同的作用域。您可以很好地说明这一点,但不要使用
%d
打印指针地址:这是未定义的行为!你会有落选的选民在你之后。谢谢你改变了这一点。(你注意到输出值是如何变化的吗?让我们保守秘密。)投票吧。你忘记了
void*
cast-这是必需的。@sudeepattel:不-一点也不。由于
static
链接说明符,变量
a
具有内部链接。删除
静态
限定符将使其具有外部链接-不需要使用
外部
关键字,但不会导致错误(可能会导致警告,因为这是对
外部
的不寻常和不必要的使用)。当然,它不能同时是
静态
外部
,因为它们指定了相反的链接。既然你没有说错误是什么,我只能猜测了。
#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