c语言 递归的执行过程探究

引用《c primer plus》第五版 9.3.1 递归的使用

 /* recur.c -- recursion illustration */
#include <stdio.h>
void up_and_down(int); int main(void)
{
up_and_down();
return ;
} void up_and_down(int n)
{
printf("Level %d: n location %p\n", n, &n); /* 1 */
if (n < )
up_and_down(n+);             /* 递归处 */  
printf("LEVEL %d: n location %p\n", n, &n); /* 2 */ }
过程:  main()调用了up_and_down(1),
然后第一层的up_and_down(此时n为1),
执行到了我注释的那个地方/*递归处*/即第15行
在递归处调用了up_and_down(调用时将n+1(也就是1+1)赋给了第二层的参量n) 由于调用后第一层要等待第二层的返回,所以第一层执行还没有完成,所以还轮不到第一层的/* 2 */ 处的打印,
第二层的up_and_down又执行到了/*递归处*/,又调用了函数,以此类推。
最后执行到了最深层时,n不再满足小于4的条件,所以不再递归。
就执行了/* 2 */ 处的打印,然后函数结束了,就return返回值【此处return void;】并退出当前层的函数
次深层检测到 被自己调用的函数的返回值 后继续执行/* 2 */ 处的打印,结束后再return void; 依次类推。
 

输出结果为:

LEVEL 1: n location 0x0012ff48
LEVEL 2: n location 0x0012ff3c
LEVEL 3: n location 0x0012ff30
LEVEL 4: n location 0x0012ff24
LEVEL 4: n location 0x0012ff24
LEVEL 3: n location 0x0012ff30
LEVEL 2: n location 0x0012ff3c
LEVEL 1: n location 0x0012ff48

总结:由于c语言的顺序结构,所以调用函数后要等待被调用的函数执行完成(即有返回值后)才能执行下一步,而递归恰恰是一层一层地调用自己,所以得等到最深层执行完成后,才返回值告诉次深层函数可以继续执行。次深层执行后才能返回告诉次次深层继续执行。
【在函数没有执行完成前,不return。 导致了每一个函数都得等待被调用函数的返回才能继续,不断调用就得不断等待被调用的函数,因此必须等最深层函数开始返回后才有了一步步的函数的后续执行和返回】

重点:调用时的LEVEL1地址和返回时的LEVEL1(LEVEL数字)是相同的
每一级递归都使用自己的私有变量(子函数中变量的作用域和储存时期部分的知识) 关于利用递归函数赋值的部分,引用《c primer plus》第五版 9.3.3尾递归
 // factor.c -- uses loops and recursion to calculate factorials
#include <stdio.h>
long fact(int n);
long rfact(int n);
int main(void)
{
int num; printf("This program calculates factorials.\n");
printf("Enter a value in the range 0-12 (q to quit):\n");
while (scanf("%d", &num) == )
{
if (num < )
printf("No negative numbers, please.\n");
else if (num > )
printf("Keep input under 13.\n");
else
{
printf("loop: %d factorial = %ld\n",
num, fact(num));
printf("recursion: %d factorial = %ld\n",
num, rfact(num));
}
printf("Enter a value in the range 0-12 (q to quit):\n");
}
printf("Bye.\n"); return ;
} long fact(int n) // loop-based function
{
long ans; for (ans = ; n > ; n--)
ans *= n; return ans;
} long rfact(int n) // recursive version
{
long ans; if (n > )
ans= n * rfact(n-);
else
ans = ; return ans;
}

首先,此处的赋值是    将 函数返回值 赋给一个变量

所以递归赋值这种也是一样的:
一步步等待,直到最深层函数执行完成并返回后
次深层才能利用返回值执行赋值操作,然后再执行完成并返回
次次深层才能利用返回值执行赋值操作......
依次类推 疑问递归函数里 x=3+addall(n);
那么x的值在递归过程中如何变化? =========End

