4

以下是代码,我将其作为参考,以了解{}函数中存在的子作用域(或)虚拟作用域(just)如何影响堆栈帧的结构。

#include <stdio.h>
int main()
{
   int main_scope=0; /*Scope and life time of the variable is throughout main*/

   {
     //From below two statements I assume that there
     //is no seperate "stack frame" created for just
     //braces {}.So we are free access (scope exists) and
     //modify (lifetime exists) the variable "main_scope"
     //anywhere within main

     main_scope++;
     printf("main_scope++:(%d)\n",main_scope);

    //I expected this statement to throw an error saying
    //"Multiple definition for "main_scope".But it isn't????

    int main_scope=2;
    printf("Value of redefined main_scope:(%d)\n",main_scope);

  }

  printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
  return 0;
}

样本输出

main_scope++:(1)
Value of redefined main_scope:(2)
Finally main_scope in main:(1)

基于上述行为,我推测如下。

  • 没有为范围创建堆栈帧{}
  • 通过这种方式auto,声明/定义的变量main和子范围内的变量{}共享相同的堆栈帧。
  • main因此,在函数内的任何地方(甚至在子范围内)都可以自由访问声明/定义的变量。
  • 另一方面,在子作用域中声明/定义的变量在块外失去了作用域。但只要堆栈帧存在,它的生命周期就有效。

问题:如果上述几点是正确的,那么为什么在给出同一个变量的多个定义时代码没有失败,一个是 within main,另一个是 within {}

4

2 回答 2

2

硬件堆栈在这里无​​关紧要。对于函数入口处的所有局部变量,它只能增长一次,而在函数退出时只能收缩一次,或者每次定义新的局部变量时它可以增长和收缩,并在其封闭的 {} 离开时销毁。

相关的是变量的“可见性”。

int main_scope=0;

{
    main_scope++;
    printf("main_scope++:(%d)\n",main_scope);
    // the main_scope variable that was assigned 0 is the most recent
    // visible declaration of main_scope.

    int main_scope=2;
    // now, the previous declaration of main_scope is obscured by the new one,
    // and so, you're going to access the new one
    printf("Value of redefined main_scope:(%d)\n",main_scope);
}

printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
// the previous scope inside {} is left, so, main_scope is going to be
// the one, to which we assigned 0

在内部/子范围中定义与外部/超范围同名的对象是完全合法的。后者将在 {} 范围内被遮挡。

仅供参考,还有其他一些地方可能会出现变量定义,例如在for(;;)语句的第一个表达式中:for (int i = 0; i < 10; i++) .... 该变量i仅在 for 的主体内可见,您也可以通过定义另一个来将其隐藏在那里i

于 2012-10-13T13:41:59.623 回答
1

局部变量隐藏了外部变量main_scope

int main()
{
    int i=1;
    {

      int i=2;
      printf("%d", i);
      /* Whenever you use i here, it's always the local one that's used. 
      The outer i is hidden by the local i. But the local i will be deallocated 
      once the scope exits.*/
    } 
}

在 C 中是完全合法的。(请注意,这在 C++ 中是非法的!)

在您的示例中,肯定会为 inner 创建一个堆栈帧main_scope,但是一旦程序超出该内部范围,它将被释放。

于 2012-10-13T13:42:12.527 回答