【问题标题】:Why did the compiler assign different memory address to the same variable, after re-defining the variable?为什么编译器重新定义变量后,给同一个变量分配不同的内存地址?
【发布时间】:2020-02-06 10:18:30
【问题描述】:

代码如下:

#include <stdio.h>
int main()
{
    int i;
    printf("%p\n",&i);
    for (i = 0; i < 5; i++)
    {
        int i = 10;
        printf("%d %p\n", i,&i);
        i++;
    }
    return 0;
}

首先我们定义了一个变量i(就在main之后)。然后在for 循环的开始,我们再次定义了相同的变量i。因此,在for 循环内,i 的值为 10。for 循环必须只迭代一次,因为i&gt;5 在第一次迭代之后。但令我惊讶的是,输出如下:

0x7ffe8b799da0
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4

我的问题是:
1)为什么编译器在执行i&lt;5;i++指令时考虑初始定义变量i,而不是重新定义变量i? (第一次迭代后)。

2) 为什么编译器给同一个变量标识符i分配不同的内存地址?

【问题讨论】:

标签: c memory scope shadowing


【解决方案1】:

为什么编译器会考虑初始定义的变量 i 而 执行 i

因为重新定义的(阴影)变量尚未在范围内。如果删除第一个定义,则会收到“未声明的标识符”错误。这在循环的第一次迭代后也不会改变,因为它是在编译时确定的。

2) 为什么编译器给同一个变量分配不同的内存地址 标识符 i?

即使您无法访问循环内的外部int i,因为第二个隐藏了它,它仍然存在,因此需要自己的内存。它不会被另一个int i 覆盖。您可以通过在循环后添加 printf("%d\n", i); 来看到这一点 - 它将打印 5,因为这是循环后 i 的值。


另一方面,循环末尾的i++; 无效,因为它会影响循环内的i,它在i++; 之后超出范围。这与for (i = 0; i &lt; 5; i++) 中的i++; 不同,后者增加了外部i

【讨论】:

    【解决方案2】:

    你有两个不同的变量,都命名为i,所以显然情况会很混乱!对于程序中的每个i,我们都要问:这是“外部”i,还是“内部”i

    这又是你的程序,为清楚起见重命名了变量:

    #include <stdio.h>
    int main()
    {
        int i1;
        printf("%p\n",&i1);
        for (i1 = 0; i1 < 5; i1++)
        {
            int i2 = 10;
            printf("%d %p\n", i2,&i2);
            i2++;
        }
        return 0;
    }
    

    对于您的具体问题,循环运行 5 次的原因是循环控制 for (i = 0; i &lt; 5; i++) 无疑使用 外部 i

    【讨论】:

      猜你喜欢
      • 2013-08-29
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多