理解C++中函数的返回

简介:   连续几年的C++程序设计课教学中,学生中总有人要求为他们单独解释函数的返回(return)究竟是什么意思。各种书中都会详讲返回值的问题,而学生们掌握的难点却是在返回至何处执行。本文试图通过对一般函数及递归函数  从程序执行的流程角度,返回即是“被调用函数执行结束后,返回至调用这个函数的位置,接着完成其他任务。”。这句话绕一些,看一些具体的例子。//例1#include <i

  连续几年的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菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 =======


目录
相关文章
|
21天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
44 6
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
21 0
C++ 多线程之线程管理函数
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
135 1
|
1月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
26 1
|
1月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
38 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
2月前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
22 3
|
3月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
|
3月前
|
C++
c++常见函数及技巧
C++编程中的一些常见函数和技巧,包括生成随机数的方法、制表技巧、获取数字的个位、十位、百位数的方法、字符串命名技巧、避免代码修改错误的技巧、暂停和等待用户信号的技巧、清屏命令、以及避免编译错误和逻辑错误的建议。
32 6