变量作用域行为c语言

变量作用域行为c语言,c,scope,C,Scope,代码段: void function(void) { while(1) { int i = 0; i += 1; if(i == 500) break; } } 每次重新启动循环时,变量i都存储在堆栈中? 运行此代码时的内存结构是什么? 这个变量的行为是什么? 这样做是好还是坏 谢谢。你永远不会到达i==500。它每次通过循环都会被重置,因为它在的范围内,而(1){}。 以下内容将起作用 void function(

代码段:

void function(void)
{
    while(1)
    {
         int i = 0;
         i += 1;
         if(i == 500) break;
    }
}
每次重新启动循环时,变量
i
都存储在堆栈中? 运行此代码时的内存结构是什么? 这个变量的行为是什么? 这样做是好还是坏


谢谢。

你永远不会到达
i==500。
它每次通过循环都会被重置,因为它在
的范围内,而(1){}。

以下内容将起作用

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

你永远不会到达
i==500。
每次通过循环都会重置它,因为它在
的范围内,而(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;
    }
}

在这段代码中,变量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中运行时,它会为它需要的所有局部变量分配空间。如果变量在函数顶部彼此相邻分配,则很容易看到其工作原理:

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,这就是为什么循环将永远运行



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

当一个函数在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,这就是为什么循环将永远运行



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

从逻辑上讲,循环的每次迭代都会创建一个只存在于循环体中的
i
变量的新实例。如前所述,此代码永远不会终止,因为
while
循环的每次迭代都会创建
i
的新实例,并将其初始化为
0

试图在循环体外部引用
i
会导致未定义的行为;瞧,像代码一样

int *p;
while ( 1 )
{
  int i = 0;
  p = &i;
  if ( some_condition )
    break;
  ...
}

printf( "last value of i was %d\n", *p );
不能保证做你想做的事


实际上,生成的机器代码将在功能输入时为
i
留出一次空间;然而,你不应该依赖这种行为

从逻辑上讲,循环的每次迭代都会创建一个仅存在于循环体中的
i
变量的新实例。如前所述,此代码永远不会终止,因为
while
循环的每次迭代都会创建
i
的新实例,并将其初始化为
0

试图在循环体外部引用
i
会导致未定义的行为;瞧,像代码一样

int *p;
while ( 1 )
{
  int i = 0;
  p = &i;
  if ( some_condition )
    break;
  ...
}

printf( "last value of i was %d\n", *p );
不能保证做你想做的事


实际上,生成的机器代码将在功能输入时为
i
留出一次空间;然而,你不应该依赖这种行为

i
永远不会达到500杜德
i
永远不会达到500dude@X0R40你无论如何也不会那样做。你应该做
while(我希望尽可能接近提供的示例OP,以便他/她更容易理解。当然,这就是为什么我向上投票并向OP发表我的评论。啊,对不起。我的错误。@X0R40你无论如何都不会这么做。你应该做
while(我希望尽可能接近提供的示例OP,以便他/她更容易理解。当然,这就是为什么我向OP投票并发表我的评论。啊,对不起。我的错误。@Bode
I
将在作用域启动时创建?(我的意思是,当作用域启动时,将为
I
保留一个内存空间)@X0R40:实际上,
i
的内存将在函数输入时留出一次。但是,代码的行为将如同在循环的每次迭代中创建和销毁一个新实例一样。@Bode
i
将在