变量作用域行为c语言

Variable scope behavior c language

代码片段:

void function(void)
{
    while(1)
    {
         int i = 0;
         i += 1;
         if(i == 500) break;
    }
}

变量i每次重新开始循环时都存储在堆栈中? 运行这段代码的内存结构是什么? 这个变量的行为是什么? 这样做是坏习惯还是好习惯?

谢谢。

你永远达不到i == 500.因为它在while(1){}.

的范围内所以每次循环都会被重置

以下将起作用。

void function(void)
{
    int i = 0;
    while(1)
    {
         i += 1;
         if(i == 500) break;
    }
}

在此代码中,变量 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;
    }
}

当 C 中的函数 运行 时,它会为所有需要的局部变量分配 space。如果变量在函数顶部彼此相邻分配,则很容易看出它是如何工作的:

void foo(){
    int x;
    int y;

    y = 1;
    x = y + 2;
    return x + y;
}

如果变量是在函数的内部块内声明的,编译器所做的是 "lift" 将那些变量声明到函数的顶部。如果存在名称冲突的变量,编译器会为您重命名,以便它们引用正确的变量。

// 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,这就是循环将永远 运行 的原因。


至于在内部范围内声明变量是否是一个好习惯,它与内存使用无关,而与变量名的范围有关。一般来说,如果可能的话,将变量限制在内部范围内是一件好事(出于与局部变量优于全局变量的相同原因)。也就是说,您始终必须在循环之前而不是在循环内部初始化变量。在这种情况下,它是关于消除错误而不是成为最佳实践。

从逻辑上讲,循环的每次迭代都会创建一个 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留出一次space;但是,您不应该依赖这种行为。