函数的返回值不能是数组或函数,但是可以是是数组和函数的指针或引用
函数返回一个值的过程和初始化完全一致,先创建一个临时变量,用返回值初始化该临时变量,然后用该临时变量去初始化另一个变量或者给另一个变量赋值
所以函数的返回值只是返回对象的拷贝
int func()
{
int a=1;
return a;
}
int b=func();
在上面的代码中,函数并不是返回a本身,而是返回a的拷贝,这个拷贝在一个临时变量里存放,a在函数作用域结束后被释放,无效,之后用该临时变量来初始化b
不能返回局部变量的引用和指针
const string &localparatest()
{
string res;
if (res.empty()) {
return "empty";
}
else {
return res;
}
}
上述代码编译时会提示返回局部变量的引用,因为局部变量在函数作用域结束时就会被释放,所以引用将绑定一个无效的变量,导致出现该警告
同理,也不要返回局部变量的指针,因为函数结束后,局部变量的指针将指向一块无效的内存区域
所以,不要返回局部变量的指针和引用
引用是左值,可以放在等号左边,而函数可以返回引用,所以返回合法引用的函数可以作为左值,来绑定变量
int main(int argc, char const *argv[])
{
string str="asdf";
char a='q';
returnreference(str, 2)=a;
cout<<str<<endl;
return 0;
}
char &returnreference(string &str,
string::size_type index)
{
assert(index<str.size());
return str[index];
}
函数returnreference返回字符的引用,所以可以将returnreference作为左值(实际是str的第三个字符)来绑定字符变量a
所以str的第三个字符被改为q
返回数组指针和引用
函数不能返回数组,但是可以返回数组的指针和引用,声明或定义一个返回数组的指针或引用的函数比较麻烦,代码如下:
int (*returnarrayp(int a))[10];
int (&returnarrayr(int a))[10];
上述代码读法和写法的规则都遵循先中间,再两边的规则,参见C++知识点6——数组与指针初步
int (*returnarrayp(int a))[10]
先看中间returnarrayp(int a),是一个形参为int的函数,再看左边星号,返回的是一个指针,该指针指向一个int数据,看到右边的[10]得知该指针指向一个int数组,数组的大小为10
int (&returnarrayr(int a))[10];同理
示例
int arr[3][3]={};
int main(int argc, char const *argv[])
{
int (*p)[3]=returnarrayp(3);//函数调用
for (int i=0;i<3*3;++i) {
cout<<p[i/3][i%3]<<endl;
}
return 0;
}
int (*returnarrayp(int a))[3]
{
for (int i=0;i<3*3;++i) {//一次循环给二维数组赋值
arr[i/3][i%3]=a;
}
return &arr[0];//返回数组的指针
}
注意:函数返回数组的指针或引用时,返回值数组的维度和函数声明时数组的维度必须一致,否则报错,原因是因为如果数组的指针指向一个二维数组,那么必须和二维数组里的每一个一维数组匹配
返回数组的引用的函数示例
int arr[3][3]={};
int main(int argc, char const *argv[])
{
int (&r)[3]=returnarrayr(4);
for (int i=0;i<3;++i) {
cout<<r[i]<<endl;
}
return 0;
}
int (&returnarrayr(int a))[3]
{
for (int i=0;i<3*3;++i) {
arr[i/3][i%3]=a;
}
return arr[0];
}
注意:main函数中,数组的引用r只绑定了二维数组中的第一个一维数组,所以不能用一维数组的引用遍历二维数组,否则报错
而二维数组可以通过数组指针遍历,因为指针可以指向不同的内存,而引用只是固定的绑定对象
参考:
《C++ Primer》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出