内存四区之二
变量的本质分析
变量的概念
- 概念:既能读又能写的内存对象,称为变量;若一旦初始化之后不能修改的对象则称之为常量
- 变量定义形式:数据类型 标识符, 标识符, …, 标识符;
示例:
int x;
int woefCut, Radius, Height;
double FlighrTime, Mileage, Speed;
变量的本质
- 程序通过变量来申请和命名内存空间
int a = 0;
- 通过变量名访问内存
变量:一段连续内存空间的别名 - 修改变量的两种方式
直接方式
间接方式;内存由地址编号,拿到地址编号也可以修改内存
示例:
#include <stdio.h>
int main(void)
{
int i = 0;
//通过变量直接操作内存
i = 10;
// 动过内存编号操作内存
printf("&i:%d\n", &i); // 假设内存地址为1245024
*((int *)(1245024)) = 100;
printf("i:%d", i);
return 0;
}
- 数据类型和变量的关系
通过数据类型定义变量 - 总结
1、堆内存,可读可写
2、通过变量往内存读写数据
3、不是向变量续写数据,而是向变量锁代表的内存空间中写数据
——–load——-
程序的内存四区模型
流程说明
- 操作系统把物理硬盘代码load到内存
- 操作系统把C代码分成四个区
- 操作系统找到main函数入口执行
内存四区 | 解析 |
---|---|
栈区 ( stack ) | 由编译器自动分配释放,存放函数的参数值,局部变量的值等 |
堆区 ( heap ) | 一般由程序猿分配释放 ( 动态内存申请与释放 ),若程序员不释放,程序结束时可能由操作系统回收 |
全局区 ( 静态区 ) ( static ) | 全局变量和静态变量的村吃是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放 |
常量区 | 字符串常量和其他常量的存储位置,程序结束后由操作系统释放 |
程序代码区 ( static ) | 存放函数体的二进制代码 |
建立正确程序运行内存布局图是学好C的关键
栈区 和 堆区
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// 堆
char *getMem(int num)
{
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char) * num);
if(p1 == NULL)
{
return NULL;
}
return p1;
}
// 栈
// 注意 return 不是把内存块 64 个字节给 return 出来
// 而是把内存块的首地址返回给tmp
// 理解指针的关键是内存,没有内存哪来指针
char *getMem2()
{
char buf[64] = { 0 }; // 临时变量,栈区存放
strcpy(buf, "123456789");
return buf;
}
void main(void)
{
char *tmp = NULL;
tmp = getMem(10);
if(tmp == NULL)
{
return;
}
strcpy(tmp, "111222"); // 向 tmp 所指向的内存空间中copy数据
tmp = getMem2();
return;
}
全局区
#include <stdio.h>
char * getStr1()
{
char *p1 = "abcdefg2";
return p1;
}
char *getStr2()
{
char *p2 = "abcdefg2";
return p2;
}
int main(void)
{
char *p1 = NULL;
char *p2 = NULL;
p1 = getStr1();
p2 = getStr2();
// 打印 p1 p2 所指向内存空间的数据
printf()"p1:%s , p2:%s \n", p1, p2;
// 打印 p1 p2 的值
printf("p1:%p, p2:%p\n", p1, p2);
return 0;
}