菜鸟教程 - C++ 把引用作为返回值
先上代码:
#include <iostream>
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
return vals[i]; // 返回第 i 个元素的引用
}
// 要调用上面定义函数的主函数
int main ()
{
cout << "改变前的值" << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
setValues(1) = 20.23; // 改变第 2 个元素
setValues(3) = 70.8; // 改变第 4 个元素
cout << "改变后的值" << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return 0;
}
看到这部分时,一直想不通
setValues(1) = 20.23;
这步是什么意思,怎么就改变了值了呢,一度认为是不是代码写错了或者遗漏了什么。
但是经本地代码编译实践,输出正常代码没错,后来经同事点拨才恍然大悟,下面一块来辨析下!
我错在哪里
根据以往经验,函数嘛无非就是封装执行一些功能,如有必要的话将结果通过返回值返回;而返回值通常会加以再利用,常见的是赋值给其他变量或者再参与运算。
即总觉得有返回值的函数调用都发生在“=”右边(即作为右值使用),现在冷不丁放在左边就蒙了,错就错在这个惯性思维,忽略了这里是在讲引用,现在想来真是犯了低级错误,也片面的理解了左、右值!
概念理解
什么是引用
菜鸟教程 - C++ 引用
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。
一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
#include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
左值(Lvalues)& 右值(Rvalues)
C++ 中有两种类型的表达式:
- 左值(lvalue):指向内存位置的表达式被称为左值表达式。
左值可以出现在赋值号的左边或右边。 - 右值(rvalue):术语右值指的是存储在内存中某些地址的数值。
右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。
变量是左值,因此可以出现在赋值号的左边。
数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边,这是一个有效的语句:int g = 20;
。
但是这个就不是一个有效的语句,会生成编译时错误:10 = 20;
。
其实这里解释的已经很清楚了,只怪自己当初看时只记住的“左、右值”这么个概念,而没有好好理解其本质。
代码辨析
double& setValues( int i )
{
return vals[i]; // 返回第 i 个元素的引用
}
setValues(1) = 20.23; // 改变第 2 个元素
引用作为返回值,返回的相当于是一个变量,当然可以作为左值,对其进行赋值操作,这一步就等价于:
vals[i] = 20.23;
不是多大的问题,只怪自己太粗心!