连续几年的C++程序设计课教学中,学生中总有人要求为他们单独解释函数的返回(return)究竟是什么意思。各种书中都会详讲返回值的问题,而学生们掌握的难点却是在返回至何处执行。本文试图通过对一般函数及递归函数

从程序执行的流程角度,返回即是“被调用函数执行结束后,返回至调用这个函数的位置,接着完成其他任务。”。这句话绕一些,看一些具体的例子。

//例1
#include <iostream>
using namespace std;
int max(int x, int y);
int main()
{
int a,b,c;
a=30;
b=20;
c=max(a,b);
cout<<"大者为: "<<c<<endl;
return 0;
} int max(int x, int y)
{
int z;
if(x>y)
z=x;
else
z=y;
return z;
}

在第
9
行调用
max(a, b)
时,函数会到第
14
行开始定义的
max
函数中执行。执行至
21

return z
时,函数返回至第
9
行(即“返回至调用这个函数的位置”),将返回值赋值给变量
c
(即“接着完成其他任务”,此处是为
c
赋值。)

建议初学者在破解这个难关时,利用IDE中提供的单步执行工具实际“走”一遍看看。具体步骤如图1至图4。

“返回”,也就是C++中的return,词典中的释义是“回到一个地方或状况或从一个地方或状况回来的行动”。用现实生活中的例子也可以解释。例如:

某一天,我要修理一下家里漏水的水龙头。关总阀,拆龙头,修理均顺利完成,却发现后续的安装无法进行,家里储备的密封胶条没有了,于是吩咐老婆,出去买胶条去。老婆下楼后准备骑自行车去,却发现车胎没气了,于是喊过来正在楼下玩的儿子:“帮娘回家取气筒去。”儿子回家一趟,返回给他的娘一支气筒。于是老婆给自行车打了气,去市场一趟,给我返回了密封胶条,我得以把余下的安装、开阀门,清理现场等工作干完。

图5说明了这样一个调用、返回的过程。

函数的递归是函数“自己调用自己”的过程,这让不少还觉得了解了“返回”含义的同学又遇到了障碍。写过一个助学文档《读懂C++递归程序》,演示的就是这样一个调用和返回的过程。

以下面以求阶乘的递归函数为例来说明相关问题。

//例2
#include <iostream>
using namespace std;
long fact(int);
int main( )
{
int n;
long y;
n=5;
y=fact(n);
cout<<n<<"!="<<y<<endl;
return 0;
} long fact(int n)
{
long f;
if (n==1)
f=1;
else
f=fact(n-1)*n;
return f;
}

实际上,递归函数返回的意义仍旧。递归中的每一次调用自身,参数并不一样。在
main
函数中第
9
行执行到
y=fact(n)
时,调用的是
fact(5)
;执行
fact(5)
时,需要调用
fact(4)
,依此一直要调用到
fact(1)
,从而不再递归调用直接得到求解的结果。调用一级一级就是这样下来的,返回则是逆着这个顺序展开,
fact(1)
的返回值
1
,返回给
fact(2)
用于计算
fact(1)*2

fact(2)
的返回值
2
,返回给
fact(3)
用于计算
fact(2)*3
,依此一直返回到
fact(5)
,求出值后递归结束,
fact(5)

return
语句返回到
main
函数中,最终完成了任务。这个过程如图
6
所示。

对于递归函数中返回的理解,建议也利用单步执行的方式进行一次跟踪,从而增加直观的映像。图7至图13展示了这个过程中的几处关键。

再次建议,将调试工具用好,这是学习程序设计过程中必备的技能。

==================== 迂者 贺利坚 CSDN博客专栏=================

|== IT学子成长指导专栏 专栏文章分类目录(不定期更新) ==|

|== C++ 课堂在线专栏 贺利坚课程教学链接(分课程年级) ==|

======== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 =======

 

