什么引用:
引用是别名,创建引用时,将其初始化另外一个对象,引用(reference)是C++对C语言的重要扩充。引用的声明的方法:类型标示符 & 引用名 = 目标变量名;说明:
1、&在此不是求地址运算,而是其标识作用。
2、类型标示符是指目标变量的类型。
3、声明引用时必须对此进行初始化。
4、引用声明完毕后,相当于目标变量名优两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量的别名。
5、声明一个引用,不是新定义了一个变量,它只是表示该引用名师目标变量名的一个别名,他本身不是一个数据类型,因此引用本身不占有存储单元,系统不给引用分配存储单元。因此对引用求地址就是对变量名求地址。
6、不能建立引用的数组,因为数组是一个由若干个元素所组成的集合,所以无法建立一个由引用组成的集合。但是可以建立数组的引用。(目前有点绕,不太理解。所以最好引用不要操作数组)下面是关于这条的例子:
int& ref [3]= {2,3,5};//声明ref引用的数组错误
但是可以这样写:
const int (&ref)[3] ={2,3,5}; //gcc编译的时候加上选项 -std=c++0x
ref[0] = 35; //错误
为什么要加上const ,因为{2,3,5}此时是个字面值数组,是保存在代码段里,只读的属性,如果不加,编译错误,而且后面对ref[0]的赋值也不会成功.
下面是在代码中对上面说明进行验证上面的5条:
/*
*reference.cpp
*Date : 2013-9-19
*Author: sjin
*Mail:413977243@qq.com
*/
#include <iostream>
using namespace std;
int main()
{
int intone;
#if 1
int &rSomeRef = intone;//引用必须初始化
#else
int &rSomeRef;
rSomeRef = intone;
/*如果执行这里会报下面的错误,可以自己尝试下
* reference.cpp:17: error: ‘rSomeRef’ declared as reference but not
* initialized
*/
#endif
intone = 5;
cout << "intone :\t" << intone <<"\t\t rSomeRef :\t" << rSomeRef << endl;
cout << "&intone :\t" << &intone <<"\t rSomeRef :\t" << &rSomeRef << endl;
rSomeRef = 10;
cout << "intone :\t" << intone <<"\t\t rSomeRef :\t" << rSomeRef << endl;
cout << "&intone :\t" << &intone <<"\t rSomeRef :\t" << &rSomeRef << endl;
/*这个在很多书籍上都强调不要对引用重新赋值。
* 给引用重新赋值相当于给目标重新赋值。
* 引用的地址还是和目标变量的地址一致
*/
cout << "*******************引用重新赋值后*******************" << endl;
int inttwo = 50;
rSomeRef = inttwo;
cout << "intone :\t" << intone <<"\t\t rSomeRef :\t" << rSomeRef << endl;
cout << "&intone :\t" << &intone <<"\t rSomeRef :\t" << &rSomeRef << endl;
cout << "inttwo :\t" << inttwo <<"\t\t rSomeRef :\t" << rSomeRef << endl;
cout << "&inttwo :\t" << &inttwo <<"\t rSomeRef :\t" << &rSomeRef << endl;
cout << "*****************************************************" << endl;
return 0;
}
输出:
intone : 5 rSomeRef : 5
&intone : 0xbfb6c2d8 rSomeRef : 0xbfb6c2d8
intone : 10 rSomeRef : 10
&intone : 0xbfb6c2d8 rSomeRef : 0xbfb6c2d8
*******************引用重新赋值后*******************
intone : 50 rSomeRef : 50
&intone : 0xbfb6c2d8 rSomeRef : 0xbfb6c2d8
inttwo : 50 rSomeRef : 50
&inttwo : 0xbfb6c2d4 rSomeRef : 0xbfb6c2d8
*****************************************************
空指针和空引用
在指针没有被初始化和删除指针时,应将它们赋为空。但引用并非如此,因为必须在创建时同时将引用初始化为它指向的东西。
使用引用来实现swap()函数
/*
*swap.cpp
*Date : 2013-9-20
*Author: sjin
*Mail:413977243@qq.com
*/
#include <iostream>
#define N 0
using namespace std;
void swap2(int *x,int *y)
{
int temp;
cout << "*******************swap2(传递地址)************************" << endl;
cout << "before swap x :" << x <<"\t y :"<<y <<endl;
cout << "before swap &x :" << &x <<"\t &y :"<< &y <<endl;
temp = *x;
*x = *y;
*y = temp;
cout << "after swap x :" << x <<"\t y :"<<y <<endl;
cout << "after swap &x :" << &x <<"\t &y :"<< &y <<endl;
cout << "*******************swap2(传递地址)************************" << endl;
}
#if N
void swap(int &x, int &y)
#else
void swap(int x, int y)
#endif
{
int temp;
cout << "*******************swap()************************" << endl;
if(N == 1){
cout << "引用实现数据交换" << endl;
}else{
cout << "普通实现数据交换(错误的数据交换)"<<endl;
}
cout << "before swap &x :" << &x <<"\t &y :"<<&y <<endl;
temp = x;
x = y;
y = temp;
cout << "after swap &x :" << &x <<"\t &y :"<<&y <<endl;
cout << "*******************swap()************************" << endl;
}
int main()
{
int x = 5, y = 10;
cout << "验证引用下数据交换" << endl;
cout << "before swap, x: "<< x << "\t y: " << y << endl;
cout << "before swap, &x: "<< &x << "\t &y: " << &y << endl;
// swap(x,y);
swap2(&x,&y);/*使用指针传递*/
cout << "after swap, x: "<< x << "\t y: " << y << endl;
cout << "after swap, &x: "<< &x << "\t &y: " << &y << endl;
return 0;
}
输出结果:
/*
*swap.cpp
*Date : 2013-9-20
*Author: sjin
*Mail:413977243@qq.com
*/
#include <iostream>
#define N 0
using namespace std;
void swap2(int *x,int *y)
{
int temp;
cout << "*******************swap2(传递地址)************************" << endl;
cout << "before swap x :" << x <<"\t y :"<<y <<endl;
cout << "before swap &x :" << &x <<"\t &y :"<< &y <<endl;
temp = *x;
*x = *y;
*y = temp;
cout << "after swap x :" << x <<"\t y :"<<y <<endl;
cout << "after swap &x :" << &x <<"\t &y :"<< &y <<endl;
cout << "*******************swap2(传递地址)************************" << endl;
}
#if N
void swap(int &x, int &y)
#else
void swap(int x, int y)
#endif
{
int temp;
cout << "*******************swap()************************" << endl;
if(N == 1){
cout << "引用实现数据交换" << endl;
}else{
cout << "普通实现数据交换(错误的数据交换)"<<endl;
}
cout << "before swap &x :" << &x <<"\t &y :"<<&y <<endl;
temp = x;
x = y;
y = temp;
cout << "after swap &x :" << &x <<"\t &y :"<<&y <<endl;
cout << "*******************swap()************************" << endl;
}
int main()
{
int x = 5, y = 10;
cout << "验证引用下数据交换" << endl;
cout << "before swap, x: "<< x << "\t y: " << y << endl;
cout << "before swap, &x: "<< &x << "\t &y: " << &y << endl;
// swap(x,y);
swap2(&x,&y);/*使用指针传递*/
cout << "after swap, x: "<< x << "\t y: " << y << endl;
cout << "after swap, &x: "<< &x << "\t &y: " << &y << endl;
return 0;
}
当N为 1时:引用传递/
验证引用下数据交换
before swap, x: 5 y: 10
before swap, &x: 0xbfc5a09c &y: 0xbfc5a098
*******************swap()************************
引用实现数据交换
before swap &x :0xbfc5a09c &y :0xbfc5a098
after swap &x :0xbfc5a09c &y :0xbfc5a098
*******************swap()************************
after swap, x: 10 y: 5
after swap, &x: 0xbfc5a09c &y: 0xbfc5a098
当N为0时:按值传递
验证引用下数据交换
before swap, x: 5 y: 10
before swap, &x: 0xbff4eaec &y: 0xbff4eae8
*******************swap()************************
普通实现数据交换(错误的数据交换按值传递)
before swap &x :0xbff4ead0 &y :0xbff4ead4
after swap &x :0xbff4ead0 &y :0xbff4ead4
*******************swap()************************
after swap, x: 5 y: 10
after swap, &x: 0xbff4eaec &y: 0xbff4eae8
swap2()按地址传递
验证引用下数据交换
before swap, x: 5 y: 10
before swap, &x: 0xbfd793ec &y: 0xbfd793e8
*******************swap2(传递地址)************************
before swap x :0xbfd793ec y :0xbfd793e8
before swap &x :0xbfd793d0 &y :0xbfd793d4
after swap x :0xbfd793ec y :0xbfd793e8
after swap &x :0xbfd793d0 &y :0xbfd793d4
*******************swap2(传递地址)************************
after swap, x: 10 y: 5
after swap, &x: 0xbfd793ec &y: 0xbfd793e8