- 引用的概念
引用不是定义了一个新变量,而是给已经存在的变量取一个别名,编译器不会为引用变量开辟空间,它和它引用的变量共用一块内存空间。
使用方法如下:
int main()
{
int a=10;
int &b=a;//定义引用类型
printf("%d\n",a);
printf("%d\n",b);
printf("%p\n",&a);
printf("%p\n",&b);
return 0;
}
运行一下,看结果如下,清楚看出二者地址相同
需要注意的一点是引用类型必须和引用实体是同种类型的,例如上面的代码a是int型的,那么引用类型必须也是int型。
- 引用特性
1.引用在定义时必须初始化,例如int &a;如果在你的代码里出现这句代码编译器就会报错
2.一个变量可以有多个引用,这句话好理解,就像一个人可以有多个外号,可能你的同学叫你XXX,你在家家人叫你XX,一个道理
3.引用一旦引用一个实体,再不能引用其他实体
- 常引用
看一组问题
//前提:
const int a = 10;
const int b = 10;
int c = 10;
double d = 1.11;
//下面这些代码谁对谁错??
int &r1 = a;
const int &r2 = b;
int r3 = b;
int *p1 = &b ;
const int *p2 = &b ;
int *p3=&c ;
const *p4=&c ;
int &r4 = d;
const int &r4 = d;
一个一个分析,在此之前先说一个赋值规则,权限可以缩小但是权限不可以放大
1.错误,a自己都不能随意更改,被引用后更不能随意更改了
2.正确,b不能随意更改,引用也不能随意更改
3.正确,只是将b的值赋给r3,就算更改r3也与b无关了
4.错误,b不能随意更改,权限不能放大
5.正确,同2
6.正确,c可以随意更改,引用后也一样
7.正确,权限缩小可以
8.错误,d是double型的,r4其实是引用了中间的那个临时变量
9.正确
- 引用的使用场景
1.作参数
用一段简单的代码解释
void swap(&a,&b)
{
int c=a;
a=b;
b=c;
}
int main()
{
int x1=10,x2=20;
swap(x1,x2);
cout<<x1<<endl;
cout<<x2<<endl;
return 0;
}
2.作返回值
这段代码是否可以运行?
int Arr(int i)//改成int &Arr(int i)
{
static int a[10]={0,1,2,3,4,5};
return a[i];
}
int main()
{
Arr(3)=10;
cout<<Arr(3)<<endl;
return 0;
}
不可以运行,原因是给Arr(3)赋值10的时候其实并不是真的给a[3]赋值了10,而是给它的拷贝赋值了10,改变它的拷贝对a[3]本体没有影响。修改后就可以了,因为此时是给a[3]的引用赋值了10,改变他的引用,本体也修改了,所以可行。
再提到一点,如果删去static是否可行呢?不可行,因为删去static的话,返回值出了作用域也就是函数Arr()就会被销毁。
所以你们觉得下面这段代码输出的是多少?3?其实是7,原因和上面一样,在函数返回时,离开函数作用域后,其栈上看见已经还给系统,因此不能用栈上的空间作为引用类型返回。如果以引用类型返回,返回值得生命周期必须不受函数限制。
int &Add(int a,int b)
{
int c=a+b;
return c;
}
int main()
{
int &ret =Add(1,2);
Add(3,4);
cout<<"Add(1,2) is:"<<ret<<endl;
return 0;
}
我们都知道以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递形参,就是实参的一份临时拷贝,这样效率是十分低下的,尤其是当参数或者返回值类型非常大时,效率更低,所以说我们在传值和返回时传引用效率更高。
- 引用和指针的差别
前面说了,引用就是一个别名,没有独立空间,和被引用实体共用一块空间,但其实引用在底层实现上是有空间的,因为引用是按照指针方式来实现的。
那么引用和指针的不同之处是什么呢?
- 引用在定义是必须初始化,而指针没有要求
- 指针可以在任何时候指向任何一个同类型的实体,而引用不行
- 没有NULL引用但是有NULL指针
- 在sizeof中含义不同,引用结果为引用类型的大小,而指针始终是地址空间所占字节个数(32位平台占4个字节)
- 有多级指针,没有多级引用
- 访问实体的方式不同,指针需要显式解引用,引用是编译器自己处理
看上去指针比引用更加好用,但是为什么还是需要大量用到引用呢?因为引用比指针用起来相对更加安全