理解C++中函数的返回的更多相关文章

  1. C++中函数的返回值

    原文 [ 函数的返回值用于初始化在调用函数处创建的临时对象.在求解表达式时,如果需要一个地方储存其运算结果,编译器会创建一个没有命名的对象,这就是 临时对象.temporary object ] -- ...

  2. 如何理解javaSript中函数的参数是按值传递

    本文是我基于红宝书<Javascript高级程序设计>中的第四章,4.1.3传递参数小节P70,进一步理解javaSript中函数的参数,当传递的参数是对象时的传递方式. (结合资料的个人 ...

  3. Oracle中函数/过程返回结果集的几种方式

    原文 Oracle中函数/过程返回结果集的几种方式 Oracle中函数/过程返回结果集的几种方式:    以函数return为例,存储过程只需改为out参数即可,在oracle 10g测试通过.    ...

  4. Oracle中函数/过程返回多个值(结果集)

    Oracle中函数/过程返回结果集的几种方式: 以函数return为例,存储过程只需改为out参数即可,在oracle 10g测试通过. (1) 返回游标: return的类型为:SYS_REFCUR ...

  5. 深入理解python中函数传递参数是值传递还是引用传递

    深入理解python中函数传递参数是值传递还是引用传递 目前网络上大部分博客的结论都是这样的: Python不允许程序员选择采用传值还是传 引用.Python参数传递采用的肯定是"传对象引用 ...

  6. C语言中函数的返回值

    规则 除局部变量的内存地址不能作为函数的返回值外,其他类型的局部变量都能作为函数的返回值. 我总结出下面这些规则: int.char等数据类型的局部变量可以作为函数返回值. 在函数中声明的指针可以作为 ...

  7. 理解Java中的协变返回类型

    在面向对象程序设计中,协变返回类型指的是子类中的成员函数的返回值类型不必严格等同于父类中被重写的成员函数的返回值类型,而可以是更 "狭窄" 的类型. Java 5.0添加了对协变返 ...

  8. 理解JavaScript中函数方法

    1.函数声明和函数表达式 通过字面量创建函数的方式有两种函数声明和函数表达式: 函数声明: function sum(x, y) { var result = x + y; return result ...

  9. python中函数的返回值

    函数返回值(一) <1>“返回值”介绍 现实生活中的场景: 我给儿子10块钱,让他给我买包烟.这个例子中,10块钱是我给儿子的,就相当于调用函数时传递到参数,让儿子买烟这个事情最终的目标是 ...

随机推荐

  1. spring framework 各版本源码下载地址

    现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-projects/spring-framework/tags ...

  2. Oracle客户端PL_SQL的安装

    Oracle数据库的操作大多还是在客户端完成的,因此在众多的客户端软件中我选择了PL_SQL,一下谈谈PL_SQL的基本安装和操作,以及在操作中碰到的一些问题: 1. 首先下载PL_SQL客户端软件, ...

  3. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  4. C# List<> 删除

    List<string> l = new List<string>() { "A1", "A2", "A3", &q ...

  5. hdu 4814 Golden Radio Base

    详解见:http://blog.csdn.net/tri_integral/article/details/18666797 #include<cstdio> #include<cs ...

  6. iOS 并发:NSOperation 与调度队列入门(1)

    一直以来,并发都被视为 iOS 开发中的「洪水猛兽」.许多开发者都将其视为危险地带,唯恐避之而不及.更有谣传认为,多线程代码应该尽力避免.笔者同意,如果你对并发的了解不够深入,就容易造成危险.但是,危 ...

  7. 为什么Nagios会那么吵?你又能做些什么呢?(1)

    如果你受困于 Nagios 的告警洪潮中不能自拔,那么这两篇连载博客就是为你而生的.让我们来详细的阐述下这个问题! 运维人员都有着独立的监控工具,因此会经常受到 Nagios 告警吵闹的影响.很多运维 ...

  8. 在8086中,[ idata],[bx]表示内存单元时。可能是一个字节,也可能是一个字。

    可能表示一个字节,也可能表示一个字.主要由指令中另一个计算对象决定.如al表示一个字节.ax就表示一个字. 这个区别主要体现在循环中,偏移地址的循环变量是加1还是加2,al是偏移地址加1,ax是偏移地 ...

  9. Java异常处理之try-catch-finally

    /** * @author Administrator * 功能:异常 */ package com.test; import java.io.*; import java.net.*; public ...

  10. velocity-1.7学习笔记

    Velocity是由Apache软件组织提供的一项开放源码项目,它是一个基于Java的模板引擎.通过Velocity模板语言(Velocity Template Language,VTL)定义模板(T ...