为什么以下代码每次输出相同的内存位置?
int x;
for (x = 0; x < 10; x++) {
int y = 10;
printf("%p\n", &y);
}
我认为每次运行for循环时内存位置都应该改变,变量是新的。
答案 0 :(得分:18)
是的,内存位置 可以 更改是完全正确的。但它没有:)。在每次迭代中,旧变量被“销毁”,并且在同一位置“创建”新变量。虽然任何体面的编译器都会优化不必要的“行动”
答案 1 :(得分:5)
是的,每次变量都是新的,但是在块结束时,堆栈中的任何新变量都会再次释放。
因此,下一次堆栈指针回到原来的位置。注意:这种行为很常见,但标准无法保证。
答案 2 :(得分:3)
这是一个编译器优化。因为局部变量超出范围并且即将创建完全相同类型的变量,所以它重用了内存地址。值得注意的是,就您的计划而言,这仍然是一个“新鲜”或“新”的变量。
比较以下代码段和输出:
for (i = 0; i < 3; i++) {
int n = 0;
printf("%p %d\n", (void *)&n, n++);
}
0x7fff56108568 0 0x7fff56108568 0 0x7fff56108568 0
for (i = 0; i < 3; i++) {
static int n = 0;
printf("%p %d\n", (void *)&n, n++);
}
0x6008f8 0 0x6008f8 1 0x6008f8 2
答案 3 :(得分:0)
变量的范围规则仅描述您有权访问局部变量的范围:从定义到其块的结尾。
这条规则没有说明为它预留空间的那一刻。一个常见的策略是为函数开头一次调用函数所需的所有变量保留空间。
因此,当执行跨越变量的定义时,通常不需要特别做任何事情,而不是单个指令。另一方面,这将该变量的值留给先前发现的值。因此,初始化为已知状态的重要性,正如您在示例中使用= 10
。