我有一个关于范围规则的非常基本的问题。在循环中声明变量时,请说:
while ( /*some condition*/ )
{
int a = 0;
//Remaining operations
}
是否在循环的每次迭代中声明了一个新的int
变量?或者是a
在每次迭代结束时被销毁并再次重新创建? Java或C ++中的编译器如何理解和实现它?
答案 0 :(得分:3)
您必须区分逻辑级别和实现级别。
从逻辑的角度来看,变量并非真正“创建”或“被破坏”,但这就是你可能想象的结果。该变量只是在范围中声明,因此它保证存在(你可以分配给它并读取它的值),它在块的开头被初始化(所以它具有值0
),并且在代码块之外不是可见。这就是语言定义所说的内容。在C ++中,如果省略初始化(即=0
部分),则语言不会对值是什么做出任何假设(因此编译器可以“重用”内存位置)。在Java中,afair,初始化是隐式的,因此如果省略初始化,a
也将设置为零。
在实现级别,只要符合上述规范,编译器或多或少可以自由地执行任何操作。所以在实践中,它很可能会在堆栈上保留一些空间,并在每次迭代时使用相同的内存来存储a
的值。由于您已经使用了初始值设定项,因此值0
将在每个循环开始时写入此位置。请注意,如果范围内未使用a
,编译器也可以自由地简单地对其进行优化。或者,如果可能,它可以将其分配给CPU寄存器。
然而,从理论上讲,编译器还可以在每次迭代中为a
保留一个“新的”内存位置,并在循环结束时清除所有这些内存位置(尽管这可能导致StackOverflow(!)很长时间循环......)。或者使用垃圾收集的动态内存分配(这会导致性能不佳......)。
答案 1 :(得分:2)
我发现将a
视为同一个被重复创建和销毁的变量更容易。
答案 2 :(得分:2)
基本上,a是一个局部变量,它在循环中的每次迭代中初始化为0,然后销毁,依此类推,直到循环完成时最终被销毁
注意:
while(//Some Condition)
会注释掉右括号,因此代码也不会运行
将此更正为:
while(/* some condition */)
答案 3 :(得分:1)
仅在源代码中声明。在字节码中,它只是在堆栈上使用一个局部变量,它将在每次迭代时初始化为0。与循环外的声明的区别在于,当它在内部循环中时,JVM将重用a
占用的变量。
答案 4 :(得分:1)
a
在每次迭代后创建并销毁。