C到C++/编译过程/链接方式/内存模型/STL

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
      • 存放函数体的二进制代码。
  • 堆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()
  • stack
    • 声明:stack<data_type> s;
      • 查看栈顶元素:s.top()
      • 栈判空:s.empty()
      • 入栈:s.push()
      • 出栈:s.pop()
      • 栈元素数量:s.size()
  • string
    • 声明:string s1, s2;
      • 字符串判等:s1 == s2
      • 字典序小于:s1 < s2
      • 字典序大于:s2 > s2
      • 字符串连接:s1 += s2
      • 字符串长度:s1.length()
    • string会不断扩容,比char功能更强。
  • 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()

7.编码规范

  • 重要性:
    • 1.规范代码可促进团队合作。
    • 2.规范代码可减少bug处理。
    • 3.规范代码可降低维护成本。
    • 4.规范代码有助于代码审查。
    • 5.统一代码规范可大家轮岗更容易。
  • 原则:
    • 重要的是执行,命名。
    • 好的版式易于阅读,学会用换行和注释做代码片段区隔。
    • 注释要正确,一定要和代码保持同步。

猜你喜欢

转载自blog.csdn.net/u011616934/article/details/125418280