C++引用

在C++中,有一种比指针更加便捷的传递聚合类型的数据方式,就是引用。

引用(Reference)是 C++ 相对于C语言的又一个扩充。引用可以看做是数据的一个别名,通过这个别名和原来的名字都能够找到这份数据。

引用的定义方式类似于指针,只是用&取代了*。

C++引用作为函数参数

在定义或声明函数时,我们可以将函数的形参指定为引用的形式,这样在调用函数时就会将实参和形参绑定在一起,让它们都指代同一份数据。如此一来,如果在函数体中修改了形参的数据,那么实参的数据也会被修改,从而拥有“在函数内部影响函数外部数据”的效果。

#include <iostream>
using namespace std;
void swap1(int a, int b);
void swap2(int *p1, int *p2);
void swap3(int &r1, int &r2);
int main() {
    int num1, num2;
    cout << "Input two integers: ";
    cin >> num1 >> num2;
    swap1(num1, num2);
    cout << num1 << " " << num2 << endl;
    cout << "Input two integers: ";
    cin >> num1 >> num2;
    swap2(&num1, &num2);
    cout << num1 << " " << num2 << endl;
    cout << "Input two integers: ";
    cin >> num1 >> num2;
    swap3(num1, num2);
    cout << num1 << " " << num2 << endl;
    return 0;
}
//直接传递参数内容
void swap1(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}
//传递指针
void swap2(int *p1, int *p2) {
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
//按引用传参
void swap3(int &r1, int &r2) {
    int temp = r1;
    r1 = r2;
    r2 = temp;
}

指针就是数据或代码在内存中的地址,指针变量指向的就是内存中的数据或代码。这里有一个关键词需要强调,就是内存,指针只能指向内存,不能指向寄存器或者硬盘,因为寄存器和硬盘没法寻址。

寄存器离 CPU 近,并且速度比内存快,将临时数据放到寄存器是为了加快程序运行。但是寄存器的数量是非常有限的,容纳不下较大的数据,所以只能将较小的临时数据放在寄存器中。int、double、bool、char 等基本类型的数据往往不超过 8 个字节,用一两个寄存器就能存储,所以这些类型的临时数据通常会放到寄存器中;而对象、结构体变量是自定义类型的数据,大小不可预测,所以这些类型的临时数据通常会放到内存中。
编译器会为const引用创建临时变量

引用不能绑定到临时数据,这在大多数情况下是正确的,但是当使用 const 关键字对引用加以限定后,引用就可以绑定到临时数据了。

编译器会为临时数据创建一个新的、无名的临时变量,并将临时数据放入该临时变量中,然后再将引用绑定到该临时变量。注意,临时变量也是变量,所有的变量都会被分配内存。

const引用与转换类型

不同类型的数据占用的内存数量不一样,处理方式也不一样,指针的类型要与它指向的数据的类型严格对应。

虽然 int 可以自动转换为 float,char 也可以自动转换为 int,但是float *类型的指针不能指向 int 类型的数据,int *类型的指针也不能指向 char 类型的数据。

当对引用添加 const 限定后,情况就又发生了变化,编译器允许引用绑定到类型不一致的数据。

当引用的类型和数据的类型不一致时,如果它们的类型是相近的,并且遵守「数据类型的自动转换」规则,那么编译器就会创建一个临时变量,并将数据赋值给这个临时变量(这时候会发生自动类型转换),然后再将引用绑定到这个临时的变量。

给引用添加 const 限定后,不但可以将引用绑定到临时数据,还可以将引用绑定到类型相近的数据,这使得引用更加灵活和通用,它们背后的机制都是临时变量。

引用类型的函数形参请尽可能的使用 const

当引用作为函数参数时,如果在函数体内部不会修改引用所绑定的数据,那么请尽量为该引用添加 const 限制。

#include <cstdio>
using namespace std;
double volume(const double &len, const double &width, const double &hei){
    return len*width*2 + len*hei*2 + width*hei*2;
}
int main(){
    int a = 12, b = 3, c = 20;
    double v1 = volume(a, b, c);
    double v2 = volume(10, 20, 30);
    double v3 = volume(89.4, 32.7, 19);
    double v4 = volume(a+12.5, b+23.4, 16.78);
    double v5 = volume(a+b, a+c, b+c);
    printf("%lf, %lf, %lf, %lf, %lf\n", v1, v2, v3, v4, v5);
    return 0;
}
  • 使用 const 可以避免无意中修改数据的编程错误;
  • 使用 const 可以避免无意中修改数据的编程错误;
  • 使用 const 引用能够让函数正确生成并使用临时变量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值