C++ 引用

引用:

1,定义:

引用就是某一变量的别名,对引用的操作与对该变量直接操作完全一样;

2,引用的声明方式:

类型标识符&引用名=目标变量名;

​ &:引用声明符

#include<iostream>
using namespace std;
int main()
{
    int x=100;
    int&rx=x;
    cout<<"rx="<<rx<<endl;
    rx=200;
    cout<<"x="<<x<<endl;
    return 0;
}

程序结果如下:

rx=100;
x=200;

main函数第2行声明了变量x的引用rx,在第三行输出rx的内容,结果为100,即变量x的值。

第四行对引用rx赋值200,在第五行输出变量x的值,x=200.

可以看出引用rx和变量x访问的是同一个内存单元。

/*声明引用时,引用前面的类型标识符是指目标变量的类型,且必须同时对其进行初始化,声明代表哪一个变量。声明完毕后,相当于目标变量有两个名称,目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。引用变量定义时,引用一块内存,该引用就不能再引用其它内存了*/
3,对引用的进一步声明:

(1)不能建立void类型的引用。

​ 任何实际存在的变量都是属于非void类型的,void含义是无类型或空类型,void只是在语法上相当于一个类型而已,所以不能建立void类型的引用

(2)不能建立数组的引用。

​ 引用只能是变量或对象的引用。数组是具有某种类型的数据的集合,其名字表示该数组的起始地址而不是一个变量,所以不能建立数组的引用

char c[6]="hello";
char &rc=c;         //错误

(3)可以将变量的引用的地址赋给一个指针,此时指针指向的是原来的变量

int a=3;             //定义整型变量a
int &b=a;            //声明b是整型变量a的引用
int *p=&b;           //指针生命p指向变量a的引用b,相当于指向a,合法

(4)可以建立指针变量的引用

int a=3;              //定义整型变量a
int*p=&a;              //定义指针变量p,并指向a
int*&rp=p;            //rp是一个指向整型变量的指针变量p的引用

由于引用不是一个独立的数据类型,不能建立指向引用的指针变量,语句“int &*p=&a”是错误的

(5)常引用。可以用const对引用加以限制,

​ 常引用声明方式:const 类型标识符&引用名=目标变量名

常引用声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到引用的安全性。

int a=3;
const int&ra=a;
ra=1;              //错误,不能通过引用对目标变量的值进行修改
a=1;                //正确

/*由于引用ra是变量a的常引用,所以通过常引用ra修改变量a的语句是非法的,而变量a是一个普通变量,所以通过变量名修改变量a的值是合法的。*/

常引用可用做函数形参,既能提高程序执行效率,又能保护传递给函数的数据不在函数中被改变,达到保护实参的目的。

void show(const string&s)
{
    s="Welcome";          //错误,不能修改常引用形参的值
    cout<<s<<endl;       //正确,只能访问常引用形参的值
}
  • 引用型形参应该在能被定义成const的情况下,尽量定义为const,这样函数调用时的实参既可以是const型,也可以是非const型

(6)可以用常量或表达式对引用进行初始化,但此时必须用const进行声明。如:

int a=3;
const int&b=a+3;   //正确

//此时编译系统将const int&b=a+3转化为:

int temp=a+3;          //先将声明式的值存放在临时变量temp中
const int &b=temp;       //声明b是temp的别名

临时变量是内部实现的,用户无法访问临时变量

这种方法不仅可以用表达式对引用进行初始化,还可以用不同类型的变量对之初始化:

double d =3,14159;            //d是double类型变量
const int&a=d;               //用d初始化a

//编译系统将“const int&a=d”转换为:

int temp=d;              //先将double类型变量转化为int型,存放在temp中
const int &a=temp;       //声明a是temp的别名,temp和a是同类型的

(7)引用作为函数的返回值。函数的返回值为引用表示该函数的返回值是一个内存变量的别名。可以将函数调用作为一个变量来使用,可以为其赋值

#include<iostream>
using namespace std
int &Max(int&x,int&y){return (x>y)?x:y}
int main()
{
    int a=2,b=3;
    cout<<"a="<<a<<"b="<<b<<endl;
    Max(2,4);
    //由于函数的返回值为引用,所以可以为函数赋值
    //为函数赋的值实际赋给了两个参数中的最大者,所以a=2,b=4;
    cout<<"a="<<a<<"b="<<b<<endl;
    return 0;
}

程序运行结果:

a=2 b=3
a=2 b=4

定义返回引用函数的时候,注意不要返回对该函数内的自动变量的引用,否则,因为自动变量的生存期仅局限于函数内部,当函数返回时,自动变量就消失了,函数会返回一个无效的引用。函数返回的引用是对某一个函数参数的引用,而且这个参数本身也是引用类型。

4,指针和引用的区别:

(1)从内存分配看:指针变量需要分配内存区域,引用不需要分配内存区域

(2)指针可以有多级,但是引用只能是一级(int * *p合法 int& &a不合法)

(3)指针的值可以为NULL,但是引用的值不能为NULL,并且引用在定义时必须初始化

(4)指针的值在初始化后可以改变,即指向其他的存储单元,而引用在进行初始化后就不能再改变了

(5)引用较指针更安全,因为指针指向的空间若被释放后,指针将成为野指针。而引用指向一块实际存在的空间

(6)定义一个指针和引用在汇编语言中是一样的

原文地址:https://www.cnblogs.com/earthmolin/p/9916029.html