返回类型和return语句
- 函数的执行语句由return语句返回
- return语句结束当前正在执行的函数,将控制权返回给函数的调用者
- return语句有两种形式:
- return;
- return 表达式;
- 非void的函数必须返回一个与声明类型匹配的值,否则会引起编译错误。
函数的返回类型
- 函数的返回类型决定了函数调用表达式的类型,以及是否是左值
- 调用一个返回引用的函数得到左值
- 其他返回类型得到右值
- 返回引用的函数调用表达式可以作为左值使用
- 可以为返回类型是非const引用的函数的结果赋值
- 对应用返回值的修改会改变实际返回的对象,为了避免这种情况,可以声明为const
返回值
- 默认情况下,函数的返回值是按值传递的
- 得到控制权的函数将接收return语句中指定的表达式值的副本
- 返回值的方式和初始化变量或形参的方式完全一样
- 返回的值用于初始化调用点的一个临时量(函数调用的结果)
返回引用
- 将函数声明为返回引用,则不需要对return语句中的表达式进行复制,而是返回对象本身
- 函数返回的引用仅是指向对象的一个别名
//找出s1和s2中比较短的一个并返回其引用
const string& shorter(const string& s1, const string& s2)
{
return (s1.size() <= s2.size())? s1 : s2;
}//函数返回结果时不会真正复制对象,返回的是s1和s2本身
- 注意
- 不能返回自动局部对象的指针或引用
- 函数执行结束后,函数占用的栈存储空间被释放,原本位于这段存储空间中的局部对象和临时对象都被释放,返回的局部变量引用或指针将指向不再有效的内存区域
const string& mainp() { string ret; //局部对象ret ...... //对ret做操作 if(!ret.empty()) return ret; //错误:局部对象 else return "Empty"; //错误:临时对象 }
- 不能返回自动局部对象的指针或引用
返回列表
-
C++11的函数可以返回花括号包围的值的列表,用来初始化表示函数返回结果的临时量
- 如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定
- 如果函数返回内置类型,则花括号括起来的列表最多包含一个值,而且这个值所占的空间不应该大于返回值类型的空间
- 如果函数返回类类型,由类本身定义初始值如何使用
vector<string> func() { if(condition) return {}; else return {"Okay",str1, str2}; }
main函数的返回值
- 如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定
-
main的返回类型为int(0为成功,非0为失败),可以没有return语句(编译器隐式插入一条表示0的return语句)
-
宏EXIT_SUCCESS和EXIT_FAILURE
- 标准库中定义,用作main的返回值,表示main函数执行成功和失败
尾置返回类型的语法形式
对于返回类型比较复杂的函数最有效
auto fac(int n) -> int;
auto shorter(string& s1, string& s2) -> string&;
// func带一个int参数、返回指向大小为10的int数组的指针
int (*func(int i))[10];
// 使用尾置返回类型语法,发挥类型更清晰
auto func(int i) -> int(*)[10];