我只是在C上闲逛,因为我刚刚学到了更多关于指针的知识。但我主要关注的是地址问题,我只是查看随机变量地址,这就是我发现的内容。
#include<stdio.h>
#include<conio.h>
int main()
{
int x=5;
int y=4;
int z=8;
printf("%p\n",&x);
printf("%p\n",&y);
printf("%p\n",&z);
}
此代码显示3个不同的地址,这是预期的。如果我只有一个printf语句,就像这样
printf("%p\n",&x);
它会显示其中一个地址,也是预期的。但是,如果我删除变量&#39; x&#39;,并使用其他变量,例如&#39; y&#39;或&#39; z&#39;,它会显示完全相同的地址& #39; X&#39;了。怎么可能?
所以基本上,当你检查所有的变量&#39;在相同代码中的地址,每个地址都有不同的地址。如果您分别检查每一个,它们将具有完全相同的地址。
PS:这只发生在整数和浮点数上,我尝试使用char,每个变量给出一个单独的地址。
答案 0 :(得分:4)
编译器正在优化代码中未使用的变量。这是dead code elimination。
所以当你有这样的代码时
int main()
{
int x=5;
int y=4;
int z=8;
printf("%p\n",&z);
}
编译器可以告诉您永远不要使用x或y,因此可以从编译对象中删除该代码。这使您生成的代码更快,并生成更小的对象大小。
答案 1 :(得分:2)
编译器可能正在消除未使用的变量。因此,只有你要打印的那些才会被创建。
答案 2 :(得分:1)
“但是,如果我删除变量'x',并使用另一个变量,如'y'或'z',它将显示与'x'完全相同的地址。 “
这与其他答案建议的优化无关,但结果是相同的:在第二次测试中,你没有声明你的变量。您的程序看起来像
int main()
{
//int x=5; // commented out
int y=4;
int z=8;
//printf("%p\n",&x); // commented out
printf("%p\n",&y);
printf("%p\n",&z);
}
对于每个变量,编译器保留空间(此处:在堆栈上),并且此编译器显然按照它遇到您的声明的顺序执行此操作(几乎所有编译器都这样做)。 x
不再被声明,所有后续变量只是在地址空间中向上移动。
请注意,它对所有变量,char
变量也是如此。但对于char
变量,您通常会给出一个大小。考虑:
char s1[10];
char s2[10];
char s3[10];
和
//char s1[10]; // commented out
char s2[10];
char s3[10];
在第一个示例中,第二个示例的 s2
与s1
具有相同的地址,因为所有这些s
变量的大小相同。如果它们的大小不同,您会看到不同的地址,但是您可以根据它们的大小来计算这些差异。 (注意:“填充”可以在这里发挥作用,编译器分配的次数略多于声明,因此下一个变量从4字节/ 8字节边界开始(4:32位编译; 8:64位编译)。