【递归】执行过程探究(c)
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 0x0012ff48LEVEL 2: n location 0x0012ff3cLEVEL 3: n location 0x0012ff30LEVEL 4: n location 0x0012ff24LEVEL 4: n location 0x0012ff24LEVEL 3: n location 0x0012ff30LEVEL 2: n location 0x0012ff3cLEVEL 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)的更多相关文章
- Android UI测量、布局、绘制过程探究
在上一篇博客<Android中Activity启动过程探究>中,已经从ActivityThread.main()开始,一路摸索到ViewRootImpl.performTraversals ...
- 多文件目录下makefile文件递归执行编译所有c文件
首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...
- 【转】多文件目录下makefile文件递归执行编译所有c文件
首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...
- koa执行过程原理分析
本文原创,转载请注明出处https://i.cnblogs.com/EditPosts.aspx?postid=5710639 我们大家都知道,当koa接到请求经过中间件时,当执行到 yield ne ...
- webpack执行过程
webpack-cli 执行过程 1.webpack.config.js,shell options参数解析 2.new webpack(options) 3.run() 编译的入口方法 4.comp ...
- TButton.Repaint的执行过程
测试,在按钮事件里写上 Button1.Repaint;(包括TWinControl.Invalidate;和procedure TWinControl.Update;两个函数,会被TButton所继 ...
- 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) ...
- mysql数据库查询过程探究和优化建议
查询过程探究 我们先看一下向mysql发送一个查询请求时,mysql做了什么? 如上图所示,查询执行的过程大概可分为6个步骤: 客户端向MySQL服务器发送一条查询请求 服务器首先检查查询缓存,如果命 ...
- 【JS】js引擎执行过程
概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 语法分析: 分别对加载完成的代码块进行语法检验,语法正 ...
随机推荐
- 一个简单的 WPF 程序,用于显示实时时间
直接贴代码了: TimeShowerWindow.xaml <Window x:Class="HelloWorld.TimeShowerWindow" xmlns=" ...
- 关于5G手机使用4G套餐扫盲
有些人说换5G手机用4G套餐不用5G套餐可以享受最高 300 mbps 的签约速率.在此我来给你们科普下. 5G套餐分为 500 mbps 和 1000 mbps 两种.且都享受优先接入,顺序是 10 ...
- 排障利器之远程调试与监控 --jmx & remote debug
监控和调试功能是应用必备的属性之一,其手段也是多种多样. 一般地,我们可以通过:线上日志, zabbix, grafana, cat 等待系统做一问题留底,有问题及时报警,从而达到监控效果. 而对于应 ...
- MySQL5.6升级到5.7详细教程
前言:最近看了下系统的数据库是5.6的,想着升级到5.7,特此记录 一.官网下载MySQL5.7rpm包(4个) 进入MySQL community download页面,默认是MySQL最新版8.0 ...
- 【C#夯实】我与接口二三事:IEnumerable、IQueryable 与 LINQ
序 学生时期,有过小组作业,当时分工一人做那么两三个页面,然而在前端差不多的时候,我和另一个同学发生了争执.当时用的是简单的三层架构(DLL.BLL.UI),我个人觉得各写各的吧,到时候合并,而他觉得 ...
- qt 界面去掉系统边框2.0版
之前的一版存在bug.如果将鼠标放移动到界面内某个可点击的widget上(如:QPushButton)上,按住鼠标左键不放,界面可能会出现界面非预期移动的问题. 那是因为当鼠标移动到可点击的widge ...
- php CI如何实现全站静态生成html,动态创建目录
php CI如何实现全站静态生成html,动态创建目录CodeIgniter框架生成HTML的方法 public function out_html($code) { $data['articles' ...
- Angular i18n(国际化方案)
一.引言 i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称.在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无 ...
- PHP json中文
json_encode 和 json_decode 只支持utf-8编码的字符串,GBK的字符串要用json就得转换成utf-8字符串 看效果 <?php header("Conten ...
- bootstrap基础样式学习(一)
1.按钮btn .btn 按钮基础的样式 .btn-default 白底黑子的按钮 .btn-danger/warning/success/info/primary .btn-lg/sm/xs 按钮大 ...