在生活中,一个人常常有多个称呼,人们可以根据称呼联想到这个人,不管是名字,学号,还是别名
都代表这个人,那么在程序中,一个变量代表着一块连续的内存空间,我们定义一个整型变量a,则a
代表一块四个字节的内存空间,他的首地址是0x1000 ,那么我们是否可以用另一个名称代表这一块空
间呢,有人会想到指针,用指针指向这一块空间,但跟我们说的别名是两回事,
在c语言中,定义一个指针p指向变量a,p并不代表a所代表的空间的别名,只是一种指向关系,实际
上p本身就是一块内存空间,
c++中提供了给变量定义的别名的机制,那就是引用,引用类似于指针,只是用&取代了*,语法格式
为:
type *name = date ;
type是被引用的数据的类型,name是引用的名称,date是被引用的数据,引用必须在定义的同时进行初始化,不能中途改变,例如:
#include <iostream>
using namespace std ;
int main ()
{
int a = 10 ;
int &b = a ;
cout << "a = " << a << "b = " << b << endl ;
cout << "&a = " << &a << "&b = " << &b << endl ;
b = 20 ;
cout << "a = " << a << "b = " << b << endl ;
return 0 ;
}
由此可看,a和b的地址一样,变量b是a的引用,他们代表着同一份数据。都指向同一个地址,因此a和b的数据一样,对谁赋值都一样,
引用作为函数参数
在c语言中,函数参数传递有两种,即值传递和地址传递,现在又多了一个引用,
在定义或声明函数时,我们可以将函数的形参指定为引用的形式,这样在调用函数时就会将实参和形参绑定在一起,让它们都指代同一个数据,因此,如果更改了形参的值,那么实参的值也会被修改,达到了“在函数内部能影响函数外部数据”的效果,下面我们通过交换两个变量的值,来比较值传递,地址传递,和引用传递的不同
#include<iostream>
using namespace std;
//值传递
void swap1(int a,int b)
{
int temp = a ;
a = b ;
b = temp ;
}
//地址传递
void swap2(int *pa,int *pb)
{
int temp = *pa ;
*pa = *pb ;
*pb = temp ;
}
//引用传递
void swap3(int &a,int &b)
{
int temp = a ;
a = b ;
b = temp ;
}
int main ()
{
int num1 = 10 ;
int num2 = 20 ;
swap1(num1,num2);
cout << "num1 = "<< num1 << " " << "num2 = " << num2 << endl ;
swap2(&num1,&num2) ;
cout << "num1 = " << num1 << " " << "num2 = " << num2 << endl ;
swap(num1,num2) ;
cout << "num1 = " << num1 << " " << "num2 = " << num2 << endl ;
return 0 ;
}
对于函数swap1()直接传递参数的内容,不能达到交换连两个变量值的目的,对于swap2(),传递的是指针,能够达到交换两个变量值的目的,调用函数时,分别将num1,num2的指针传递个pa,pb,可以从内部通过指针间接的修改num1,num2的值,对于swap3(),通过引用传递,将a,b的值绑定到num1和num2中,修改哪一个数据都会随之改变。
引用作为函数返回值
引用不仅仅可以作为函数形参,还可以作为函数的返回值,但要注意的是,不能返回局部数据(局部变量,局部对象,局部数组)的引用,因为当函数调用结束后,局部数据就会被摧毁,有可能下次使用的时候数据就不存在了。因此我们可以返回一个全局变量或者静态变量的引用,对于将引用作为函数返回值的函数,有四种处理方式
- 不接收函数返回值
- 用一个普通变量接收函数返回值,这时接收的是变量的值而不是变量的引用
- 用一个引用接收函数返回值,接收的是一个引用
- 当成左值来使用
通过以下代码进行解释
#include<stdio.h>
#include<iostream>
int& fun()
{
static int a ;
a++ ;
printf ("a = %d\n",a) ;
return a ;
}
int main ()
{
fun() ;
int a = fun() ;
printf ("main a = %d\n",a) ;
a = 20 ;
fun() ;
int &b = fun() ;
printf("b = %d\n",b) ;
b = 30 ;
fun() ;
fun() = 100 ;
printf("b = %d\n",b) ;
return 0 ;
}