C++笔记(基础)引用 inline内联函数
引用
int& c = a;(给a起别名)
不可以空引用,定义引用的时候必须当场初始化
一个变量可以被同时引用(起好多别名)但是不能重复引用(给别名起别名)
用引用在函数体传参可以,但是直接传参还是不行,因为直接传参传的是副本,独立的新内存,引用传参传的是变量别名,能改变原变量
左右值引用的区分:
int&c=a(左值引用) const int& ref3 = 10; // 正确,const左值引用可以绑定右值
int&&r=10(右值引用)
可以取地址的叫左值,不可以的叫右值
加了const只具有可读特性,其余都是可改可读的
指针与引用有什么区别?
1 从语法规则上讲,指针变量存储某个实例(变量或对象)的地址;引用是某个实例的别名。
2 程序为指针变量分配内存区域;而不为引用分配内存区域。
3 解引用是指针使用时要在前加 "*";引用可以直接使用
4 指针变量的值可以发生改变,存储不同实例的地址;引用在定义时就被初始化,之后无法改变
(不能作为其他的来引用
5 指针变量的值可以为空 引用不能空引用
6 指针变量作为形参时需要测试它的合法性(判空NULL) 引用不需要
7 对指针sizeof得到的是指针变量的大小 对引用变量得到的是变量的大小
8 指针的级数理论上没有限制 可以有指针的指针; 但引用只有一级 即不存在引用的引用
9 操作引用和操作指针,第一个是对变量本身操作,第二个是变量的地址操作
引用和指针作为函数参数在函数体内操作,都可以改变原本的变量
能用引用就不用指针
引用作为函数参数传的是地址,如果需要很简单的函数比如说不改变变量的直接传值也没问题,比如直接return x+y,这样反而更省时间
函数
在函数中定义的局部变量决不允许在函数中以取地址的方式返回
因为内存会被回收(但是具有一定的缓存回收时间)
inline关键字
用于定义内联函数
inline是以空间换时间的做法
一般函数的操作是:
调用到函数时,跳转到函数入口,执行完函数区域再返回操作主体代码
使用内联函数和不使用内联函数相比,额外的调用开销主要体现在以下几个方面:
保存和恢复寄存器:在调用普通函数时,需要将当前函数中使用的寄存器值保存到栈中, 以便在函数返回后恢复这些值,确保程序能够正确继续执行。 而内联函数不需要进行这些操作,因为它没有函数调用和返回的过程。
程序计数器跳转:普通函数调用会改变程序计数器(PC)的值, 使其跳转到被调用函数的入口地址执行代码,执行完后再跳回到调用点继续执行后续代码。 这个跳转过程需要一定的时间开销。内联函数则直接将代码插入到调用处,避免了程序计数器的跳转。
栈操作:函数调用时要进行栈帧的创建和销毁操作,包括为函数的局部变量分配栈空间、传递参数等。 内联函数没有这些栈操作,减少了相关的时间和空间开销。
但不是所有的函数都适合声明为内联函数。如果函数体比较长或者包含复杂的结构(比如循环、递归等)。
编译器可能不会按照我们期望的那样进行内联处理。
因为内联函数虽然减少了函数调用开销,但它会使代码体积增大(因为函数体代码被多次插入到调用位置),
如果函数体过长,代码体积增加较多,反而可能影响程序的性能。
函数体代码过长或者是递归,即使加上inline也不会以内联方式进行操作
用法:inline int add(int a, int b) {return a + b;}
内联函数与宏的核心区别:
本质:
宏:预处理器文本替换(无语法检查)
内联函数:编译器处理的真正函数(有完整语法 / 类型检查)
安全性:
宏:易因优先级 / 类型问题出错
内联函数:遵循语法规则,类型安全
功能:
宏:仅支持简单文本替换,不支持类成员访问
内联函数:支持复杂逻辑、类成员访问等所有函数特性
可控性:
宏:强制替换,不可控
内联函数:编译器决定是否内联,更智能