局部变量保留函数中的值
Local Variable retaining Value in Function
#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( 未定义的行为。
- 保留对其他类的成员函数的引用
- 局部变量保留函数中的值
- 保留函数指针模板参数
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- 如何使用 swig 修改类构造函数以保留对其中一个构造函数参数的引用?
- 将成员函数保留为未定义
- C++:如何为多个重载函数保留通用代码路径?
- 我应该保留这个函数来查找第 n 个素数还是可以优化?
- 函数,该函数将在堆栈底部保留最小的出现次数
- 如何在共享库中保留静态库中的自由函数
- 保留的函数名称可以重载吗?
- OMNET++ 如何保留 AODVRouting 类中的所有函数,但仅覆盖发送 AODVPacket 函数?
- 如果引用应该保留,不删除析构函数中的指针会导致内存泄漏吗?
- 我的单例中的数组在离开函数后没有保留信息,然后在尝试再次访问信息时崩溃
- openCV Mat 中的值在自定义类构造函数中设置后不会保留
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 内联函数是否在内联函数中保留其上下文
- 如何在内联程序集中调用函数时保留堆栈
- 如何为同一类对象的成员函数保留单独的变量副本?
- 即使阵列腐烂到指针,如何将函数的参数保留为数组,这很好