哪位好心人有帝王盒子邀请码会员啊?

return语句终止当前正在执行的函数并将控制权返回到调用该函数的地方。return语句有两种形式:
无返回值函数
没有返回值的return语句只能用在返回类型是void的函数中。返回void的函数不要求非得有return语句,因为在这类函数的最后一句后面会隐含地执行return。
通常情况下,void函数如果想在它的中间位置提前退出,可以使用return语句。return的这种用法有点类似于我们用break语句退出循环。
一个返回类型是void的函数也能使用return语句的第二种形式,不过此时return语句的expression必须是另一个返回void的函数。强行令void函数返回其他类型的表达式将产生编译错误。
有返回值的函数
return语句的第二种形式提供了函数的结果。只要函数的返回类型不是void,则该函数内的每天return语句必须返回一个值。return语句返回值的类型必须与函数的返回类型相同,或者能隐式地转换成函数的返回类型。
尽管C++无法确保结果的正确性,但是可以保证每个return语句的结果类型正确。也许无法顾及所有情况,但是编译器仍然尽量确保具有返回值的函数只能通过一条有效的return语句退出。
在含有return语句的循环后面应该也有一条return语句,如果没有的话该程序就是错误的。
值是如何被返回的
返回一个值得方式和初始化一个变量或形参的方式完全一样:返回的值用于初始化调用点的一个临时量,该临时量就是函数调用的结果。
必须注意当函数返回局部变时的初始化规则。例如我们写一个函数,给定计数值、单词和结束符之后,判断计数值是否大于1:如果是,返回单词的复数形式;如果不是,返回单词原型:
//如果ctr的值大于1,返回word的复数形式
string make_plural(size_t ctr,const string &word,const string &ending)
  return (ctr&)?word+ending:
该函数的返回类型是string,意味着返回值将被拷贝到调用点。因此,该函数将返回word的副本或者一个未命名的临时string对象,该对象的内容是word和ending的和。
同其他引用类型一样,如果函数返回引用,则该引用仅是它所引对象的一个别名。举个例子来说明,假定某函数跳出两个string形参中较短的那个并返回其引用:
//挑出两个string对象中较短的那个,返回其引用
const string &shorterString(const string &s1,const string &s2)
  return s1.size()&=s2.size()?s1:s2;
其中形参和返回类型都是const string的引用,不管是调用函数还是返回结果都不会真正拷贝string对象。
不要返回局部对象的引用或指针
函数完成后,它所占的存储空间也随之被释放掉。因此,函数终止意味着局部变量的引用将指向不再有效的内存区域:
//严重错误:这个函数试图返回局部对象的引用
const string &manip()
  //以某种方式改变一下ret
  if(!ret.empty())
     &//错误:返回局部对象的引用
    return "Empty"; &//错误:&Empty&是一个局部临时量
上面的两条return语句都将返回未定义的值,也就是说试图使用manip函数的返回值将引发未定义的行为。对于第一天return语句来说,显然它返回的是局部对象的引用。在第二条return语句中,字符串字面值转换成一个局部临时string对象,对于manip来说,该对象和ret一样都是局部的,当函数结束时临时对象占用的空间也就随之是否释放了,所以两条return语句都指向了不再可用的内存空间。
如前所述,返回局部对象的引用是错误的;同样,返回局部对象的指针也是错误的。一旦函数完成,局部对象被释放,指针将指向一个不存在的对象。
返回类类型的函数和调用运算符
和其他运算符一样,调用运算符也有优先级和结合律。调用运算符的优先级与点运算符和箭头运算符相同,并且也符合左结合律。因此,如果函数返回指针、引用或类的对象,我们就能使用调用的结果访问结果对象的成员。
例如,我们可以通过如下形式得到较短string对象的长度:
//调用string对象的size成员,该string对象是由shorterString函数返回的
auto sz=shorterString(s1,s2).size();
因为上面提到的运算符都满足左结合律,所以shorterString的结果是点运算符的左侧运算对象,点运算符可以得到该string对象的size成员,size又是第二个调用运算符的左侧运算对象。
引用返回左值
函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其他返回类型得到右值。可以像使用其他左值那样来使用返回引用的函数调用,特别是,我们能为返回类型是非常量引用的函数的结果赋值:
char &get_val(string &str,string::size_type ix)
  return str[ix];
