1.定义
变量有两个属性:名称+内存空间
引用只有一个属性:名称
引用不是变量
引用是一个变量的别名,它没有自己独立的内存空间,和它所指向的变量共享内存空间
对引用所做的改变就是对它所指向的变量所做的改变
引用定义时必须初始化,并且初始化后不能再成为其他变量的引用
语法:
类型 &引用名 = 变量
2.const引用
const引用可以是const变量的引用,也可以是非const变量的引用
非const引用只能是非const变量的引用
int类型的引用 作为double变量的引用 只能将引用定义为const才是对的。
double a3 = 3.14;
const int &b3 = a3; //ok 等价于产生一个临时变量 int temp=a3, const int &b3=temp
//int &c3 =a3; //error 系统不会产生一个临时的int型变量
解释一下为什么加上const才可以:因为系统产生了一个临时变量,设临时变量为temp,b3指向的是temp而不是a3,如果定义b3时没有const修饰,那么可以根据b3来修改值,当时b3的修改只能修改temp的值,而不能修改a3的值,这就与引用的定义矛盾,所以索性编译器就不让b3修改内容,因此只有加上const才是对的。
3.引用作为函数参数
当函数被调用的时候引用初始化
4.引用作为函数返回值
当函数返回值时初始化
一定不要返回局部变量的引用
可以将函数写在赋值运算符的左边
5.引用值指针的区别
(1)引用时直接访问,指针是间接访问
(2)引用没有自己独立的内存空间,指针有自己的内存空间(4个字节,32bit系统)指针的实质是一个变量
(3)引用一经初始化就不能做其他变量的引用,指针只要不为const类型,可以指向不同的变量
6.注意事项
(1)不能建立void类型的引用 因为没有void类型的变量
(2)不能建立引用的数组 因为没有办法初始化
(3)可以将变量的引用的地址赋值给一个指针,此时指针指向的是原来的变量
(4)不能定义指向引用类型的指针变量 因为引用不是一种独立的数据类型,换句话说没有int& 这种类型的变量
int a=3;
//int& *p = &a; //error
(5)可以建立指针变量的引用
(6)可以使用const对引用限定,不允许修改该引用的值
(7)用常量或者表达式初始化引用时,一定要加const
(8)创建不同类型的引用时,一定要加const,系统生成一个临时变量
尽可能的使用引用,不得已时再使用指针。
值传递:为形参分配内存空间,将实参的值赋值为形参
地址传递:指针传递,实质还是值传递,传递的是地址而已
引用传递:不分配内存,没有赋值拷贝操作
下面通过程序来理解引用的应用:
#include <iostream>
using namespace std;
void swap1(int a,int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void swap2(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int& sum(int a, int b) //返回局部变量的引用
{
int temp;
temp = a+b;
return temp;
}
int a[] = {0,1,2,3,4};
int& change(int i) //返回全局变量的引用
{
return a[i];
}
int main()
{
int a =100;
int c = 300;
//int &b; //error,必须要进行初始化
int &b=a;
b=200;
cout<<b<<endl; //200
b = c; //并不代表b重新指向了c,只是将c的值赋值给了b所指向的变量
cout<<b<<endl; //300
c = 500;
cout<<b<<endl; //300
//const引用,用来指向const变量的引用
const int a1=100;
const int &q = a1; //ok;
const int &q1 = a; //ok q1为常量
//q1 = 200; //error
//int &q2 = a1; //error 如果这条语句是合法的,q2是可以修改a1的内容的,但是a1是常量不能修改
//q = 200; //error q为常量
double a3 = 3.14;
const int &b3 = a3; //ok 等价于产生一个临时变量 int temp=a3, const int &b3=temp
//int &c3 =a3; //error 系统不会产生一个临时的int型变量
//引用作为参数传递,在函数调用时引用初始化
int x=3, y=4;
swap1(x,y);
cout<<"x="<<x<<",y="<<y<<endl; //swap不成功
swap2(x,y);
cout<<"x="<<x<<",y="<<y<<endl; //swap成功,引用在函数调用的时候出事后
//引用作为返回值,可以将函数放到赋值运算的的左边,引用在函数返回的时候初始化
//不要返回局部变量的引用
change(3) = 100; //change()函数出现在赋值运算符的左边
int n = sum(x,y); //将局部变量的值赋给了n,n有自己的内存
int &n2 = sum(x,y); //将局部变量的起别名n2,与局部变量共享内存,函数调用完后,内存销毁
cout<<n<<endl; //7
cout<<n2<<endl; //不确定的数
return 0;
}