⚓️作者简介:即将大四的北京某能源高校学生。
📚座右铭:“九层之台,起于垒土” 。所以学习技术须脚踏实地。
📖这里推荐一款刷题、模拟面试神器,可助你斩获大厂offer:点我免费刷题、模拟面试
函数是一个命名了的代码块,我们通过调用函数指向相应的代码,函数通常具有参数,对参数进行操作后会产生相应的作用或结果。我们可以使用return语句终止当前正在执行的函数并将控制权返回到调用该函数的地方。
根据函数是否有返回值,可将函数分为有返回值的函数和无返回值的函数。
无返回值的函数没有返回值,所以可以没有 return 语句或仅有 return;
来结束函数的执行。如果没有 return 语句,函数会在最后一句后面隐式地执行 return,return;
也可以在函数中间,用于提前结束函数的执行。
void swap(int &v1, int &v2){
if(v1 == v2)
return ; //程序提前退出,类似循环中的break。
int tmp = v2;
v2 = v1;
v1 = tmp;
//这里隐式执行return;
}
这个函数首先检查值是否相等,相等则直接退出函数,不相等则进行交换,最后一句赋值语句后面隐式执行return语句。
void 函数也可以使用 return expression;
这种形式的语句,不过 expression 需要是一个返回 void 的函数,返回其他类型将会编译出错。
有返回值的函数使用 return expression;
语句返回值,返回值不能为void。expression 的类型必须与函数类型相同,或者能隐式转换为函数类型。
C++无法确定结果的正确性,但是可以保证每个return语句的结果类型相同。
与无返回值的函数一样,返回类型与函数类型不同的话,编译器将会检测出这个错误
C++ 中从函数返回(不考虑异常、 longjmp 等非正常退出方式)的过程是个稍微有点长的话题…,这里我也是略知一二,很浮浅地简介一下。
首先初始化返回值,返回值的过程和返回类型有关:
初始化完返回值后,依次进行以下操作:
在标准语义中,控制已经离开了该函数,函数调用表达式的类型和值类别按以下方式确定:
函数调用完成,函数体内的局部变量的内存被释放了,因为局部变量的生命期仅存在于函数的作用域。如果返回值的类型为引用或指针的话,该局部变量消失,调用函数得到的引用绑定的对象不再存在,即引用无效,或者调用函数得到的指针也将指向一个不存在的对象。此时引用与指针会变成垂悬引用或垂悬指针。
const string &func(){
string result;
//操作result
if(result.empty())
return "empty";
else return result;
}
上面两条语句都会返回未定义的值,第一条返回的是局部临时量的引用,第二条返回的是局部变量的引用,两者在函数调用完都会被释放,此时的引用就与一个空地址绑定,成了垂悬引用。
介绍尾置返回类型前先看一下返回一个指向数组的指针的函数:
int (*func(int i))[10];
我们按照下面的顺序来理解这个函数声明:
由此可见返回复杂类型的函数的定义是很麻烦的,一不小心就会出错,所以我们可以使用尾置返回类型或decltype来简化函数的声明方法。事实证明,这些方法用起来是很有效的。
在本该出现函数类型的地方使用关键字 auto 替代,将函数真正的返回类型置于函数的形参列表之后,中间用 -> 连接,这样就是尾置返回类型声明函数的方法了。
下面使用尾至返回类型声明上面的函数:
auto func(int i)->int (*)[10];
这样就很简单明了,函数与返回类型分开,可以逐个击破,也不容易混淆。
另外一个使用decltype的方法也能简化复杂函数的声明:
int arr[10];
decltype(arr) *func(int i);
使用关键字decltype提取出arr的类型为含有十个元素的数组,func前面的 * 运算符表示func返回的是指针,所以func返回的类型就是指向含有十个元素的数组的指针。
使用decltype同样可以将函数的返回类型提取出来,但需要一个变量来声明函数的返回类型,所以用起来就没有尾置返回类型明了。
🎉总的来说本文讲解的函数返回类型的知识点对于入门的初学者是足够了,再深究的话需要较深厚的计算机组成的基础与足够的C++编程经验。博主争取努力学习,再将这些深入的知识浅显易懂地讲给大家。
希望大家多多关注,三连支持。你们的支持是我源源不断创作的动力。