引用
引用概念:
引用不是新定义一个变量,而是给已存在的变量取一个别名。编译器不给引用变量开辟空间。
创建引用变量:
C++给&符号赋予了一个新的含义,用来声明引用,如下:
int a = 10;
int& ra = a;//ra为a的引用
此处ra与a的值和地址都相同,其实就是同一内存空间的取得两个名字
注意:
- 引用变量必须初始化,且之后永不改变,即只能引用一个实体
int b = 20;
ra = b;//此处并不是将ra作为b的引用,而是赋值语句。将b的值赋给a。
- 一个变量可以有多个引用
int& rra = a;//rra也为a的引用
引用与指针的区别?
1.如果将引用写成指针形式,应该怎么写?
int& ra = a;
int *const p = &a;
2.引用与指针都可以做函数参数,但引用使用起来更方便。
- 不用解引用
void Swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void Swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
之前,我们说编译器不会给引用变量开辟空间,那么这里Swap(int&,int&)c参数是直接使用实参的吗?其实并不是,编译器在处理引用形参时,其实是将引用变量处理成指针。如图:
因此传址、传引用效率是相同的
3.引用与指针的+、-操作
int a = 10;
int ra =a;
int *pa = a;
ra++;//a++;
pa++;//指向下一个地址,指针++,加的是所指向类型的大小
4.引用在定义时必须初始化,指针不要求
int &ra;//不允许
5.没有空引用,有空指针
6.sizeof含义不同,引用结果为引用类型大小,指针始终为4(32位)/8(64位)
7.指针有多级指针,引用没有多级引用
//存在
int **ppa;
//不存在
int &&ra;
传引用、传值
double Square1(double a)
{
double ret = a*a;
return ret;
}
double Square2(double&ra)
{
double ret = a*a;
return ret;
}
在Square1中,可以使用多种参数。例如,如下
double b = Square1(a+10.0);
double c = Square1(10.0);
但这两种调用方式在Square2中都是不可使用的。那什么情况下就可以使用了呢?在Square2中使用const:
double Square2(const double &ra)//常引用
此时,如果实参与引用参数不匹配,C++将有可能生成临时变量。那什么时候会生成临时变量?
- 实参类型正确,但却不是左值
- 实参的类型不正确,但可以转化为正确的类型
什么是左值?左值是可以被引用的对象,例如,变量、数组成员、结构体、引用都是左值。非左值包括字面常量(用引号括起来的字符串除外,它们由其地址表示)和包含多项式的表达式。在C语言中,左值最初指的是可以出现在赋值语句左边的实体,但是C++中引入了const关键字之后,常规变量和const都可视为左值,因为都可通过地址访问它们。但常规变量属于可修改左值,const属于不可修改左值。
Square2(a+10.0)、Square(10.0)数据类型正确,但不是左值。
这时编译器就会产生匿名的临时变量,并让ra指向它。
int a = 10;
Square2(a);//实参的类型不正确,但可以转化为正确的类型
注意:这些临时变量只在函数调用期间存在,此后编译器可以随意将其
删除
那为什么一定要常量引用才可行呢?
看代码:
void Swap(int &ra,int &rb)
{
int temp = a;
a = b;
b = temp;
}
long a = 10,b = 20;
Swap(a,b);
由于“实参的类型不正确,但可以转化为正确的类型”,所以编译器创建两个临时变量,分别用ra、rb指向它们,Swap函数实际交换了临时变量的值,与实际意图不符。所以只有在函数的目的是使用引用变量而不是修改引用变量时,临时变量才不会造成什么不利影响。
本文探讨了C++中的引用概念,强调它作为已有变量的别名,必须初始化且不能改变引用对象。引用与指针的区别在于引用无需解引用,没有空引用,且在函数参数中使用更便捷。虽然在传址效率上两者相同,但引用在定义时必须初始化,而指针则不必。同时,介绍了左值和右值的概念,以及常量引用在函数调用中的必要性,防止错误地修改原始值。

825

被折叠的 条评论
为什么被折叠?



