1.面向对象三个最重要的特性:
①封装 ②继承③多态
2.C++ VS C (C++是C的超集)
- C语言头文件29个
- 面向过程
- C++头文件58个
- 异常处理
- 类和对象
- 面向对象
- Lambda
- 函数式编程
- 模板
- 泛型编程
- STL:标准模板库
3.编译过程
- 1.预处理 Preprocessing
- 将.cpp文件转化成.i文件
- 预处理命令cpp命令:cpp -o test.i test.cpp
- gcc/g++ 命令: gcc -E test.c -o test.i
- 2.编译 Compilation (网站:Compiler Explorer)
- 将.cpp/.h文件转换成.s文件
- 编译命令cc: cc test.i -o test.s
- gcc/g++命令:gcc -S test.i -o test.s
- 3.汇编 Assemble
- 将.s文件转化成.o文件
- 汇编命令: as -o test.o test.s
- gcc/g++ 命令:gcc -c test.s -o test.o
- 4.链接 Linking
- 将.o文件转化成可执行程序
- 链接命令ld: ld test.o -o test
- gcc/g++ 命令:gcc test.c
4.链接方式
- 1.静态链接
- 将源代码从静态链接库中拷贝到最终的可执行程序中。可能会导致最终目标文件很大。
- 2.动态链接
- 需调用的库函数以动态链接库形式存在,多个进程之间共享。链接时只需知道调用函数位置即可。
- 在程序执行时,当需要调用某个动态链接库函数时,操作函数首先查找所有正在运行程序,看内存中是否已经有该库函数的拷贝。如果有,则多进程之间可共享拷贝,否则会将其载入到该进程的虚拟内存。
5.内存模型
- C++程序内存分成5个区
- ①堆区 heap
- 用于动态内存分配。
- 堆在内存中位于bss区和栈区之间。由程序员分配和释放。
- ②栈区 stack
- 由编译器自动分配释放,存放函数的参数值、局部变量的值等。
- ③静态全局区 static
- 存放全局变量、静态数据、常量。程序结束后由系统释放。
- ④常量区(字面量区)
- 存放常量字符串,程序结束后由系统释放。
- ⑤代码区 text segment
- 存放函数体的二进制代码。
- ①堆区 heap
- 堆VS栈
- 管理方式
- 栈由程序自动申请和释放空间。
- 堆是需要程序员手动申请和释放。
- 空间大小
- 栈的空间比较小,一遍只有几兆大小。
- 堆空间非常大(与虚拟内存相关)。
- 产生碎片
- 栈和数据结构中的栈原理相同,在弹出一个元素前,上一个已经弹出,不会产生碎片,而不停调用malloc/new、free/delete会造成很多内存碎片
- 生长方向
- 堆生长方向是向上的,向着内存地址增加的方向
- 栈相反,向着内存减小的方向生长
- 分配方式
- 堆是动态分配,没有静态分配。
- 栈由静态分配和动态分配。
- 静态分配是编译器完成的,如局部变量分配。动态分配由malloc/new函数分配。
- 栈的动态分配和堆的不同,动态分配是由编译器进行释放,无需手工实现。
- 静态分配:发生在程序编译和链接阶段。
- 动态分配:发生在程序运行阶段。
- 分配效率
- 栈效率比堆高很多。
- 栈是极其系统提供的数据结构,计算机在底层提供栈的支持,分配专门的寄存器来存放栈地址,压栈出栈有相应指令,比较快。
- 堆是由库函数提供的,机制很复杂,库函数按照一定算法进行搜索内存,比较慢。
- 管理方式
6.STL
- queue
- 声明:queue<data_type> q;
- 队首元素:q.front()
- 队尾元素:q.back()
- 队列判空:q.empty()
- 入队:q.push()
- 出队:q.pop()
- 队列元素数量:q.size()
- 声明:queue<data_type> q;
- stack
- 声明:stack<data_type> s;
- 查看栈顶元素:s.top()
- 栈判空:s.empty()
- 入栈:s.push()
- 出栈:s.pop()
- 栈元素数量:s.size()
- 声明:stack<data_type> s;
- string
- 声明:string s1, s2;
- 字符串判等:s1 == s2
- 字典序小于:s1 < s2
- 字典序大于:s2 > s2
- 字符串连接:s1 += s2
- 字符串长度:s1.length()
- string会不断扩容,比char功能更强。
- 声明:string s1, s2;
- hash_map(非标准)
- 命名空间:__gnu_cxx;
- 声明:hash_map<key_type, value_type, hash_func> h;
- 判断某个key值是否在hash_map中:h.find(key)
- 将value存储在key位上:h[key] = value
- 访问key值对应的value:h[key]
- 哈希表的起始位置:h.begin()
- 哈希表的结束位置:h.end()
- unordered_map(C++11标准)
- 声明:unordered_map<key_type, value_type, hash_func> h;
- 判断某个key值是否在hash_map中:h.find(key)
- 将value存储在key位上:h[key] = value
- 访问key值对应的value:h[key]
- 哈希表的起始位置:h.begin()
- 哈希表的结束位置:h.end()
- 声明:unordered_map<key_type, value_type, hash_func> h;
7.编码规范
- 重要性:
- 1.规范代码可促进团队合作。
- 2.规范代码可减少bug处理。
- 3.规范代码可降低维护成本。
- 4.规范代码有助于代码审查。
- 5.统一代码规范可大家轮岗更容易。
- 原则:
- 重要的是执行,命名。
- 好的版式易于阅读,学会用换行和注释做代码片段区隔。
- 注释要正确,一定要和代码保持同步。