变量范围行为c语言

时间:2015-05-15 18:01:35

标签: c scope

代码段:

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

每次重启循环时,变量i都存储在堆栈中? 运行此代码时的内存结构是什么? 这个变量的行为是什么? 这样做是不好或好的做法?

感谢。

4 个答案:

答案 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;
    }
}