C++引用变量笔记
来源:互联网 发布:cf网截分析数据 编辑:程序博客网 时间:2024/06/16 09:09
引用是已定义的变量的别名,引用的主要用途是用作函数的形参。通过将引用变量用作参数,函数将使用原始数据而不是其副本。
创建引用变量
c和c++使用&符号来指示变量的地址。c++给&赋予了另一个含义,将其用来声明引用变量。例如,将rodents作为rats变量的别名,可以这样做
int rats;int & rodents = rats; //makes rodents an alias for rats
&不是地址运算符,而是类型标志符的一部分。int & 是指向int的引用。上述引用声明允许rats与rodents互换—他们指向相同的值与内存单元。
对于C语言用户而言,首次接触到引用时可能会有些困惑,因为这些用户很自然的想到指针,但是他们之间是有区别的。例如,可以创建指向rats的引用和指针:
int rats = 101;int & rodents = rats; //rodents a referenceint * prats = &rats; //prats a pointer
这样,表达式rodents(值)和*prats(值)都可以与rats(值)互换,而表达式&rodents(地址)与prats(地址)都可以通&rats(地址)互换。从这一点上来看,引用很像伪装表示的指针。但是,引用还是不同于指针的。除了表示法不同外,差别之一是,必须在声明引用时将其初始化,而不能像指针那样,先声明,再赋值:
int rat;int & rodent;rodent = rat; //No, you can't do this
注意:必须在声明引用变量时进行初始化。
引用更接近construction指针,必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于他。也就是说:
int & rodents = rats;
实际上是下述代码的伪装表示:
int * const pr = &rats;
其中,引用rodents扮演的角色与表达式*pr相同。
将引用用作函数参数
引用经常用作函数参数,使得函数中的变量名成为调用程序中的变量别名。这种传递参数的方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。C语言只能按值传递,按值传递导致被调用函数使用调用程序的值的拷贝。C语言避开按值传递的限制使用的是按指针传递方式。
//swap.cpp --- swapping with references and with points#include <iostream>void swapr(int & a, int & b); //a,b are aliases for intsvoid swapp(int * p, int * q); //q,q are addresses of intsvoid swapv(int a, int b); //a,b are new variablesint main(){ using namespace std; int wallet1 = 300; int wallet2 = 350; cout << "wallet1 = $" << wallet1; cout << " wallet2 = $" << wallet2 << endl; cout << "Using references to swap contents:\n"; swapr(wallet1, wallet2); //pass variables cout << "wallet1 = $" << wallet1; cout << " wallet2 = $" << wallet2 << endl; cout << "Using pointers to swap contents again:\n"; swapp(&wallet1, &wallet2); //pass addresses of variables cout << "wallet1 = $" << wallet1; cout << " wallet2 = $" << wallet2 << endl; cout << "Trying to use passing by value:\n"; swapv(wallet1, wallet2); //pass values of variables cout << "wallet1 = $" <<wallet1; cout << " wallet2 = $" << wallet2 << endl; return 0;}void swapr(int & a, int & b) //use references{ int temp; temp = a; //use a,b for values of variables a = b; b = temp;}void swapp(int * p, int * q) //use pointers{ int temp; temp = *p; //use *p,*q for values of variables *p = *q; *q = temp;}void swapv(int a, int b) //try using values{ int temp; temp = a; //use a, b for values of variables a = b; b = temp;}
比较函数swapr()(按引用传递)与swapv()(按值传递)的代码。唯一的外在区别是声明函数参数的方式不同。
void swapr(int & a, int & b)void swapv(int a, int b)
内在的区别在于,在swapr()中,变量a和b是wallet1和wallet2的别名,所以变换a和b的值相当于交换wallet1与wallet2的值,但在swapv()中,变量a和b是复制了wallet1与wallet2的值的新变量,因此交换a与b的值不会影响wallet1与wallet2的值。
比较函数swapr()(传递引用)和swapp()(传递指针)。第一个区别是声明函数参数的方式不同:
void swapr(int & a, int & b)void swapp(int * p, int * q)
另一个区别是指针版本需要在函数使用p和q的整个过程中使用解除引用运算符*。
引用的属性与特别之处
下面看一个例子:
#include <iostream>double cube(double a);double refcube(double &ra);int main(){ using namespace std; double x = 3.0; cout << cube(x); cout << " = cube of " << x << endl; cout << refcube(x); cout << " = cube of " << x << endl; return 0;}double cube(double a){ a *= a * a; return a;}double refcube(double &ra){ ra *= ra * ra; return ra;}
运行结果:
refcube()函数修改了main()中的x值,而cube()没有,这提醒我们为何通常按值传递。变量a位于cube()中,他被初始化为x的值,但是修改a并不会影响x。但是由于refcube()使用了引用参数,因此修改ra实际上就是修改x。如果想要让函数传递给他信息时不对这些信息进行修改,同时又想使用引用,则应该使用常量引用。例如,在这个例子中,应在函数原型和函数头中使用const:
double refcube(const double & ra);
但是,这样做在进行编译时会生成错误信息,具体报错信息如下:
应尽可能使用const
将引用参数声明为敞亮数据的引用的理由有三个:
1. 使用const可以避免无意中修改数据的编程错误;
2. 使用const使函数能够处理const和非const实参,否则只能接受非const数据。
3. 使用const引用使函数能够正确生成并使用临时变量。
因此,应尽可能将引用形参声明为const。
- C/C++中关于地址、指针和引用变量的学习笔记(十) : 引用型变量
- 【C++】学习笔记四十——引用变量
- 【C++】引用变量
- C++引用变量笔记
- 【C++】引用变量(1)
- C++学习笔记,引用变量
- C/C++中关于地址、指针和引用变量的学习笔记(一)
- C/C++中关于地址、指针和引用变量的学习笔记(二) : 数组
- C/C++中关于地址、指针和引用变量的学习笔记(三) : 结构
- C/C++中关于地址、指针和引用变量的学习笔记(四) : 函数
- C/C++中关于地址、指针和引用变量的学习笔记(五) : 指针
- C/C++中关于地址、指针和引用变量的学习笔记(六) : const和void
- C/C++中关于地址、指针和引用变量的学习笔记(七) : sizeof和typedef
- C/C++中关于地址、指针和引用变量的学习笔记(八) : 命令行参数
- C/C++中关于地址、指针和引用变量的学习笔记(九) : 内存结构
- 【笔记-C语言】 变量
- c语言形参中的引用变量
- C语言 变量的跨文件引用
- 产品测试过程
- JAVA | 18
- Servlet中的监听器简介
- python学习---第三天
- 欢迎使用CSDN-markdown编辑器
- C++引用变量笔记
- rxjava学习分享计划
- 2017ICPC青岛K Our Journey of Xian Ends
- JavaScript基础
- C++ 类与对象的定义与引用
- none of the 1 split apks are compatible with the current device with density "-1" and ABIs "". 解决办法
- 协方差和协方差矩阵
- CodeForces
- ceph集群部署流程