引用是C++引入的新语言特性,正确、灵活地使用引用,可以使程序简洁高效。
一、一般变量的引用
引用只是给变量起了一个别名,它们两个存储在同一个存储单元,具有同一地址。
来看下面的代码
int a = 10;
int b = 20;
int &rn = a;
int equal;
rn = b;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
rn = 100;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
equal = (&a == &rn) ? 1 : 0;
cout << "equal = " << equal << endl;
这里将rn作为a的引用,对rn操作就相当于对a进行了相应的操作。因为它们具有相同的存储单元,所以最后一行输出的是 equal = 1;
二、指针变量的引用
其实指针变量的引用和普通变量的引用差不多,都是给它们取了一个别名。
int a = 1;
int *p = &a;
int *&pa = p;
上面的一段代码就是将pa作为p的引用,所以对pa的操作就相当于对p的操作。
三、使用指针引用来交换两个字符串
#include <iostream>
using namespace std;
void swap(char *&x, char *&y)
{
char * temp;
temp = x;
x = y;
y = temp;
}
int main()
{
char *ap = "hello world";
char *bp = "how are you?";
cout << "ap: " << ap << endl;
cout << "bp: " << bp << endl;
swap(ap, bp);
cout << "ap: " << ap << endl;
cout << "bp: " << bp << endl;
return 0;
}
上面的代码就是利用传指针的引用实现字符串的交换。如果没有传递指针的引用,那么只是在swap函数中交换了两个字符串,和main函数里的ap,bp并没有什么关系。
四、指针和引用的区别
1、初始化要求不同
引用在创建的同时必须初始化
指针在定义的时候不一定要初始化
2、可修改性不同
引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用
指针可以在任何时候改变为指向另一个对象
3、不存在NULL引用
引用不能使用指向空值的引用,它必须指向一个某个对象
指针可以NULL,不需要总是指向某些对象,可以把指针指向任意的对象
4、测试需要的区别
引用不会指向空值,所以在使用引用前不需要测试它的合法性
指针可以指向任意的对象,所以需要在使用它之前检测它的合法性
5、应用的区别
如果是指一旦指向一个对象后就不会改变的指向,那么应该使用引用
如果存在指向NULL或在不同的时刻指向不同的对象这些可能性,应该使用指针。
五、指针的加减操作
我们先看下面一段代码
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5}; //第一行
int *ptr = (int *)(&a + 1); //第二行
printf("%d\n", *(a + 1)); //第三行
printf("%d\n", *(ptr - 1)); //第四行
return 0;
}
这段代码运行的时候会输出什么样的结果呢,我们来分析一下。
第一行声明了一个含有五个int类型的数组,并给这个数组初始化了。
第二行声明了一个int类型的指针,并把a的地址加一赋给了ptr;注意这里的加一加的是整个a数组的大小,因为a是含有五个int类型的数组,所以这里就是加上了20个字节;所以ptr指向了a[5];
第三行就是打印了,这里的a+1和之前&a+1不同,因为这里的a是数组的首地址也就是a[0]的地址,加上一就是a[0]的下一个元素,但是&a是整个数组的首地址,加上一就是加了整个数组的大小。所以这里会输入2.
第四行,因为ptr指向的是a[5], 所以ptr-1就会指向a[4],然后再用*解引用,就会得到a[4]的值了。
【注意】:注意a + 1和 &a + 1 的区别。
六、指针常量和常量指针的区别
指针常量就是指针的常量,它的地址不能被改变,但是可以修改其指向的内容。
例:
int * const p;
常量指针是指向常量的指针,它所指向的地址的内容是不可修改的。
例:
int const * p;
const int * p;
七、指针数组和数组指针的区别
指针数组表示一个数组,这个数组的每个元素都是一个指针。
例:
int *p[5]; //p是一个含有五个int * 元素的数组
数组指针表示一个指针,这个指针指向一个数组。
例:
int (*p)[5]; //p是一个指向含有五个int类型的数组的指针。