为什么以下代码每次输出的都是同一个内存地址?
int x;
for (x = 0; x < 10; x++) {
int y = 10;
printf("%p\n", &y);
}
我原本认为每次运行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
一样。