首页 [DOC]-C语言函数递归

[DOC]-C语言函数递归

举报
开通vip

[DOC]-C语言函数递归[DOC]-C语言函数递归 C语言函数递归 C语言函数递归 一、一个简单但易出错的递归例子 几乎每一本C 语言基础的书都讲到了函数递归的问题,但是初学者仍然 容易在这个地方犯错误。先看看下面的例子: void fun(int i) { if (i>0) { fun(i/2); } printf("%d\n",i); } intmain() { fun(10); return 0; } 问:输出结果是什么, 这是我上课时,一个学生问我的问题。他不明白为什么输出的结果会是这 样: ...

[DOC]-C语言函数递归
[DOC]-C语言函数递归 C语言函数递归 C语言函数递归 一、一个简单但易出错的递归例子 几乎每一本C 语言基础的书都讲到了函数递归的问题,但是初学者仍然 容易在这个地方犯错误。先看看下面的例子: void fun(int i) { if (i>0) { fun(i/2); } printf("%d\n",i); } intmain() { fun(10); return 0; } 问:输出结果是什么, 这是我上课时,一个学生问我的问题。他不明白为什么输出的结果会是这 样: 0 1 2 5 10 他认为应该输出0。因为当i 小于或等于0 时递归调用结束,然后执行printf 函数打印i 的值。 这就是典型的没明白什么是递归。其实很简单,printf("%d\n",i);语句是fun 函数的一部分,肯定执行一次fun 函数,就要打印一行。怎么可能只打印一次呢,关键就是不明白怎么展开递归函数。展开过程如下: void fun(int i) { if (i>0) { //fun(i/2); if(i/2>0) { if(i/4>0) { „ } printf("%d\n",i/4); } printf("%d\n",i/2); } printf("%d\n",i); } 这样一展开,是不是清晰多了,其实递归本身并没有什么难处,关键是其展开过程别弄错了。 二、不使用任何变量编写strlen 函数 看到这里,也许有人会说,strlen 函数这么简单,有什么好讨论的。是的,我相信你能熟练应用这个函数,也相信你能轻易的写出这个函数。但是如果我把要求提高一些呢: 不允许调用库函数,也不允许使用任何全局或局部变量编写intmy_strlen (char *strDest);似乎问题就没有那么简单了吧,这个问题曾经在网络上讨论的比较热烈,我几乎是全程“观战”,差点也忍不住手痒了。不过因为我的解决办法在我看到帖子时已经有人提出了,所以作罢。 解决这个问题的办法由好几种,比如嵌套有编语言。因为嵌套汇编一般只在嵌入式底层开发中用到,所以本书就不打算讨论C 语言嵌套汇编的知识了。有兴趣的读者,可以查找相关资料。 也许有的读者想到了用递归函数来解决这个问题。是的,你应该想得到,因为我把这个问题放在讲解函数递归的时候讨论。既然已经有了思路,这个问题就很简单了。代码如下: intmy_strlen( const char* strDest ) { assert(NULL != strDest); if ('\0' == *strDest) { return 0; } else { return (1 + my_strlen(++strDest)); } } 第一步:用assert 宏做入口校验。 第二步:确定参数传递过来的地址上的内存存储的是否为'\0'。如果是, 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 明这是一个空字符串,或者是字符串的结束标志。 第三步:如果参数传递过来的地址上的内存不为'\0',则说明这个地址上的内存上存储的是一个字符。既然这个地址上存储了一个字符,那就计数为1,然后将地址加1 个char类型元素的大小,然后再调用函数本身。如此循环,当地址加到字符串的结束标志符'\0'时,递归停止。 当然,同样是利用递归,还有人写出了更加简洁的代码: intmy_strlen( const char* strDest ) { return *strDest?1+strlen(strDest+1):0; } 这里很巧妙的利用了问号表达式,但是没有做参数入口校验,同时用*strDest 来代替('\0'== *strDest)也不是很好。所以,这种写法虽然很简洁,但不符合我们前面所讲的编码规范。可以改写一下: intmy_strlen( const char* strDest ) { assert(NULL != strDest); return ('\0' != *strDest)?(1+my_strlen(strDest+1)):0; } 上面的问题利用函数递归的特性就轻易的搞定了,也就是说每调用一遍my_strlen 函数,其实只判断了一个字节上的内容。但是,如果传入的字符串很长的话,就需要连续多次函数调用,而函数调用的开销比循环来说要大得多,所以,递归的效率很低,递归的深度太大甚至可能出现错误(比如栈溢出)。所以,平时写代码,不到万不得已,尽量不要用递归。即便是要用递归,也要注意递归的层次不要太深,防止出现栈溢出的错误;同时递归的停止条件一定要正确,否则,递归可能没完没了。
本文档为【[DOC]-C语言函数递归】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_314871
暂无简介~
格式:doc
大小:15KB
软件:Word
页数:5
分类:初中语文
上传时间:2017-10-08
浏览量:26