int main()
  string s("a value");
  cout&&s&&
  get_val(s,0)='A';
  cout&&s&&
  return 0;
把函数调用放在赋值语句的左侧可能看起来有点奇怪,但其实这没什么特别的。返回值是引用,因此调用是个左值,和其他左值一样它也能出现在赋值运算符的左侧。
如果返回类型是常量引用,我们不能给调用的结果赋值,这一点和我们熟悉的情况是一样的:
shorterString("hi","bye")="X"; & //错误:返回值是个常量
列表初始化返回值
C++11新标准规定,函数可以返回花括号包围的值得列表。类似于其他返回结果,此处的列表也用来对表示函数返回的临时量进行初始化。如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定。
返回数组指针
因为数组不能被拷贝,所以函数不能返回数组。不过,函数可以返回数组的指针或引用。虽然从语法上来说,要想定义一个返回数组的指针或引用的函数比较繁琐,但是有一些方法可以简化这一任务,其中最直接的方法是使用类型别名:
typedef int arrT[10]; & //arrT是一个类型别名,它表示的类型是含有10个整数的数组
using arrT=int [10]; & //arrT的等价声明
arrT * func(int i); & &//func返回一个指向含有10个整数的数组的指针
其中arrT是含有10个整数的数组的别名。因为我们无法返回数组,所以将返回类型定义成数组的指针。因此,func函数接受一个int实参,返回一个指向包含10个整数的数组的指针。
声明一个返回数组指针的函数
要想在声明func时不使用类型别名,我们必须牢记被定义的名字后面数组的维度:
int arr[10]; & //arr是一个含有10个整数的数组
int *p1[10]; &//p1是一个含有10个指针的数组
int (*p2)[10]=& & //p2是一个指针,它指向含有10个整数的数组
和这些声明一样,如果我们想定义一个返回数组指针的函数,则数组的维度必须跟在函数名字之后。然而,函数的形参列表也跟在函数名字后面且形参列表应该先于数组的维度。因此,返回数组指针的函数形式如下所示:
Type (*function (parameter_list)) [dimension]
类似于其他数组的声明,Type表示元素的类型,dimension表示数组的大小。(*function(parameter_list))两端的括号必须存在,就像我们定义p2是两端必须有括号一样。如果没有这对括号,函数的返回类型将是指针的数组。
举个具体点的例子,下面这个func函数的声明没有使用类型别名:
int (*func(int i))[10];
可以按照以下的顺序来逐层理解该声明的含义:
func(int i)表示调用func函数时需要一个int类型的实参;
(*func(int i))意味着我们可以对函数调用的结果执行解引用操作;
(*func(int i))[10]表示解引用func的调用将得到一个大小是10 的数组
int (*func(int i))[10]表示数组中的元素是int 类型
使用尾置返回类型
在C++11新标准中还有一种可以简化上述func声明的方法,就是使用尾置返回类型。然后函数的定义都能使用尾置返回,但是这种形式对于返回类型比较复杂的函数最有效,比如返回类型是数组的指针或者数组的引用。尾置返回类型跟在形参列表后面并以一个-&符号开头。为了表示函数真正的返回类型跟在形参列表之后,我们在本应该出现返回类型的地方放置一个auto:
//func接受一个int类型的实参,返回一个指针,该指针指向含有10个整数的数组
auto func(int i) -&int (*)[10];
因为我们把函数的返回类型放在了形参列表之后,所以可以清楚地看到func函数返回的是一个指针,并且该指针指向了含有10个整数的数组。
使用decltype
还有一种情况,如果我们知道函数返回的指针将指向哪个数组,就可以使用decltype关键字声明返回类型。例如,下面的函数返回一个指针,该指针根据参数i的不同指向两个已知数组中的某一个:
int odd[]={1,3,5,7,9};
int even[]={0,2,4,6,8};
//返回一个指针,该指针指向含有5个整数的数组
decltype(odd) *arrPtr(int i)
  return (i%2)?&odd:& &//返回一个指向数组的指针
