C语言的auto型变量存储在内存哪里?

99ANYc3cd6
预计阅读时长 11 分钟
位置: 首页 C语言 正文

核心答案

C语言中的auto型变量(即局部变量自动变量)存储在上。

c语言的auto型变量是存储在
(图片来源网络,侵删)

详细解释

为了更好地理解,我们需要从几个方面来展开:

什么是 auto 关键字?

在C语言中,auto 是一个存储类型说明符,但它非常特殊。在所有函数内部声明的变量,如果没有使用 staticextern 等其他存储类型修饰符,那么它们默认就是 auto 类型的。

当你写下这样的代码时:

void myFunction() {
    int a;      // 这里的 'a' 默认就是 auto 类型
    float b;    // 这里的 'b' 也是 auto 类型
    auto int c; // 显式声明,效果和 int c; 完全一样
}

变量 abc 都是 auto 变量,在实际编程中,几乎没有人会显式地写出 auto 关键字,因为默认就是它,我们通常直接称之为局部变量

c语言的auto型变量是存储在
(图片来源网络,侵删)

为什么 auto 变量存储在栈上?

这与其生命周期和作用域密切相关。

  • 作用域auto 变量的作用域仅限于声明它的代码块(通常是函数体或 包围的区域),一旦程序执行离开这个代码块,该变量就变得不可访问。
  • 生命周期auto 变量的生命周期与它的作用域绑定,当进入其作用域时(调用函数时),变量被创建;当离开作用域时(函数返回时),变量被销毁。

这种“进入时创建,离开时销毁”的特性,完美契合了这种数据结构的特点。

栈 是什么?

栈是一种后进先出 的数据结构,可以把它想象成一叠盘子。

  • 压栈:当调用一个函数时,系统会为这个函数在栈顶分配一块内存空间,用于存放它的参数、返回地址和所有的 auto 变量,这个过程称为“压栈”或“入栈”。
  • 弹栈:当函数执行完毕返回时,这块内存空间会被自动释放,这个过程称为“弹栈”或“出栈”。

由于后调用的函数先返回,它的内存空间先被释放,这完全符合 LIFO 原则。

代码示例

让我们通过一个简单的例子来直观感受这个过程:

#include <stdio.h>
void functionB() {
    int b = 20; // 'b' 是一个 auto 变量,存储在 functionB 的栈帧中
    printf("In functionB: b = %d\n", b);
} // functionB 执行完毕,变量 b 的内存被自动释放
void functionA() {
    int a = 10; // 'a' 是一个 auto 变量,存储在 functionA 的栈帧中
    printf("In functionA: a = %d\n", a);
    functionB(); // 调用 functionB
} // functionA 执行完毕,变量 a 的内存被自动释放
int main() {
    // main 函数也有自己的栈帧
    int main_var = 0; // main_var 也是一个 auto 变量
    printf("In main: main_var = %d\n", main_var);
    functionA(); // 调用 functionA
    printf("Back in main: main_var = %d\n", main_var);
    return 0;
}

内存变化过程:

  1. 程序开始:操作系统为 main 函数创建一个栈帧。
  2. 进入 main:在 main 的栈帧中创建 main_var
  3. 调用 functionA:在栈顶为 functionA 创建一个新的栈帧,在其中创建变量 a
  4. 调用 functionB:在栈顶为 functionB 再创建一个新的栈帧,在其中创建变量 b
  5. functionB 返回functionB 的栈帧被销毁,变量 b 消失。
  6. functionA 返回functionA 的栈帧被销毁,变量 a 消失。
  7. main 返回main 的栈帧被销毁,程序结束。

此时的栈结构就像这样:

      (栈顶)
    +-------------------+
    | functionB 的栈帧  |  <-- 存放变量 b
    +-------------------+
    | functionA 的栈帧  |  <-- 存放变量 a
    +-------------------+
    |     main 的栈帧   |  <-- 存放 main_var
    +-------------------+
      (栈底)

与其他存储类型的对比

为了更清晰地理解 auto,我们可以将它与其他存储类型进行比较:

存储类型 关键字 存储位置 生命周期 作用域 示例
自动变量 auto (默认) 函数调用期间 局部(代码块) 函数内的普通变量
静态局部变量 static 静态存储区 / 数据段 整个程序运行期间 局部(代码块) static int count = 0;
全局变量 (无) 静态存储区 / 数据段 整个程序运行期间 全局(整个文件) int global_var;
寄存器变量 register CPU寄存器 (理想情况下) 函数调用期间 局部(代码块) register int i;

关键区别:

  • auto vs static:最大的区别在于生命周期。auto 变量是“临时的”,函数调用结束就消失;static 变量是“持久的”,函数调用结束后它的值仍然保留,下次调用时仍能使用上次留下的值。
  • auto vs registerregisterauto 的一种特殊形式,它建议编译器将变量存储在速度更快的 CPU 寘存器中,而不是内存(栈)中,但这只是建议,编译器可以忽略,它不能取地址。
  • auto 型变量就是局部变量,是C语言的默认行为。
  • 它们存储在上。
  • 栈的后进先出 特性完美匹配了函数调用和返回的机制,使得局部变量的管理(创建和销毁)非常高效。
  • 离开变量的作用域(通常是函数返回)后,其占用的栈空间会被自动释放,变量也就失效了。
-- 展开阅读全文 --
头像
织梦文章首行缩进怎么设置?
« 上一篇 01-10
dede自定义表单短信验证码
下一篇 » 01-10

相关文章

取消
微信二维码
支付宝二维码

目录[+]