按月配资
#include
// 函数外定义变量 x 和 y
int x;
int y;
int addtwonum
{
// 函数内声明变量 x 和 y 为外部变量
extern int x;
extern int y;
// 给外部变量(全局变量)x 和 y 赋值
x = 1;
y = 2;
return x+y;
}
int main
{
int result;
// 调用函数 addtwonum
result = addtwonum;
printf("result 为: %d",result);
return 0;
}
咱们先把这段代码比作一个小公司的办公场景:全局变量像公司的公共打印机,局部变量像员工自己的笔记本,而函数调用就像员工去会议室开会 —— 这样理解内存分配就简单多了。
先给代码做个 "体检报告"
这段段代码做的事儿特简单:定义了全局变量x和y,在函数里给它们赋值后相加,最后输出结果。运行结果肯定是3,但咱们今天不关心结果,专注看内存里发生了啥。
内存里的 "两大区域":栈(Stack)和堆(Heap)
C 语言的内存主要分这两大块,用途完全不同:
栈(Stack):像公司的 "临时会议室",自动分配自动释放,存放局部变量和函数调用信息,特点是 "先进后出"(像叠盘子)。
堆(Heap):像公司的 "长期仓库",需要手动手动申请(malloc)和释放(free),存放动态分配的变量,谁用谁管理。
而咱们今天的主角还有一个特殊区域 ——全局变量区(属于静态存储区,既不是栈也不是堆),像公司的 "公共设备",从程序启动到结束一直存在,所有人都能访问。
逐行分析:内存里的 "演员走位"
全局变量x和y的内存分配
c
运行
int x;int y;
这俩变量定义在函数外面,属于全局变量,存放在全局变量区(静态存储区)。
程序一启动就会给它们分配内存,默认初始化为0(就像打印机买回来就插好电待命)。
整个程序运行期间,它们的内存地址不变,所有函数都能访问(就像全公司都能用打印机)。
main函数开始执行
c
运行
intmain{int result;// 局部变量// ...}
main函数被调用时,操作系统会在栈上给它分配一块 "栈帧"(相当于给main函数开了个会议室)。
局部变量result就存放在main的栈帧里(像参会人员带的笔记本),只在main函数内部有效。
调用addtwonum函数
c
运行
result = addtwonum;
调用函数时,会在栈上给addtwonum新分配一个栈帧(又开了个小会议室),这个栈帧在main的栈帧 "上面"(叠盘子一样)。
函数里的extern int x; extern int y;是声明(不是定义),告诉编译器:"x和y是外面的全局变量,我要用它们 "(相当于说" 我要去用公司的打印机 ")。
addtwonum函数内部操作
c
运行
x = 1; y = 2;return x + y;
这里修改的x和y,还是全局变量区的那两个(不是栈上的),相当于给公共打印机换了墨盒。
计算结果3会暂时存放在栈上(函数返回值的临时存储区)。
函数返回,栈帧释放addtwonum执行完,它的栈帧会被自动销毁(小会议室解散),但全局变量x和y还在(打印机继续待命)。返回值3被赋给main函数里的result(笔记本记上结果)。
main函数结束main的栈帧被销毁(大会议室解散),局部变量result消失。程序结束,全局变量区的x和y才会被释放(公司下班,打印机断电)。
画个内存分布图,一目了然
plaintext
┌─────────────────────────────────┐
│ 全局变量区 │
│ ┌─────────┐ ┌─────────┐ │
│ │ x: 1 │ │ y: 2 │ │ ← 整个程序运行期间都在
│ └─────────┘ └─────────┘ │
├─────────────────────────────────┤
│ 栈 (Stack) │
│ ┌─────────────────────────┐ │
│ │ main函数栈帧 │ │
│ │ ┌─────────────────┐ │ │
│ │ └─────────────────┘ │ │
│ └─────────────────────────┘ │ ← main栈帧在下层
│ (addtwonum栈帧已释放) │ ← 函数结束后自动销毁
├─────────────────────────────────┤
│ 堆 (Heap) │
│ (本程序没用到堆,是空的) │ ← 像空仓库
└─────────────────────────────────┘
关键结论:全局变量和局部变量的 "内存性格"
全局变量:住在全局变量区,寿命和程序一样长,全程序可见(像公司前台,谁都能找她)。
局部变量:住在栈上,寿命只在函数执行期间,出了函数就消失(像临时工,活儿干完就走)。
堆:本程序没用到,但如果用malloc分配内存,就会在这里安家(像长期租的仓库,不用了记得退租)。
这段代码里的extern声明纯属 "多此一举"—— 全局变量本来就能被所有函数访问,加不加extern结果都一样。就像你去用公司的打印机,没必要每次都跟同事声明 "我要用打印机",大家都知道它在那儿。
标题:
《C 代码内存解剖:全局变量住 "豪宅",局部变量住 "客栈"》
《从堆栈视角看 C 程序:全局变量的 "永久产权" 和局部变量的 "临时居住证"》
简介:
通过分析一段简单 C 代码的内存分配,揭示全局变量(存于全局区,寿命同程序)和局部变量(存于栈按月配资,寿命随函数)的本质区别,以及栈的自动管理特性,帮你理解内存中的 "演员走位"。
嘉正网提示:文章来自网络,不代表本站观点。