【递归】执行过程探究(c)的更多相关文章

  1. Android UI测量、布局、绘制过程探究

    在上一篇博客<Android中Activity启动过程探究>中,已经从ActivityThread.main()开始,一路摸索到ViewRootImpl.performTraversals ...

  2. 多文件目录下makefile文件递归执行编译所有c文件

    首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...

  3. 【转】多文件目录下makefile文件递归执行编译所有c文件

    首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...

  4. koa执行过程原理分析

    本文原创,转载请注明出处https://i.cnblogs.com/EditPosts.aspx?postid=5710639 我们大家都知道,当koa接到请求经过中间件时,当执行到 yield ne ...

  5. webpack执行过程

    webpack-cli 执行过程 1.webpack.config.js,shell options参数解析 2.new webpack(options) 3.run() 编译的入口方法 4.comp ...

  6. TButton.Repaint的执行过程

    测试,在按钮事件里写上 Button1.Repaint;(包括TWinControl.Invalidate;和procedure TWinControl.Update;两个函数,会被TButton所继 ...

  7. python递归函数的执行过程

    举例: def nove(n,a,b,c): if n == 1: print(a,'------------>',c) else: nove(n-1,a,c,b) nove(1,a,b,c) ...

  8. mysql数据库查询过程探究和优化建议

    查询过程探究 我们先看一下向mysql发送一个查询请求时,mysql做了什么? 如上图所示,查询执行的过程大概可分为6个步骤: 客户端向MySQL服务器发送一条查询请求 服务器首先检查查询缓存,如果命 ...

  9. 【JS】js引擎执行过程

    概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 语法分析: 分别对加载完成的代码块进行语法检验,语法正 ...

随机推荐

  1. 《Spring + MyBatis 企业应用实战》书评

    最近公司的前端用 MpVUE.JS 开发微信小程序遇到一个问题,对后端传来的富文本编辑器的标签无法进行解析.因为公司小,这个问题前端人员直接反映给老板,跟老板说,“ MpVUE.JS 无法解析富文本编 ...

  2. 利用Python爬虫刷店铺微博等访问量最简单有效教程

    一.安装必要插件 测试环境:Windows 10 + Python 3.7.0 (1)安装Selenium pip install selenium (2)安装Requests pip install ...

  3. MySQL for OPS 03:索引和执行计划

    写在前面的话 啥是索引?以一本书为例,如果想要找到某一指定章节的某一小节,书薄还好,如果书厚,可能就会找的头皮发麻.于是便出现了目录,让用户更容易查找到自己所需要的东西.索引就类似一张表的目录.其存在 ...

  4. cuda,cudnn

    20191008 服务器上的cuda总是被人搞坏掉,好烦.记录下: 卸载干净cuda sudo rm -rf /usr/local/cuda sudo apt-get remove cuda sudo ...

  5. RootKit随手记(一)RootKit的驱动隐藏、读取配置、卸载安装

    边学习边更新这专题,随手记录一下用到的思路,给自己看的(所以读者看可能有些懵,不好意思...) RootKit随手记(一)RootKit的驱动隐藏.读取配置.卸载安装 一.驱动隐藏 1. 隐藏原理 一 ...

  6. ASP.NET Core Web 项目文件

    在本节中,我们将探索并了解 asp.net core 项目文件. 我们使用 C#作为编程语言,因此项目文件具有.csproj 扩展名. 如果您使用过以前版本的 ASP.NET,那么您可能对此文件非常熟 ...

  7. pymysql 的简单使用

    一.环境 Windows  7 x64     python 3.7.1    pymysql 0.9.3  mysql5.6.43 二.pymysql的简单使用 1.准备数据库demo_temp c ...

  8. AJAX小示例

    一. 基本内容 定义:AJAX(Asynchronous Javascript And XML)翻译成中文就是"异步的Javascript和XML",即使用Javascript语言 ...

  9. vue-router简易的实现原理

    class VueRouter { constructor(options) { this.$options = options; this.routeMap = {}; // 路由响应式 this. ...

  10. 结对编程-python实现

    目录 软件工程结对项目:Python实现wc程序 结对项目Github地址 项目成员 项目要求 说明 需求 PSP表格 解题思路描述 设计实现 代码组织图 代码分析 代码覆盖率 测试 单元测试 回归测 ...