C中的For循环局部变量

为什么以下代码每次输出相同的内存位置?

int x; for (x = 0; x < 10; x++) { int y = 10; printf("%p\n", &y); } 

我认为每次运行for循环时内存位置都应该改变,变量是新的。

是的,你绝对正确的内存位置可能会改变。 但它没有:)。 在每次迭代中,旧变量被“销毁”,并且在同一位置“创建”新变量。 虽然任何体面的编译器都会优化不必要的“动作”

是的,每次变量都是新的,但是在块结束时,堆栈上的任何新变量都会再次释放。

因此,下一次堆栈指针返回到原来的位置。 注意:这种行为很常见,但标准并不能保证

这是一个编译器优化。 因为局部变量超出范围并且即将创建完全相同类型的变量,所以它重用了内存地址。 重要的是要注意,就程序而言,这仍然是一个“新鲜”或“新”的变量。

比较以下代码片段和输出:

 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

变量的范围规则仅描述您有权访问局部变量的范围:从定义到块的结尾。

这条规则没有说明为它留出空间的那一刻。 一种常见的策略是在函数开始时为一次调用函数所需的所有变量保留空间。

因此,当执行跨越变量的定义时,通常不需要特别做任何事情,而不是单个指令。 另一方面,这将该变量的值留给先前发现的值。 因此初始化为已知状态的重要性,正如您在示例中使用= 10所做的那样。