代码段:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
每次重启循环时,变量i
都存储在堆栈中?
运行此代码时的内存结构是什么?
这个变量的行为是什么?
这样做是不好或好的做法?
感谢。
答案 0 :(得分:4)
您永远不会触及i == 500.
每次循环都会被重置,因为它在while(1){}.
范围内
以下内容可行。
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}
答案 1 :(得分:1)
当函数在C中运行时,它会为其需要的所有局部变量分配空间。如果变量在函数顶部彼此相邻地分配,则很容易看出它是如何工作的:
void foo(){
int x;
int y;
y = 1;
x = y + 2;
return x + y;
}
如果变量是在函数的内部块中声明的,那么编译器所做的就是将这些变量声明“提升”到函数的顶部。如果存在具有冲突名称的变量,则编译器会为您重命名,以便它们引用正确的变量。
// This is what you write
void original(){
int x = 0;
while(1){
int x = 1;
}
}
// This is what the compiler "sees"
void lifted(){
int x1;
int x2;
x1 = 0;
while(1){
x2 = 0;
}
}
在您的情况下,您的代码的行为与此类似:
void function(void)
{
int i;
while(1)
{
i = 0;
i += 1;
if(i == 500) break;
}
}
在这个版本中,它清楚地表明i一直被重置为0,这就是循环将永远运行的原因。
至于在内部范围内声明变量是否是一种好的做法,它与内存使用无关,而与变量名的范围有关。一般来说,如果可能的话,将变量局限于内部范围是一件好事(出于同样的原因,局部变量优先于全局变量)。也就是说,你总是必须在循环之前初始化你的变量而不是在它里面。在这种情况下,它关于删除错误而不是最佳实践。
答案 2 :(得分:1)
从逻辑上讲,循环的每次迭代都会创建i
变量的新实例,该实例仅存在于循环体内。如上所述,此代码永远不会终止,因为while
循环的每次迭代都会创建i
的新实例并将其初始化为0
。
尝试在循环体外引用i
会导致未定义的行为; IOW,代码如
int *p;
while ( 1 )
{
int i = 0;
p = &i;
if ( some_condition )
break;
...
}
printf( "last value of i was %d\n", *p );
并不保证能够达到您的预期。
实际上,生成的机器代码会在函数输入时留出i
的空格;但是,你不应该依赖这种行为。
答案 3 :(得分:0)
此代码中变量i将始终为0或1;休息永远不会执行。
变量i在声明中并且是while循环的本地变量。
在C语言中,一对大括号可以创建一个新范围 隐藏变量,使用在。之外声明的相同名称 范围。
此代码:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
应改为:
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}