为什么编译器在重新定义变量后会为同一个变量分配不同的内存地址?

Why did the compiler assign different memory address to the same variable, after re-defining the variable?

代码如下:

#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>5 在第一次迭代后。但令我惊讶的是输出如下:

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

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

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

Why is the compiler considering the initial defined variable i while executing i<5;i++ instruction and, not the re-defined variable i? (after first iteration).

因为重新定义的(阴影)变量不在范围内。如果删除第一个定义,则会出现 "identifier undeclared" 错误。这在循环的第一次迭代后也不会改变,因为它是在编译时确定的。

2) Why did compiler assign different memory address to same variable identifier i?

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


另一方面,循环末尾的 i++; 没有效果,因为它影响循环内的 i,它在 i++; 之后立即超出范围.这与for (i = 0; i < 5; i++)中的i++;不同,它增加了外i.

你有两个不同的变量都命名为 i,所以显然情况会很混乱!对于程序中的每一个i,我们都要问:这是"outer"i,还是"inner"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 < 5; i++) 无疑使用了 outer i.