arrPtr使用关键字decltype表示它的返回类型是个指针,并且该指针所指的对象与odd的类型一致。因为odd是数组,所以arrPtr返回一个指向含有5个整数的数组的指针。有一个地方需要注意:decltype并不负责把数组类型转换成对应的指针,所以decltype的结果是个数组,要想表示arrPtr返回指针还必须在函数声明时加一个*符号。
阅读(...) 评论()> 问题详情
关于函数的返回值,正确的是()。A.由return语句返回时,只带回一值,其类型在函数定义时确定B.其类型
悬赏:0&答案豆
提问人:匿名网友
发布时间:
关于函数的返回值,正确的是()。A.由return语句返回时,只带回一值,其类型在函数定义时确定B.其类型由调用表达式决定C.函数可以没有返回值,这时在函数定义中,函数的类型说明就没必要了D.函数调用就要有返回值,否则调用就没有意义了请帮忙给出正确答案和分析,谢谢!
为您推荐的考试题库
您可能感兴趣的试题
1下面程序执行后的结果是(&&)。&&#include<iostream>&&using namespace std;&&void func1(int i);&&void func2(int i);&&char st[]="hello, friend!";&&void func1(int i)&&{&&cout<<st[i];&&&&if(i<3){i+=2;func2(i);}&&}&&void func2(int i)&&{&&cout<<st[i];&&&&if(i<3){i+=2;func1(i);}&&}&&void main()&&{&int i=0;func1(i);cout<<endl;}A.elloB.helC.hloD.him2下列关于形参的说法,正确的是(&&)。A.函数的形参是必须的B.函数的形参可以是表达式C.函数在定义时,形参是不占用存储空间的,只是在被调用时才会占,调用完毕也就被释放了D.形参的名称、类型、数量、顺序必须与实参都相同,否则实参不会把信息正确地传递给形参3下列说法正确的是(&&)。A.定义int a[4]={1,3};,则a[0]=1,a[1]=3,a[3]的值不确定B.定义static int a[4];,则元素值不确定C.x=5;表示给常量x赋初值D.定义int a[4];,则其元素的值是不确定的4对于char ch1[20],ch2[20];strcmp(ch1,ch2);,说法正确的是(&&)。A.若ch1==ch2,则 strcmp(ch1,ch2)返回1B.若ch1==ch2,则 strcmp(ch1,ch2)返回0C.若ch1>ch2,则 strcmp(ch1,ch2)返回1D.若chi<ch2,则 strcmp(ch1,ch2)返回1
我有更好的答案
请先输入下方的验证码查看最佳答案
图形验证:
验证码提交中……
找答案会员
享三项特权
找答案会员
享三项特权
找答案会员
享三项特权
选择支付方式:
支付宝付款
郑重提醒:支付后,系统自动为您完成注册
请使用微信扫码支付(元)
支付后,系统自动为您完成注册
遇到问题请联系在线客服QQ:
请您不要关闭此页面,支付完成后点击支付完成按钮
遇到问题请联系在线客服QQ:
恭喜您!升级VIP会员成功
常用邮箱:
用于找回密码
确认密码:27098人阅读
C语言知识(37)
  笔者从事C语言教学多年,在教学中学生们常常会问到如何编写具有多个返回值的C语言函数。编写有多个返回值的函数是所有C语言教材里均没有提到的知识点,但在实际教学与应用的过程中我们都有可能会遇到这样的问题。有学生也尝试了不少方法:如把多个需要返回的值作相应的处理后变成一个可以用return语句返回的数据,再在主调函数中拆开返回的数据使之变成几个值;或者把需要返回多个值的一个函数分开几个函数去实现多个值的返回。这些方法虽然最终都能实现返回要求的多个值,但从程序算法的合理性与最优化方面去考虑,显然不理想。我们知道C语言函数的返回值是通过函数中的return语句来实现的,可是每调用一次函数,return语句只能返回一个值。那么当我们希望从一个函数中返回多个值时,用什么方法去实现比较合理呢?在教学过程中,我建议学生跳出对return语句的定势思维,一步步引导学生通过几种间接方式实现多个返回值的C语言函数。以下是笔者在教学过程中引导学生采用的三种不同方法编写多个返回值的C语言函数。
  2方法1:利用全局变量
  分析:全局变量作为C语言的一个知识点,虽然我们都了解它的特点,但在实际教学过程中应用得并不是很多。由于全局变量的作用域是从定义变量开始直到程序结束,而对于编写有多个返回值的C语言函数,我们可以考虑把要返回的多个值定义成全局变量。当函数被调用时,全局变量被更改,我们再把更改后的全局变量值应用于主调函数中。函数被调用后被更改后的全局变量值即为函数的数个返回值。下面以一个实例演示该方法的应用。
  实例1:编写函数求3个数中的最大值与最小值。
  方法:把最大值、最小值分别定义成2个全局变量max、min,在用户自定义函数中把求出来的最大值与最小值分别赋给全局变量max、min。函数调用完毕后全局变量的max、min值即保存了函数要求返回的值。程序参考代码如下:
  #include &stdio.h&
  #include &conio.h&
  int max,/*定义两个全局变量用于保存函数返回值*/
  void max_min(int a,int b,int c) /*定义求最大最小值的函数*/
  {max=min=a; /*初始化最大最小值*/
   if(max   if(max   if(min&b)min=b;
  if(min&c)min=c;
  main()
  {int x,y,z;
  printf(& 请输入3个整数:\n&);
  scanf(&%d,%d,%d&,&x,&y,&z);
  max_min(x,y,z) ;/*调用求最大值与最小值的函数*/
  printf(&三个数中的最大值为:%d;最小值为:%d&,max,min);/*输出最大值与最小值*/
  getch();
  调试结果如下:
  请输入3个整数:
  5,-6,2
  三个数中的最大值为:5;最小值为:-6
  注意:该方法虽然可以实现有多个返回值的函数,但由于全局变量不能保证值的正确性(因为其作用域是全局,所以程序范围内都可以修改它的值,如果出现错误将非常难以发现),并且全局变量增加了程序间模块的耦合,所以该方法要慎用。
  3方法2:传递数组指针
  分析:在教学过程中,我们知道C语言函数参数的传递方式有值传递与地址传递。当进行值传递时,主调函数把实参的值复制给形参,形参获得从主调函数传递过来的值运行函数。在值传递过程中被调函数参数值的更改不能导致实参值的更改。而如果是地址传递,由于传递过程中从实参传递过来的是地址,所以被调函数中形参值的更改会直接导致实参值的更改。因此,我们可以考虑把多个返回值作为数组元素定义成一个数组的形式,并使该数组的地址作为函数的形式参数,以传址方式传递数组参数。函数被调用后,形参数组元素改变导致实参改变,我们再从改变后的实参数组元素中获得函数的多个返回值。以下实例演示该方法的应用。
  实例2:编写函数求一维整形数组的最大值与最小值,并把最大值与最小值返回给主调函数。
  方法:以指针方式传递该一维数组的地址,然后把数组的最大值与数组的第一个元素交换,把数组的最小值与最后一个元素交换。函数被调用完毕后,实参数组中的第一元素为数组的最大值,实参数组中最后一个元素为数组的最小值,从而实现返回数组的最大值与最小值的功能。程序参考代码如下:
  #include &stdio.h&
  #include &conio.h&
  void max_min(int *ptr,int n) /*定义求数组最大值最小值的函数,传递数组指针*/
  {int i,j,k;/*j保存最大值所在位置,k保存最小值所在位置*/
  int */*用于交换位置*/
  *temp=*
  for(i=0;i  {
  if(*ptr&*(ptr+i))/*最大值与第一个元素进行交换*/
  *temp=*
  *ptr=*(ptr+k);
  *(ptr+k)=*
  if(*(ptr+n-1)&*(ptr+i))/*最小值与最后一个元素进行交换*/
  *temp =*(ptr+n-1);
  *(ptr+n-1)=*(ptr+j);
  *(ptr+j)= *}
  /*调用最大最小值函数*/
  main()
  int A[6],i;
  for(i=0;i&6;i++)
   scanf(&%d&,&A[i]);
  max_min(A,6);
  printf(&max=%d, min=%d\n \n&,A[0],A[5]);
  getch();
  调试结果如下:
  请输入6个整形数,以空格隔开:
  5 8 9 32 -6 4
  max=32,min=-6
注意:该方法适用于多个返回值的数据类型一致的情况。当返回值数据类型不一致时,不适用该方法。
  4方法3:传递结构体指针
  分析:结构体作为教学中的一个难点,教材对它介绍的内容并不多,应用的实例更是少之又少,所以学生对于结构体普遍掌握情况不理想。其实,编写返回多个值的C语言函数,也可以考虑采用结构体的方式去实现。通过方法2,我们知道如果返回的数个数值的数据类型不一致,可以通过定义全局变量实现有多个返回值的C语言函数,也可以考虑把要求返回的数个值定义成一个结构体,然后同样以传递结构体指针方式把结构体的指针传递给形参结构体指针,那么函数中对形参结构体的修改即是对实参结构体的修改,函数被调用后获取的实参结构体成员即为函数的多个返回值,下面以实例演示该方法的应用。
  实例3:编写一个用户自定义函数,允许用户录入学生的基本信息(包括学号、姓名、所属班级、总评成绩),并返回这些基本信息给主调函数。
  方法:把学生基本信息定义成一个结构体,在用户自定义函数中传递该结构体的指针,则自定义函数中对结构体成员的录入操作即是对实参结构体成员的录入操作,从而实现多个返回值。参考代码如下:
  #include &stdio.h&
  #include &conio.h&
  struct inf{/*定义学生结构体,分别包含成员学号、姓名、班别、总评成绩*/
   char xh[12];
   char name[20];
   char class[15];
  main(void)
  struct inf a1; /*定义学生结构体类型变量*/
  void xxxx(struct inf *ptr);
  printf(&请输入学号,姓名,班别,总评成绩,以空格隔开:\n&) ;
  xxxx(&a1);/*调用函数,以学生结构体类型变量地址作为实参*/
  printf(&学号:%s,姓名: %s,班别:%s,总评成绩:%d&,a1.xh, a1.name,a1.class,a1.chj);
  getch();
  void xxxx(struct inf *ptr)/*该函数实现对结构体成员数据的录入操作*/
   char xh1[12],name1[20],class1[15];
   int chj1;
  scanf(&%s%s%s%d&,xh1,name1,class1,&chj1);
   strcpy(ptr-&xh,xh1);
  strcpy(ptr-&name,name1);
  strcpy(ptr-&class,class1);
  ptr-&chj=chj1;
  调试结果如下:
  请输入学号,姓名,班别,总评成绩,以空格隔开:
  200102LiLi200185
  学号:200102,姓名: LiLi,班别:2001,总评成绩:85
  注意:当函数要求返回的多个值是相互联系的或者返回的多个值数据类型不一致时可以采用该方法。
  5结束语
  对于以上这三种方法,如果想要返回的数个值数据类型一致,可以考虑采用方法2;而对于不同数据类型的返回值,如果各个数值之间是相互联系的,则方法3较为合适;方法1虽然在很多情况下都可以实现多个返回值的C语言函数,但毕竟全局变量应用过程中有很多危险,要慎重使用。
  通过对以上几种方法的分析讲解,在教学过程中,学生再遇到这样的问题时,就能根据返回值的情况选择合适的途径去实现多个返回值的C语言函数。另外,如果再遇到类似的无法用教材知识点去直接解决的问题时,他们基本都能举一反三地尝试采用间接方式去解决。
  参考文献
  [1] 谭浩强. C程序设计(第二版)[M]. 北京:清华大学出版社,1999.
  [2] 薛万鹏译. C程序设计教程[M]. 北京:机械工业出版社,2000.
  [3] 邓劲生译. Visual C++程序员实用大全[M]. 北京:中国水利水电出版社,2005.
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:393321次
积分:3986
积分:3986
排名:第7306名
原创:15篇
转载:135篇
评论:47条
(8)(2)(5)(9)(4)(20)(15)(32)(9)(2)(7)(5)(10)(22)

我要回帖

更多关于 帝王盒子 的文章

 

随机推荐