C++中的内存分区、引用、函数
内存分区模型
- 代码区
- 存放CPU执行的机器指令
- 代码区是共享的且具有只读性
- 全局区
- 全局变量和静态变量都存放在此处
- 全局区还包括了常量区、字符串常量和其他常量也存放在此
- 该区域的数据在程序结束后由操作系统释放
- const修饰的局部变量并不算在全局区
- 栈区
- 由编译器自动分配和释放,存放函数的参数值,局部变量等
- 不要返回局部变量等地址,栈区开辟的数据由编译器自动释放
- 堆区
- 由程序员分配释放,若程序员不释放,程序结束时,由操作系统回收
- cpp中就是new—new后返回地址
- 代码区和全局区—运行前划分的两个区域
- 堆栈区—运行后划分区域
- new的分析
- 在堆中开辟空间—delete对应进行删除
- new返回是该类型的指针
- 语法: new 数据类型
int *p = new int (10); delete p; int *arr = new int[10];//10个元素 for (int i = 0; i < 10;i++){arr[i] = i; } delete[] arr;
引用
- 给变量起别名
- 定义
- 数据类型 &别名 = 原名
- 别名和原名其实本质上就代表了同一块内存
- 注意事项
- 引用必须要初始化
- 引用初始化后就不可以改变
- 引用做函数参数
- 作用—函数传参时,可以利用引用技术让形参修饰实参
- 优点—可以简化指针修改实参
- 函数传参的方式
- 值传递
- 地址传递
- 引用传递
- 引用做函数返回值
- 作用—引用是可以作为函数的返回值存在的
- 注意—不要返回局部变量的引用—static修饰后即可在全局区域,这时可以返回
- 作为函数返回值,既可以作为赋值的左值也可以是右值
int& test1(void){static a = 10;return a } int& test2(void){static b = 5;return b } int &c = test1();//c指向10 test2() = 1000;//将b改为1000
- 引用的本质在cpp内部就是一个指针常量
- int &ref = a; <==> int* const ref = &a
- ref = 20 <==> *ref = 20
- 所以引用一旦初始化后就不可以发生改变
- 常量引用
- 作用—修饰形参防止误操作
- 两种使用场景
- const int& ref = 10;—合法—int temp = 10; const int &ref = temp;
- int& ref = 10;—非法—引用必须引用一块合法的内存空间
- 修饰形参来防止误操作—void show(const int& tem)—这样函数内部不可修改tem指向的内存
函数提高
- 函数的默认参数
- cpp中函数的形参列表中的形参是可以有默认值的
- 语法—返回值类型 函数名 (参数=默认值){}
- 默认参数依然可以修改,传入参数的优先级更高
- 注意
- 如果某个位置有默认参数则从这个位置往后,从左到右都必须有默认值
- 如果函数声明有默认参数,函数的实现就不能有默认参数
- 声明和实现只能有一个地方有默认值
- 函数占位参数
- cpp中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
- 语法—返回值类型 函数名 (数据类型){}—void test(int a, int){}
- 占位参数也可以默认参数
- 函数重载
- 函数名可以相同,提高复用性
- 根据函数参数的不同来判断调用哪一个参数
- 条件
- 同一个作用域下
- 函数名称相同
- 函数参数类型不同或者个数不同或者顺序不同
- 函数返回值不同不能作为重载条件
- 注意事项
- 引用作为函数重载的条件
- 在碰到const修饰的参数时,需要明确,可以实现常数的传递const int &a 可以被传递10
- const可以作为重载条件,但是要注意传什么值
- 函数重载碰到函数的默认参数
- 可能出现多个可调用
void test(int a);void test(int a, int b = 10);//如果如下调用则不合法test(10);//如果如下调用则合法test(10, 20);
- 引用作为函数重载的条件