文章目录
1. 程序 的 存储
1.1 程序 的 主要 存储模型
一般来说, 一个程序 主要 是由 代码段 , 常量段 , 静态数据区 , 栈 , 堆 这五个部分 组成. 而 静态数据区又可以 分为 .bss 段 和 数据段
代码段
:负责存放 程序编译后 的 二进制代码. 有时候存在一些 看起来 是会存储的数据,实则不占空间,他们是最终 成为了 代码,放在了 代码段 .如下:
#define 宏定义: 在C/C++中,可以使用预处理指令#define定义常量宏。例如:#define PI 3.1415926。在编译时,预处理器会将所有的宏定义进行替换,将宏定义的常量直接嵌入到代码中。
枚举(Enum):在C/C++中,使用枚举可以定义一组具有常量值的符号名称。枚举在代码中实现的功能跟使用宏类似,都可以用名字来代替数值。宏是在预处理阶段将名字换成了值,而枚举是在编译阶段将名字换成值。也就是说,枚举类型的这些名字不是变量,它们不会占据任何内存。且这些名字的有效范围是全局的,如果有变量等命名冲突了可能导致编译不过。
字面常量(Literal Constants):在代码中直接使用的字面常量,例如整数、浮点数、字符常量和字符串常量。这些字面常量在编译时会直接存放在常量区。例如,if(a<5)…这个数字5就是字面常量。
常量区
:存放 只读变量 和 字符串常量,一经初始化,不可修改
const修饰的全局变量:在全局作用域中使用const修饰的变量也会被存放在常量区。✨✨✨**如果是被const修饰的局部变量,是被存放在栈上的。**✨✨✨
常量字符串:char *str2 = “hello”;中的"hello"就是一个常量字符串。
静态数据区
: 用于 存放 全局变量 和 静态数据(static)
- .bss 段: 用于 存储 未初始化 或 初始化为 0 的 全局变量 和 静态变量
- .data段:用于 存储 已初始化 的 全局变量 和 静态变量
- 为什么要区分 .bss 段 和 .data 段
- 在程序编译的时候,不会给.bss段中的数据分配空间,只是记录数据所需空间的大小。在程序执行的时候,才会给.bss段中的数据分配内存。通过这种方式,可以节省一部分内存空间,进一步缩减可执行程序的大小
栈: 存放 局部变量 , 函数调用信息 等. 由系统自动分配和释放
堆: malloc ,alloc 函数 申请的空间. 由程序员 手动申请 和 释放,若不 手动释放,程序结束后由系统回收♻️
1.2 直接实战
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//宏定义和枚举常量会被当成代码编译进代码段,所以说,不占空间
#define PI 3.1415926
enum color
{
red,
green,
yellow
};
int a = 6; //存放在静态数据区的数据段 (已初始化 的 全局变量)
char* str1; //存放在静态数据区的 .bss 段 (未初始化 的 全局变量)
static int c = 3; //存储在静态数据区的数据段 (已初始化 的 静态变量)
static int d; //存储在静态数据区的 .bss 段 (未初始化 的 静态变量)
const int b = 5; //存放在常量区 (全局 常变量)
int main() //main函数本质上就是一个函数指针,存放在栈中
{
static int e; //存储在静态数据区的BSS段 (未初始化 的 静态变量)
static int f = 2; //存储在静态数据区的数据段 (已初始化 的 静态变量)
const char g; //存储在栈中 (局部 常变量)
char *str2 = "hello"; //str2存放在栈中,“hello”存放在常量区
char str3[]="world"; //str3存放在栈中
str1 = (char*)malloc(sizeof(char)*strlen(str2)); //申请的内存存放在堆中
strcpy(str1,str2); //进行字符串拷贝
if(a > 5);
printf("str1 = %s\r\n",str1);
printf("str2 = %s\r\n",str2);
printf("str3 = %s\r\n",str3);
return 0;
}
解析1:
//宏定义和枚举常量会被当成代码编译进代码段,所以说,不占空间
#define PI 3.1415926
enum color
{
red,
green,
yellow
};
int a = 6; //存放在静态数据区的数据段
char* str1; //存放在静态数据区的BSS段
static int c = 3; //存储在静态数据区的数据段
static int d; //存储在静态数据区的BSS段
const int b = 5; //存放在常量区
#define PI 3.1415926
这个宏定义,在程序预处理阶段,会将所有的PI转换为数字3.1415926 ,而3.1415926 这个数字,会被当成代码,存储在代码段。enum color{}
这个枚举类型,里面的枚举常量red,green, yellow他们和宏定义类似,在程序的编译阶段,他们会被替换成对应的数字,所以说他们是不占空间的!(这个不占空间是相对的,他们是存放在了代码段,而代码段一般不算在我们所说的空间里面)变量a
,他被初始化了成了一个非0的数据,所以存放在静态数据区的数据段。str1
没有被初始化&#