目录
引用:
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)定义一个指针和引用在汇编语言中是一样的
[TOC]