You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C语言函数f()二次及三次调用时未初始化i值可预测?

未初始化局部变量为何保留之前函数调用的数值?

问题描述

无法理解为何函数f()第二次调用时,未初始化的变量i的值为1234?原以为第一次f()执行完毕后,其栈帧会被弹出,此时i应是不可预测的值。同样,在调用g(5432)后第三次调用f()时,i的值突然变为5432,这是为什么?

代码示例

void f();
void g(int);

void main() {
    f();
    f();
    g(5432);
    f();
}

void f() {
    int i;
    printf("%d\n", i);
    i = 1234;
}

void g(int val) {
    printf("%d\n", val);
}

运行输出

0
1234
5432
5432

原因解释

  • 局部变量的存储特性:C语言中未初始化的局部变量属于自动存储类别,默认存在栈内存里。函数调用时会为局部变量分配栈帧,函数返回后,栈指针只是向上移动标记栈帧可复用,不会主动清空栈内的数据——之前存储的值会保留到被新数据覆盖为止。
  • 第一次调用f():此时i所在的栈内存是未初始化的随机值(本次输出0是环境栈初始化为0的结果,换个环境可能是其他数值),随后i被赋值为1234。函数返回后,栈里的1234并没有被清除。
  • 第二次调用f():函数再次分配栈帧时,刚好复用了第一次f()用的栈空间,i所在的内存位置还留着之前的1234,所以输出这个值。
  • 调用g(5432):函数g的参数val会存在栈内存中,输出后函数返回,栈里对应位置保留着5432。
  • 第三次调用f():再次复用栈空间时,i的位置刚好对应之前g参数val的存储位置,所以输出5432。

要特别注意:这种行为属于C标准定义的未定义行为,换个编译器、优化等级或者操作系统,运行结果可能完全不同,绝对不能在实际代码里依赖这种特性。

内容的提问来源于stack exchange,提问作者Disdainty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:05:01