c-一个变量的多个实例(静态、非静态)



我发现了这段C代码:

main(){
static int i=0;
i++;
if(i<=5){
int i = 3;
printf(" %d",i);
main();
}
}

1。首先,由于变量i有多个定义,我预计此代码会出现编译错误。但是,它成功地编译并运行,并给出了这个输出。

3 3 3 3 3

2。观察输出,3正好打印了5次,这意味着循环从0计数到5,因此意味着对于if条件,使用i的第一个定义(静态)。

3但是,打印的值是3,这是i的第二个定义。

因此,变量标签i指的是内存中的两个不同实例。一个被用作循环计数,用于进行增量,另一个是正在打印的值。

我唯一能解释这一点的方法是:

  1. int i = 3(第二个定义)在每个递归调用中重复i实例在调用函数时创建,并在进行下一次递归调用时终止。(由于静态作用域)。printf使用这个实例,因为它是最新的定义(?)

  2. 当进入新的递归级别时,正在执行i++。由于没有其他方法可以解决此i,因此它使用i的静态"实例",该实例在代码中仍然"活动",因为它被定义为静态。

然而,我无法准确地了解这是如何工作的。。有人能解释一下代码和内存中发生了什么吗?

这里的编译器是如何进行变量绑定的?

内部作用域获胜。

示例:

int i = 1;
void foo() {
int i = 2; // hides the global i
{
int i = 3; // hides local i
}
}

这种行为是故意的。您可以为变量作用域使用不同的命名约定:

  • 全局/静态
  • 函数自变量
  • 当地人
  • 类/结构成员

如果在同一函数中隐藏变量(例如函数参数和正则局部变量),某些编译器会发出警告。因此,您的编译器达到了最大警告级别。

当存在多个同名变量时,编译器将始终使用该变量的最本地版本

在循环之外,第一个i是唯一存在的,因此它是被检查的。然后创建一个新的i,其值为3。在这一点上,每当你谈论i时,都会认为你指的是第二个,因为这更具地方性。当您退出循环时,第二个i将超出范围并被删除,因此如果您再次开始谈论i,它将是第一个。

if语句的{}创建了一个新的块作用域,当您在该作用域中声明i时,您将在外部作用域中隐藏i。新作用域直到{才开始,因此if语句引用的是外部作用域中的i

C99标准草案6.2.1标识符的范围段落4说明(emphasis mine):

[…]如果一个标识符指定了两个同名的不同实体空间,作用域可能重叠。如果是这样,一个实体的作用域(内部作用域)将是其他实体(外部范围)范围的严格子集。在内部范围内标识符指定在内部范围中声明的实体在外部作用域中声明的实体在内部作用域中隐藏(不可见)

最新更新