深入学习C++底层
文章目录
C++内存管理
-
栈 存储函数的返回地址、参数、局部变量、返回值,从高地址向低地址增长
-
堆 malloc/free开辟内存的空间,从低地址向高地址增长
-
自由存储区 new/delete开辟内存空间
-
数据区
数据区包含全局/静态存储区和常量存储区,存储已初始化的全局变量和静态变量、未初始化的全局变量和静态变量及字符串常量
-
代码区 存储程序的机器代码和程序指令
LINUX进程区分段及存储数据
Linux的每个进程都有各自独立的4G逻辑地址,其中03G是用户态空间,34G是内核空间,不同进程相同的逻辑地址会映射到不同的物理地址中。
逻辑地址分段如下,自下而上:
-
代码段。分为只读存储区和代码区,存放字符串是常量和程序机器代码和指令
-
数据段。存储已初始化的全局变量和静态变量。
-
bss段。存储未初始化的全局变量和静态变量,及初始化为0的全局变量和静态变量
-
堆。 当进程未调用malloc时是没有堆段的,malloc/free开辟的内存空间,向上生长
-
映射区。存储动态链接库以及调用mmap函数进行的文件映射
-
栈。存储函数的返回地址、参数、局部变量、返回值,向下生长。
GCC编译流程
-
预处理阶段:hello.c – “gcc -E预处理,头文件展开,宏替换” --> hello.i
-
编译阶段:hello.i – “gcc -s生成汇编文件” --> hello.s
-
汇编阶段:hello.s – “gcc -c生成二进制文件” --> hello.o
-
链接阶段:hello.o – “调用ld进行链接” --> a.out
动态库静态库区别及GCC加载库
静态库
-
编译时期链接
-
浪费空间和资源,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。
-
若静态库需修改,需重新编译所有链接该库的程序
动态库
-
运行时链接
-
运行时被链接,故程序的运行速度稍慢
-
动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉即可
GCC编译加载静态库
-
将所有的.c文件编译成.o目标文件
-
gcc -c add.c生成add.o
-
gcc -c max.c生成max.o
-
对生成的.o目标文件打包生成静态库
-
ar crv libfoo.a add.o max.o //libfoo.a是库的名字
-
ar:做库的命令
-
c:创建库
-
r:将方法添加到库里
-
v:显示过程,可以不要
-
使用静态库
-
gcc -o main main.c -static -L. -lfoo //这里写的foo是去掉前后缀后库的名字
-
-L:指定路径 .代表当前路径
-
-l:指定库名
GCC编译加载动态库
extern-C的结果和CPP编译的区别
#include <stdio.h> void print(int a,int b) { printf("这里调用的是C语言的函数:%d,%d\n",a,b); }
#ifndef _P_H #define _P_H void print(int a,int b); #endif
#include <iostream>
using namespace std;
#include "p.h"
int main()
{
cout<<"现在调用C语言函数\n";
print(3,4);
return 0;
}
重载的底层原理
根据上面的编译分析,可以知道C语言没有重载,只有C++才有函数重载,因为函数重载通过参数列表的不同来实现。
"int __cdecl Add(int,int)" (?Add@@YAHHH@Z)
"double __cdecl Add(double,double)" (?Add@@YANNN@Z)
"long __cdecl Add(long,long)" (?Add@@YAJJJ@Z)
在C语言中被解析为_Add,三个一样,所以不能进行区分,因此C语言不支持函数重载
编译性语言和解释性语言的本质区别和优缺点
-
根本区别
-
计算机不能直接的理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言的编写的程序。翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。
-
解释性语言不用编译,在运行时翻译
-
编译性语言是编译的时候直接编译成机器可以执行的语言,编译和运行是分开的,但是不能跨平台。比如exe文件,以后要运行的话就不用重新编译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行的时不要翻译,所以编译型语言的程序执行效率高
-
编译性语言的优缺点
-
优点
-
运行速度快,代码效率高,编译后程序不可以修改,保密性好
-
缺点
-
代码需要经过编译方可运行,可移植性差,只能在兼容的操作系统上运行。
-
解释性语言的优缺点
-
优点
-
可移植性好,只要有解释环境,可以在不同的操作系统上运行。
-
缺点
-
运行需要解释环境,运行起来比编译的要慢,占用的资源也要多一些,代码效率低,代码修改后就可以运行,不需要编译过程
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_45893999/article/details/113480802