文章目录提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
- 前言
- 一、引用
- 1.1 引用的概念
- 1.2 引用的特性
- 1.3 常引用(const引用)
- 1.4 引用的使用场景
- 1.4.1 作参数
- 1.4.2 作返回值
- 1.5 传值和传引用效率比较(传参)
- 1.6 传值返回和传引用返回性能比较
- 1.6 指针和引用的区别
- 二、内联函数
- 2.1 内联函数的概念
- 2.1 内联函数的特性
- 2.2 内联函数和宏
前言
前一篇文章我们简单了解C++的命名空间、输入输出、缺省参数和函数重载等https://editor.csdn.net/md/?articleId=124978175。今天我们来继续了解新的知识。
一、引用 1.1 引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
注意:引用的符号为&,这里要和取地址符号区别开来。可以简单理解为:&放在类型和变量中间就是引用。&单独放在变量前就是对变量取地址。
void Test1()
{
int a = 0;//类型& 引用变量名(对象名) = 引用实体
int& b = a;//这里&放在类型int和变量b之间,&是引用。
printf("%pn",&a);//这里&单独放在变量名之前,&是取地址
printf("%pn",&b);
//由于b是a的引用,他们公用一块空间,所以打印出来的地址是一样的。
}
1.2 引用的特性注意:引用类型必须和引用实体是同种类型的。
引用有以下三个特性:
①.引用在定义的时候必须初始化。
②.一个变量可以有多个引用。
③.引用一旦引用一个实体,便不能引用其他实体。
void Test2()
{
int a = 0;
int& b = a;
//int& b没有初始化,编译器会报错。
int& c = a;//一个变量可以有多个引用。
int d=1;
c=d;//注意:这里是d赋值给c,而不是c是d的别名
}
1.3 常引用(const引用)
const int a=1; //int& b=a;编译出错,权限放大。(a是只读的,b是可读可写的)。 const int& b=a;//权限不变(a是只读的,b也是只读的) int c = 2; const int& d=c;//权限缩小。
注意:权限可以不变,权限也可以缩小,但是权限不能放大。 另外,在常引用中还有一个需要注意到的地方,请看以下代码。
int x1=1; int x2=2; //int& ret = x1 + x2;注意,这种方式是不行的,编译器在编译这条 //语句对x1+x2进行处理,把得到的结果存到临时变量中去,而临时 //变量具有常属性。我们可以把这句代码理解为 //int& ret = const(x1+x2),这很明显属于权限的放大。 //下面画个图方便我们理解 const int& ret = x1 + x2;//这才是正确使用方法1.4 引用的使用场景 1.4.1 作参数
int Add(int& x , int& y)
{
return x + y;
//引用作参数,相当于是实参的别名。
}
1.4.2 作返回值
int& Sub(int x , int y)
{
return x - y;
//引用作返回值,返回的是x-y的别名。
}
1.5 传值和传引用效率比较(传参)注意:在引用作返回值时,如果函数返回时,出了函数作用域,返回对象还未还给系统,则可以使用引用返回,如果已经还给系统了,则必须使用传值返回(因为如果这块区域没有还给系统,我们还可以通过地址去取它里面的数据,如果已经还给了系统,通过它的地址去取到的时随机值)。
1.6 传值返回和传引用返回性能比较所有的传值都是把值拷贝到一个临时变量中去。当这组数的规模很小时,传值和传引用没有太大的区别。但是如果这组数规模很大,使用传值返回的话,会把这些数据拷贝到临时变量中去,这样效率低。但是如果使用传引用的话,传过去的是这组大规模数的别名,可以通过这个别名直接操作这组数,效率高。
1.6 指针和引用的区别传值返回返回的返回对象值的拷贝,传引用返回则是返回对象的别名。跟上面类似,如果返回数的规模很大,传值返回所消时间太多,而传引用返回效率要高得多。但是传引用返回也有弊端,如果函数返回对象除了函数作用域就销毁了的话,就不能使用传引用返回,只能使用传值返回。
在语法层面上,引用只是取了一个别名,没有独立的空间,与引用实体共用一块空间。但是在其底层实际上是由空间的,因为引用是按照指针的方式来实现的。
我们给出引用和指针代码,然后看一下他们的汇编代码对比。
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
二、内联函数 2.1 内联函数的概念从上图我们可以看出,引用和指针的底层实现是一样的。
引用和指针的区别:
①.引用在定义时必须初始化,而指针可以不初始化。
②.引用在初始化引用一个实体时,就不能引用其他实体,而指针在任何时候可以指向同一类型的实体。
③**.没有NULL引用,但是又NULL指针**。
④.在sizeof中的含义不同:引用为引用实体类型的大小,而指针始终是地址空间所占字节数的多少(32位平台下为4字节,64位平台下为8字节)。
⑤.有多级指针,但是没有多级引用。
⑥.访问指针时需要解引用,而引用不需要,编译器自己处理。
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率。
inline int Add(int x , int y)
{
return x + y;
}
int main()
{
int ret = 0;
ret = Add(1 , 2);
return 0;
}
2.1 内联函数的特性
2.2 内联函数和宏①.内联函数是一种以空间换时间的做法,省去调用函数额外开销。所以代码很长或者有循环/递归的函数不适宜 使用作为内联函数。
②.inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
③. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
宏的优点:
①.增强代码的复用性。
②.提高性能。
宏的缺点:
①.不方便调试,因为宏在编译时就进行了替换。
②.导致代码可读性差,可维护性差,容易误用。
③.没有类型的安全检查。
C++中有哪些可以替代宏:
①.修饰常量时用const。
②.内联函数。



