【问题标题】:Multiple variables have the same address, yet they don't?多个变量具有相同的地址,但它们没有?
【发布时间】:2016-04-01 17:58:20
【问题描述】:

我只是在 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);

它将向我显示其中一个地址,这也是预期的。但是,如果我删除变量“x”,并使用另一个变量,如“y”或“z”,它将显示与“x”完全相同的地址。这怎么可能?

所以基本上,当您检查同一代码中所有变量的地址时,每个变量的地址都会不同。如果您分别检查它们中的每一个,它们将具有完全相同的地址。

PS:这只发生在整数和浮点数上,我用 char 尝试了同样的方法,每个变量都给出了一个单独的地址。

【问题讨论】:

  • 编译器会剔除未使用的变量
  • 答案似乎没有回答问题,我理解这意味着您已经从代码中完全删除了x,而y 现在拥有x 之前的地址。 " 如果我​​删除变量 x..." 想象一个倾斜的架子,上面放着 3 个杯子。当您移除最低的杯子时,其他杯子会向下滑动以占据之前使用的空间。
  • 添加几行代码,确保所有三个变量都被使用 x += y; x += z; 然后尝试打印单个变量地址并查看差异。

标签: c


【解决方案1】:

编译器正在优化代码中未使用的变量。这是dead code elimination

所以当你有这样的代码时

int main()
{
    int x=5;
    int y=4;
    int z=8;

    printf("%p\n",&z);
}

编译器可以告诉您从不使用 x 或 y,因此可以从编译对象中删除该代码。这使您生成的代码更快并生成更小的对象大小。

【讨论】:

    【解决方案2】:

    很可能,编译器正在消除未使用的变量。因此,只会创建您调用打印的那些。

    【讨论】:

      【解决方案3】:

      "但是,如果我删除变量“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 位编译)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-12
        • 2014-08-07
        • 2020-03-22
        • 2015-10-25
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        • 2016-09-28
        相关资源
        最近更新 更多