返回类型和 return 语句
return 语句终止当前正在执行的函数并将控制权返回到调用该函数的地方。return 语句有两种形式:
return;
return expression;
不要返回局部对象的引用或指针:
函数完成后,它所占用的存储空间也随之被释放掉。因此函数终止意味着局部变量的引用和指针将指向不再有效的内存区域:
一种典型的错误就是将一个指向局部变量的指针作为函数的返回值。由于该数组是局部变量,因此在函数返回时其数组空间已经作废了,即指针应用一块无意义的地址空间,所以不会有返回值。如果得到正常的值,只能是幸运的退出函数的时候,系统只是修改了栈顶的指针,并没有清内存; 所以,是有可能正常访问到局部变量的内存的。 但因为栈是系统自动管理的,所以该内存可能会被分配给其他函数,这样,该内存的内容就会被覆盖;不再是原来的值了。
#include <iostream>
using namespace std; const string &cmp(void){
const string s1 = "hdfl", s2 = "jflds";
return s1 > s2 ? s1 : s2;
} int main(void){
const string s = cmp();
// cout << s << endl;//错误,cmp 返回是一个指向被释放的无效内存区的引用
return ;
}

如前所述,返回局部对象的引用是错误的,同样返回局部对象的指针也是错误的。一旦函数完成,局部对象被释放,指针将指向一个不存在的对象。
引用返回左值:
函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其他返回类型得到右值。所以能为返回类型是非常量引用的函数的结果赋值:
#include <iostream>
using namespace std; char &gel(string &str, size_t indx){
return str[indx];
} int main(void){
string s("a value");
cout << s << endl;//输出 a value
gel(s, ) = 'A';//将s[0]的值改成A
cout << s << endl;//输出A value
return ;
}
当然,如果函数返回的是常量引用,自然是不能给调用结果赋值的。
列表初始化返回值:
c++11 规定,函数可以返回花括号包围的值的列表。类似于返回其他结果,此处的列表也用来对表示函数返回的临时变量进行初始化。如果列表为空,临时量执行值初始化,否则,返回的值由函数的返回类型决定:
#include <iostream>
#include <vector>
using namespace std; vector<string> gel(void){
return {"fjls", "fjsl", "gel", "yy"};
} int main(void){
vector<string> s = gel();
for(auto indx : s){
cout << indx << endl;
}
return ;
}
如果函数返回的是内置类型,则花括号包围的列表中最多包含一个值,而且该值所占空间不应该大于目标类型的空间。如果函数返回的是类类型,由类本身定义初始值如何使用。
返回数组指针:
因为数组不能拷贝,所以函数不能返回数组。不过,函数可以返回数组的指针或引用:
#include <iostream>
using namespace std; typedef int arrT[];//arrT是一个类型别名,表示的类型是含有10个整数的数组
// using arrT = int[10];//arrT的等价声明
typedef int arry[][]; arrT* gel(arrT& x){//x是数组a的引用
return &x;
} arrT& lou(arry& x){
return x[];
} int main(void){
arrT a = {, , };
arrT *b = gel(a);//相当于b指向a
for(auto indx : *b){//b是一个指针,需要解引用
cout << indx << " ";
}
cout << endl;
// 输出 1 2 3 0 0 0 0 0 0 0
arry c = {{, , }};
arrT &d = lou(c);//返回c的第一个数组元素的引用
for(auto indx : d){
cout << indx << " ";
}
cout << endl;
// 输出 1 2 3 0 0 0 0 0 0 0
return ;
}
当然,不使用类型别名也是可以的,但是要麻烦一些。其声明如下:
Type (*function(parameter_list))[dimension]
其中 Type 表示元素类型,dimension 表示数组的大小,类似于一般的数组指针声明。(*function(parameter_list)) 两端的括号必须存在,如果没有则函数的返回类型将是指针的数组。
#include <iostream>
using namespace std; int (*gel(int (&a)[]))[]{//注意:返回指针不能是局部对象
return &a;
} int (&lou(int (&a)[][]))[]{//注意:返回引用不能是局部对象
return a[];
} int main(void){
int a[] = {, , };
int (*b)[] = gel(a);
for(auto indx : *b){
cout << indx << " ";
}
cout << endl;
//输出 1 2 3 0 0 0 0 0 0 0 int c[][] = {{, , }};
int (&d)[] = lou(c);
for(auto indx : d){
cout << indx << " ";
}
cout << endl;
//输出 1 2 3 0 0 0 0 0 0 0
return ;
}
尾置返回类型:
在 c++11 中还有一种可以简化上述 gel 函数声明的方法,就是使用尾置返回类型。任何函数的定义都能使用尾置返回,但是这种形式对于返回类型比较复杂的函数最有效,比如返回类型是数组的指针或者数组的引用。尾置返回类型跟在形参列表后面并以一个 -> 符号开头。为了表示函数真正的返回类型,我们在本应该出现返回类型的地方放置一个 auto:
#include <iostream>
using namespace std; auto gel(int (&x)[]) -> int(*)[]{//使用尾置返回类型返回数组指针
return &x;
} auto lou(int (&x)[][]) -> int(&)[]{//使用尾置返回类型返回数组引用
return x[];
} int main(void){
int a[] = {, , };
int (*b)[] = gel(a);
for(auto indx : *b){//b是指针,需要解引用
cout << indx << " ";
}
cout << endl;
//输出 1 2 3 0 0 0 0 0 0 0 int c[][] = {{, , }};
int (&d)[] = lou(c);
for(auto indx : d){
cout << indx << " ";
}
cout << endl;
//输出 1 2 3 0 0 0 0 0 0 0
return ;
}
使用 decltype:
还有一种情况,如果我们知道函数返回的指针将指向哪个数组,就可以使用 decltype 关键字声明返回类型:
#include <iostream>
using namespace std; int a[]; decltype(a) *gel(int (&x)[]){
return &x;
} decltype(a) &lou(int (&x)[][]){
return x[];
} //注意:decltype(a)返回的只是一个数组,并不会将数组类型转化成指针或者引用类型,所以还要再加一个指针或引用声明符 int main(void){
int b[] = {, , };
int (*c)[] = gel(b);
for(auto indx : *c){
cout << indx << " ";
}
cout << endl;
//输出1 2 3 int d[][] = {{, , }};
int (&e)[] = lou(d);
for(auto indx : e){
cout << indx << " ";
}
cout << endl;
//输出1 2 3
return ;
}
返回类型和 return 语句的更多相关文章
- 函数----基础,参数传递,返回类型和return语句
一.函数基础1.形参和实参 实参是形参的初始值.第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推.尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序.编译器能以任意可行的顺序对实 ...
- 返回类型和return语句
return语句终止当前正在执行的函数并将控制权返回到调用该函数的地方.return语句有两种形式: return; return expression; 无返回值函数 没有返回值的return语句只 ...
- 【c++ primer, 5e】返回类型和return语句
[无返回值函数] 1.在c++的void函数中,可以显式地使用return;语句来提前结束函数的调用. [有返回值函数] 1.值是如何被返回的:返回一个值的方式和初始化一个变量或者形参的方式完全一样. ...
- 关于类中的参数类型和return返回值
基础有些忘了,现在重新巩固一下 先定义一个Person类 class Person(): def __init__(self,name,age,height): self.name=name, sel ...
- try {}里有一个return语句 finally执行顺序
先看例子 package example; class Demo{ public static void main(String args[]) { int x=1; System.out.print ...
- GO学习笔记 - 没有参数的 return 语句返回各个返回变量的当前值,这种用法被称作“裸”返回。
Go 的返回值可以被命名,并且就像在函数体开头声明的变量那样使用. 返回值的名称应当具有一定的意义,可以作为文档使用. 没有参数的 return 语句返回各个返回变量的当前值.这种用法被称作“裸”返回 ...
- Python return语句 函数返回值
return语句是从python 函数返回一个值,在讲到定义函数的时候有讲过,每个函数都要有一个返回值.Python中的return语句有什么作用,今天就来仔细的讲解一下. python 函数返回值 ...
- java try中包含return语句,finally中的return语句返回顺序
//结论: finally 中的代码比 return 和 break 语句后执行 public static void main(String[] args) { int x=new Test.tes ...
- 高程(3):操作符、for、for...in循环、break/continue/return语句、函数等
1.关系操作符 注意点:1)比较操作数是两个字符串,是比较字符串的字符编码值. 如:"a" > "b" 返回 false:"a" & ...
随机推荐
- python使用pika链接rabbitmq Connection reset by peer 解决办法
记录一下, 最近在用机器学习打算做一个Rest API, 数据存入mongo,任务采用消息队列,rabbitmq 由于引擎采用python编写,所以WEB也直接打算用python编写了,比较省事. W ...
- flask系列二之基础知识
一.调试模式(debug模式) 1.设置debug模式 在app.run()中传入关键字参数debug,app.run(debug=Ture),就设置当前项目为debug模式.如下所示: # 从fla ...
- scala中存在的问题
2017-12-27 scala学习中存在的问题: 1.表达式的概念要搞清楚 2.八种基本数据类型要搞清楚 Byte\Short\Int\Long\Char\Boolean\Double\Float都 ...
- 数据库与vs的连接
新建一个MFC基于对话框的项目后,更改属性, 其中需要将include(里面都是MySQL的头文件)lib是库文件,将.dll放入与.exe同级目录下,或放入系统里(c:\windows\system ...
- TensorFlow模型保存和提取方法
一.TensorFlow模型保存和提取方法 1. TensorFlow通过tf.train.Saver类实现神经网络模型的保存和提取.tf.train.Saver对象saver的save方法将Tens ...
- 项目引入Solr时应该考虑的一些问题
1.数据更新频率:每天数据增量有多大,随时更新还是定时更新 2.数据总量:数据要保存多长时间 3.一致性要求:期望多长时间内看到更新的数据,最长允许多长时间延迟 4.数据特点:数据源包括哪些,平均单条 ...
- HTTP请求:POST和GET的差异
1,一般情况下应用目的不同:GET是从服务器上获取数据,POST是向服务器传送数据. 2,将数据提交到服务器的方式不同:GET是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各 ...
- 第十三课 Actionlib(2)
上节课讲到了客户端,这节课讲解一下服务器 1.创建服务器源文件touch fibonacciserver.cpp 2.编写源文件 3.修改CMakeLists.txt 4.编译之catkin_make ...
- hdu 1905 Pseudoprime numbers
#include<stdio.h> #include<math.h> #define ll long long ll mod; bool Judge(int x) { ;i&l ...
- 当鼠标悬停在链接上,或者点击过的链接,颜色会被设置为 #2a6496。同时,会呈现一条下划线。点击过的链接,会呈现一个颜色码为 #333 的细的虚线轮廓。另一条规则是设置轮廓为 5 像素宽,且对于基于 webkit 浏览器有一个 -webkit-focus-ring-color 的浏览器扩展。轮廓偏移设置为 -2 像素
a:hover, a:focus { color: #2a6496; text-decoration: underline; } a:focus { outline: thin dotted #333 ...