引用概念
C++ 用的引用就如同C语言的指针一样重要,但它比指针更加方便和易用,有时候甚至是不可或缺的。
同指针一样,引用能够减少数据的拷贝,提高数据的传递效率。
函数传参本质上是一次赋值(=)的过程,赋值就是对内存进行拷贝。所谓内存拷贝,是指将一块内存上的数据复制到另一块内存上。
引用可以看做是数据的一个别名,通过这个别名和原来的名字都能够找到这份数据。
引用类似于 Windows 中的快捷方式,一个可执行程序可以有多个快捷方式,通过这些快捷方式和可执行程序本身都能够运行程序
引用定义
引用的定义方式类似于指针,只是用&取代了*,语法格式为:
int a = 1;
int& ra = a;//单独一个a,不需在a的前面加&
//ra 是一个初始化为a的整型引用
引用类似指针常量,一旦引用和某个变量关联起来,该引用就会一直指向该变量。
int a = 1;
int* const ra = &a;
引用作为变量
引用必须在定义的同时初始化,并且以后也要从一而终,不能再引用其它数据,这有点类似于常量(const 变量)
#include <iostream>
using namespace std;
int main()
{
int a = 99;
int& r = a;
cout << a << ", " << r << endl;
cout << &a << ", " << &r << endl;
return 0;
}
99, 99
0x28ff44, 0x28ff44
本例中,变量 r 就是变量 a 的引用,它们用来指代同一份数据;也可以说变量 r 是变量 a 的另一个名字。
从输出结果可以看出,a 和 r 的地址一样,都是0x28ff44;或者说地址为0x28ff44的内存有两个名字,a 和 r,想要访问该内存上的数据时,使用哪个名字都行。
注意,引用在定义时需要添加&,在使用时不能添加&,使用时添加&表示取地址。
如上面代码所示,第 6 行中的&表示引用,第 8 行中的&表示取地址。除了这两种用法,&还可以表示位运算中的与运算。
由于引用 r 和原始变量 a 都是指向同一地址,所以通过引用也可以修改原始变量中所存储的数据
#include <iostream>
using namespace std;
int main()
{
int a = 99;
int &r = a;
r = 47;
cout << a << ", " << r << endl;//47, 47
return 0;
}
常引用
如果不希望通过引用来修改原始的数据,那么可以在定义时添加 const 限制,形式为:
int a = 1;
const int& r = a;
int const & r = a;//两种方法都可以
引用作为函数参数
在定义或声明函数时,我们可以将函数的形参指定为引用的形式,这样在调用函数时就会将实参和形参绑定在一起,让它们都指代同一份数据。
按引用传参在使用形式上比指针更加直观。在以后的 C++ 编程中,我鼓励读者大量使用引用,它一般可以代替指针(当然指针在C++中也不可或缺),C++ 标准库也是这样做的
#include <iostream>
using namespace std;
void swap1(int* p1, int* p2);
void swap2(int& r1, int& r2);
void swap3(int a, int b);
int main() {
int a, b;//局部变量仅仅是定义,未赋值
//cout << a << " " << b;在VS里面会报错,但是在Qt里面,每次就会打印相同的值
cin >> a >> b;
swap1(&a, &b);
cout << a << " " << b << endl;
cin >> a >> b;//重新赋初值
swap2(a, b);//不需要加&
cout << a << " " << b << endl;
cin >> a >> b;
swap3(a, b);
cout << a << " " << b << endl;
system("pause");
return 0;
}
void swap1(int* p1, int* p2) {
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
void swap2(int& r1, int& r2) {
int temp = r1;
r1 = r2;
r2 = temp;
}
void swap3(int a, int b) {
int temp = a;
a = b;
b = temp;
}
C++ 引用 vs 指针
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。