《C Primer Plus》函数章节:递归函数。结合 Visual Studio 调试理解 C 语言的递归函数,下面是书上一模一样的代码,贴在这里:

#include<stdio.h>

void up_and_down(int);

int main(void)
{
up_and_down(1);
return 0;
} void up_and_down(int n)
{
printf("Level %d: n location %p\n", n, &n);
if (n < 4)
{
up_and_down(n + 1);
}
printf("LEVEL %d: n location %p\n", n, &n);
}

通过指针运算符可以查看到这个变量的内存地址信息。在格式化打印语句里取值就是%p,按照十六进制输出,而%d是按十进制输出。

可以看到变量 n 的地址在前 4 次都发生变化,这是因为传递给函数的变量是属于函数的,它是一个局部变量,因此地址不一样。后四次 n 变量的地址与前面的地址信息呈倒转的现象,是因为递归函数在往回执行导致的结果。

if n < 4,所以最多只能执行四次up_and_down()函数。请注意,这四次执行完成之后,后面还有一个打印语句,它还没有被执行,也就是说,递归函数在哪里,那么后面的代码就被“截断”暂时不执行:

可以发现,行 18 累计了 4 次,然后依次从高到低由往回执行,也就是图1显示的效果。下图是递归函数执行的流程图:

第 1~4 级函数执行自己的时候,n 在逐步自增 1,直到第 4 级递归函数不符合 if 条件,就开始从第 4 级函数依次返回执行。根据图1可知,每一级函数接收的变量 n 都是独立的内存地址。所以,依次返回执行每一级的函数的变量 n 看似就是在自减。

递归有时候难以捉摸,有时候却很方便实用。结束递归是使用递归的难点,因为递归代码中没有终止递归的条件,就会无限递归。可以使用循环的地方通常可以使用递归,有时候用循环解决问题比较好,但有时候用递归更好。递归比较消耗计算机内存,每递归一次,里面的变量就要重新创建一次,图1已经证实了这一点。

探索 C 语言的递归函数的更多相关文章

  1. [转]深度探索C语言函数可变长参数

    转自:http://www.cnblogs.com/chinazhangjie/archive/2012/08/18/2645475.html 一.基础部分 1.1 什么是可变长参数 可变长参数:顾名 ...

  2. 探索Java语言与JVM中的Lambda表达式

    Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法.( ...

  3. 【C语言】递归函数DigitSum(n)

    //写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和, //比如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19 #include <std ...

  4. 深度探索Go语言:包装方法

    问题1:什么是包装方法? 下面咱们来验证下包装方法的存在: 首先,定义一个Point类型,表示一维坐标系内的一个点,并且按照Go语言的风格为其实现了一个Get方法和一个Set方法. package g ...

  5. C语言:递归函数n!

    #include <stdio.h> long recursion(int n); void main(){ int n; long result; printf("input ...

  6. 【C语言探索之旅】 开宗明义及第一课:什么是编程?

    内容简介 1.课程大纲 2.第一部分第一课:什么是编程? 3.第一部分第二课预告:工欲善其事,必先利其器 ​ 课程大纲 不知道为什么,一直对C语言有一种很深厚的“情怀”(类似老罗对锤子手机的那种),说 ...

  7. Go 语言递归函数

    递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recursion() } ...

  8. Go语言【第十三篇】:Go语言递归函数

    Go语言递归函数 递归,就是在运行的过程中调用自己,语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recurs ...

  9. GO语言学习(二十)Go 语言递归函数

    Go 语言递归函数 递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recu ...

  10. PHP内核探索之变量(6)- 后续内核探索系列大纲备忘

    年前因为工作比较饱和,现在又忙着换工作的事情,基本停止了对博文的更新.后续的博文,还是慢慢补上吧. 为了不至于过于发散,先搞个未成形的大纲,如下: PHP内核探索之变量  不平凡的字符串 PHP内核探 ...

随机推荐

  1. 【Day04】Spring Cloud 升华篇:容器化技术docker和kurbernetes

    一.介绍 1.要考虑的问题 微服务数量有很多 中间件的部署-nacos-server sentinel-server 如何部署多个服务和中间件? 2.存在问题---机器上直接解压使用 资源利用率的问题 ...

  2. java中使用apache poi 读取 doc,docx,ppt,pptx,xls,xlsx,txt,csv格式的文件示例代码

    java使用apache poi 读取 doc,docx,ppt,pptx,xls,xlsx,txt,csv格式的文件示例代码 1.maven依赖添加 在 pom 文件中添加如下依赖 <depe ...

  3. gulp报错The following tasks did not complete

    代码如下: //引用gulp模块 const gulp = require('gulp'); //使用gulp.task()建立任务 gulp.task('first', () => { con ...

  4. 多表查询两种方法、可视化软件navicat、python操作mysql、pymysql模块

    目录 多表查询的思路 多表查询的两种方法 小知识点补充数说明 可视化软件Navicat 安装教程 数据库常用操作 多表查询练习题 python 操作MySQL pymysql补充说明 Non-grou ...

  5. TypeError: __str__ returned non-string (type WebStepInfo)

    错误代码: class CaseStep(models.Model): id = models.AutoField(primary_key=True) casetep = models.Foreign ...

  6. 第一章 --------------------WPF基础概述

    1.在使用WPF之前我一直在思考为什么要使用WPF? 主要原因在于我已经受够了MFC和Winform 和QT的界面设计.尤其是MFC的界面设计,使用一个界面库十分的复杂,并且我的绝大多数时间都是用在这 ...

  7. 低代码开发平台YonBuilder移动开发,开发阅读APP教程

    ​ 设计实现效果如下图: 主要包括书架,阅读,收藏功能. 经过分析,我们可以先实现底部导航功能,和书架列表页面. 1. 使用 tabLayout 高级窗口实现底部导航 . 使用tabLayout 有两 ...

  8. day06-Spring管理Bean-IOC-04

    Spring管理Bean-IOC-04 3.基于注解配置bean 3.1基本使用 3.1.1说明 基本说明:基于注解的方式配置bean,主要是项目开发中的组件,比如Controller,Service ...

  9. JavaScript 内存管理及垃圾回收

    一.内存管理 JavaScript 是一种自动垃圾回收语言,这意味着 JavaScript 引擎会自动监测和清理无用的内存. JavaScript 中的内存管理主要由 JavaScript 引擎负责, ...

  10. thinkphp无法访问man.php/index/login

    配置半天.user.ini,权限问题解决了,但是还是访问不了后台登陆界面(链接:域名/man.php/index/login),后来发现是伪静态thinkphp没设置好,设置好后重启nginx就好啦