函数探幽--引用变量
引用是已定义的变量的别名(另一个名称)。如果将twain作为clement作为变量的引用,则可以交替使用twain和Clemente来表示该变量。
- 引用变量的主要用途是用作函数的形参。通过将引用变量用作参数,函数将使用原始数据而不是其副本。
创建引用变量
- 要将rodents作为rats变量的别名
int rats;
int & rodents = rats;
这里的&不是地址运算符,而是类型标识符的一部分。
上述引用声明允许 rats 与 rodents 互换——他们指向相同的值和内存单元。
- 就像指针的声明中 char * 指的是指向 char 的指针一样,int &指的是指向 int 的的引用。
引用与指针的比较
int rats = 101;
int & rodents = rats; //共用一个内存空间
int * prats = &rats;
这样,表达式 rodents 和 *prats 都可以和 rats 互换,
表达式&rodents 和 prats 都可以和 &rats互换。
指针与引用的差别:
- 必须在声明引用时将他初始化,而不能像指针那样,先声明再赋值 但与const指针类似。一旦与某个变量关联起来就将一直效忠于他。
- int & rodents = rats ; 可伪装表示为 int * const pr = &rats ;
如果引用声明后再赋值,如下
int rats = 100;
int & rodents = rats ;
int bunnies=50;
rodent = bunnies; //编译器不会报错,只是将他当作简单的赋值语句。
输出结果:rats = rodents = bunnies =50;
但是:rats与rodents还是原来的地址 bunnies指向另外一个地址 。
将引用用作函数参数
下面时三种传参方式的声明与调用的对比:
void swapr(int & a,int & b); //引用传递
void swapp(int * a,int * b); //指针传递
void swapv(int a,int b); //值传递
swapr(wallet1,wallet2); //引用传递
swapp(&wallet1,&wallet2); //指针传递
swapv(wallet1,wallet2); //值传递
值传递与引用传递代码的表现形式上基本相同 只有引用传递的声明时 类型符不同
指针传递传过去的是地址,函数中的操作也都是对地址进行。
常量引用可以避免传递的参数被修改 double refccube (const double &ra)
什么时候创建临时变量?
如果引用的参数是const,则编译器在下面两种情况下生成临时变量:
- 实参类型正确,但不是左值
- 实参类型不正确,但可以转换为正确的类型。
左值是什么,左值参数是可被引用的数据对象如:变量,数组元素,结构成员,引用和接触引用的指针
非左值包括:字面常量(用引号括起来的字符串除外,他们有其地址表示)和包含多项的表达式。
下面是一个例子:
可以随意将其删除。
应尽量使用const:
使用const可以避免无意中修改数据的编程错误
使用const使函数能处理const和非const实参,否则只能接受非const数据
使用const引用使函数能够正确生成并使用临时变量
将引用用于结构
使用结构引用参数的方式与使用基本变量的引用相同,只需要在声明结构参数时使用引用运算符&即可
为什么要返回引用
即返回引用会比传统会返回机制效率更高。
返回引用是需要注意的问题
应避免返回函数终止时不再存在的内存单元的引用