补充内容:
c++编译过程:编译预处理、编译优化、汇编、链接
①编译预处理:处理以“#”开头的指令,产生“.i”文件;【如头文件、define宏定义等】
②编译优化:将源码".cpp"文件翻译成“.s”汇编代码;【如词法语法语义分析,代码优化等】
③汇编:将汇编代码“.s”翻译成机器指令“.o”或".obj"目标文件【汇编后的.o文件是纯二进制文件】
④链接:产生“.out"或".exe"可运行文件【分为动态链接(.dll/.so)和静态链接(.lib/.a)】
区别:
静态链接是 将各个模块的obj和库链接成一个完整的可执行程序;而动态链接是程序在运行的时候寻找动态库的函数符号(重定位),即DLL不必被包含在最终的exe文件中;
优缺点:
静态链接:浪费空间,每个可执行程序都会有目标文件的一个副本,这样如果目标文件进行了更新操作,就需要重新进行编译链接生成可执行程序(更新困难);优点就是执行的时候运行速度快,因为可执行程序具备了程序运行的所有内容。
动态链接:节省内存、更新方便,但是动态链接是在程序运行时,每次执行都需要链接,相比静态链接会有一定的性能损失。
--------
c++程序执行时,内存分为四个区域
一、程序运行前:在程序编译后,生成exe可执行程序,未执行该程序前分为两个区域
①代码区:存放函数体的二进制代码,由操作系统进行管理
1、存放CPU执行的机器指令【将程序员写的代码转化为 0101的二进制形式】
2、代码区的特点:
2.1、代码区是共享的,目的是对于频繁被执行的程序,只需要在内存中有一份 代 码【比如需要双击打开这个程序,一份执行代码即可多次执行】
2.2、代码区是只读的,防止程序意外修改exe的指令
②全局区:存放全局变量、静态变量、常量
1、全局区内包含了常量区,常量区内有字符串常量和其他常量【const修饰的变量】
2、该区域的数据在程序结束后由操作系统释放
【由图可看见,局部变量和全局变量不在同一个存储段中】
** 普通变量前加static 属于静态变量 【int a】→【static int a】**
** 字符串常量和const修饰的全局常量 都存在全局区中 **
** 局部变量和const修饰的局部常量 并不在全局区中 **【有局部的都不在全局区中】
二、程序运行后:
③栈区:由编译器自动分配释放,存放函数的形参值、局部变量等
** 不要返回局部变量的地址 **
如果用指针去操作这一块内存,第一次可以正常操作,因为编译器会怕你误操作帮你保留内容;但是第二次操作数据就不再会保留,操作就会失误。此时属于非法操作。
④堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
c++中利用new关键字在堆区中开辟内存【int * p = new int(10),用指针接收new开辟的地址】
** 用栈存储堆区的地址编号,在堆区中存储数据内容 ** 【指针属于局部变量,该方法可解决第三点中的非法操作】
三、new操作符
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符【delete】
语法:new 数据类型
** new返回的是该数据类型的指针 **
//数据类型 * p = new 数据类型(数据);
int * func()
{
int * p = new int(10);
}
int main(){
int * p =func();
cout << *p << endl;
//手动释放
delete p;
}
** 在堆区里利用new开辟数组 ** 利用中括号创建数组
void test(){
int * arr = new int[10]; //10代表数据有10个元素
for(int i = 0; i<10; i++){
arr[i] = i+100; // 赋值100~109
}
for(int i = 0; i<10; i++){
cout << a[i] << endl;
}
delete[] arr; //释放时要加上中括号,告诉其释放的是数组而不是一个数据
}
标签:常量,int,四区,代码,C++,内存,new,链接
From: https://blog.csdn.net/weixin_60546365/article/details/140364569