局部变量保留函数中的值

Local Variable retaining Value in Function

本文关键字:函数 保留 局部变量      更新时间:2023-10-16
#include<stdio.h>
void sum();
int main(){
sum();
sum();
sum();
sum();
}
void sum(){
int x;
x++;
printf("%dn",x);
}

此代码的输出(在 devc,代码块中(是:- 1 2,但我不明白为什么?? 因为变量 "x" 在超出范围时应该被销毁。

你所看到的是未定义行为的表现。

变量x未初始化,因此其值不确定。 然后尝试递增变量,该变量首先读取不确定值。 一旦你这样做了,你就无法预测你的程序会做什么。

在这种特殊情况下,每次调用sum堆栈时,它恰好位于内存中的同一位置,因此x之前的任何值都恰好仍然存在。 如果在对sum的调用之间添加了对printf的调用,则可能会看到不同的结果。

您正在使用未初始化的变量。这调用了未定义的行为,这意味着允许编译器做任何它想做的事情。

我复制粘贴了您的代码,对其进行了编译并运行了两次。结果如下:

/tmp$ ./a.out 
22012
22013
22014
22015
/tmp$ ./a.out 
21987
21988
21989
21990

如果将int x;更改为int x = 0(或任何其他值(,则每次调用函数时,它将打印相同的值。

C 标准并没有说一个对象在其生命周期结束时被销毁。它表示不再为对象保留存储。C 2018 6.2.4 2:

对象的生存期是程序执行期间保证为其保留存储的部分。

这意味着,当函数返回时,存储不会保留给x。但是,没有努力"破坏"或擦除它。如果稍后再次调用该函数时它碰巧具有相同的内容,那就这样吧。如果它碰巧被用于其他事情并因此更改,那就这样吧。

请注意,范围是错误的概念。范围是在源文本中标识符可见的位置。生存期是指在程序执行期间存在对象(在 C 计算模型中,意味着保留存储(。生存期和作用域之间存在某种关联,但自动对象将继续存在,直到其关联块的执行结束。

此外,还有关于使用未初始化对象的特殊规则(C 2018 3.19.3 1(。由于这些规则,它们可能不像普通内存那样工作,尤其是在受编译器优化影响时。未初始化的自动对象每次使用时都可能具有不同的值,即使没有对其内存进行明显的更改也是如此。使用未初始化的自动对象,其地址尚未被获取会导致 C 标准 (C 2018 6.3.2.1 2( 未定义的行为。