变量与常量
- 常量
- 包括整型常量、实型常量、字符常量、字符串常量、符号常量1
- 与常变量相比,常量是没有名字的不变量
- 变量
- 有名字的、具有特定属性的存储单元
- 静态变量
- 由static修饰
- 常变量
- 有名字的不变量,便于在程序中被引用
- C99允许使用常变量(
const int a = 3
) - 常变量有变量的基本属性:有类型,占存储单元
define符号常量与const常变量有何区别
// 符号常量
// define是预编译指令,在预编译时进行字符串替换
// 这意味着,预编译结束后,符号常量就不复存在了
// 即,不需要给符号常量的名字分配存储单元
#define PI 3.1415926
// 常数变量
// 要占用存储单元
const float pi = 3.1415926
const常变量与static静态变量有何区别
- const 只读常变量,放在只读数据区,类似于一种保证
i promise that i will never try to change it
- static 静态变量,只能初始化一次
字符串常量与字符串变量
char* s = "hello world"
char* ss = (char*)malloc(128);
memset(ss, 0, 128);
strcpy(ss, "hello world")
类型 | 存储区域 | 例子 |
---|---|---|
字符串常量 | 静态存储区.ROdata | &”hello world”或&(s[0]) |
字符串变量 | 栈 | &s |
malloc声明的字符串变量 | 堆 | &ss |
编译
🎅⭐👀👇
序号 | 阶段 | 行为 | 备注 |
---|---|---|---|
1 | 预处理Preprocessing | 展开所有的#define 宏定义;处理 #if 、#ifdef 、#elif 、#else 、#endif 等;处理 #inlcude ,将被包含的文件直接插入;删除注释; 添加行号和文件标识; 保留 #program 编译器指令;gcc -E hello.c -o hello.i 进行预处理,输出文件.i |
预处理器cpp |
2 | 编译compilation | 词法分析,得到一系列token 语法分析,生成语法树 语义分析,静态语义 + 动态语义源代码优化,将语法树转化为中间代码 目标代码生成 目标代码优化 输出文本文件.s |
编译器ccl |
3 | 汇编assembly | 将.s文本文件翻译为机器语言指令 将指令打包为 可重定位目标程序 格式输出二进制文件.o |
汇编器as |
4 | 链接linking | 将程序中调用的诸如printf.o等预编译好的目标文件合并进程序 输出可执行目标文件 |
连接器linker |
linker 可以执行于编译时(源代码翻译为机器代码时),或者加载时(程序被加载到内存并执行时),甚至是运行时(应用程序来执行链接) 使得分离编译成为可能
标识符
标识符: 对变量、符号常量名、函数、数组、类型等命名的有效字符序列 即,一个对象的名字 C语言规定标识符只能由字母下划线和数字组成,且第一个字符必须为字母或下划线,且区分大小写
内存分类
CPP中的五分类
- 栈:编译器自动分配和释放,一般存储 局部变量、函数参数 和 函数返回地址
- 堆:new分配;delete释放
- 自由存储区:malloc分配;free回收
- 全局、静态变量存储区
- 常量存储区
我自己的C++内存布局
高地址 | 内核 | 存储内容 | 备注 |
---|---|---|---|
⬇️ | 栈 | 返回地址; 函数参数; 局部变量(非 static ) |
运行时动态生成br>即,动态内存分配 |
… | 栈空间 | 由高地址向低地址, 快速,连续,空间有限 |
|
内存映射 | 高效的I/O映射 | 文件映射、动态库、匿名映射 | 用于加载一个共享的动态内存库。 用户可使用系统interface创建共享内存,用作进程通信 共享库的内存映射,如printf()函数 |
… | 堆空间 | 堆区域由所有共享库和进程中动态加载的模块共享 | 由低地址向高地址, 缓慢,不连续(链表),空间大 |
⬆️ | 堆 | 用于程序运行时的动态内存分配, 是由程序员自己分配的 运行时动态生成 即,动态内存分配 |
|
.bss | 未初始化的全局变量和静态变量 | 由global 或static 修饰;运行前由内核初始化为0 静态内存分配 |
|
.data | 读写数据段.WR data | 初始化的全局变量和静态变量 | 由程序员初始化 经编译并链接后得到 静态内存分配 |
.data(只读) | 只读数据段.RO data | 初始化的常变量,如字符串常量 | 由const 修饰的全局变量经编译并链接后得到 静态内存分配 |
.text(只读) | 代码段 | 可执行代码 | 有效防止堆栈溢出; 共享的;只读的; 经编译并链接后得到 是程序代码在内存中的映射 |
关于
.bss
段的命名由来: IBM 704汇编语言“块存储开始block storage start”指令,
也可以记为“better save space”。
关于.text
段是共享的:
对于经常执行的程序,只需要存储一个副本在内存中。
关于.text
段是只读的:
有效防止程序以外修改指令。
-
符号常量,用DEFINE宏定义。 ↩