前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C语言函数递归_c语言递归举例

C语言函数递归_c语言递归举例

作者头像
Java架构师必看
发布于 2022-07-19 00:35:48
发布于 2022-07-19 00:35:48
13.7K00
代码可运行
举报
文章被收录于专栏:Java架构师必看Java架构师必看
运行总次数:0
代码可运行

大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说C语言函数递归_c语言递归举例,希望能够帮助大家进步!!!

文章目录

函数递归

程序调用自身的编程技巧称为递归 recursion)

函数自己调用自己就是递归

你也可以理解成是一种嵌套结构,但递归分为俩部分,第一是“递”,进入嵌套结构。第二是”归“,最终会一步一步返回。第一次接触递归都会很懵,慢慢理解这个过程就明白了。

什么是递归?

递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接

调用自身的

一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,

递归策略

只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式在于:把大事化小

递归的俩个必要条件

代码引例1

接受一个整型值(无符号),按照顺序打印它的每一位。

例如:

输入:123,输出 1 2 3

参考代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
void print(int n) { 
   
 if(n>9)
 { 
   
 print(n/10);
 }
 printf("%d ", n%10);
}
int main()
{ 
   
 int num = 123;
 print(num);
 return 0; }

只听到从架构师办公室传来架构君的声音:

尚寐无觉!有兔爰爰,雉离于罿。有谁来对上联或下联?

运行结果如下:

我们要怎么理解这个函数递归的实现呢

我们可以采用画图方式理解这个过程

所以我们可以看到,递归必须满足俩个必要条件:

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

2.每次递归调用之后越来越接近这个限制条件。

题中的限制条件就是(n>9),当我们的n通过(n/10)越来越少,直至n=1,无法满足时,递归停止,并开始返回。

这里有一个重要点就是print(n/10),如果没有这个条件,换成print(n)的话,n一直无法减小,一直进行递归。最后会导致栈溢出(Stack Overflow)。

栈溢出(Stack Overflow)

关于栈溢出,我就先简单介绍一下栈

栈:栈是一种计算机系统中的数据结构,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来),是一种特殊的线性表。栈的操作常用的有进栈(PUSH),出栈(POP),还有常用的标识栈顶和栈底。

可以把栈想象成一摞扑克牌一样,一张一张叠加起来。

而栈溢出呢是缓冲区溢出的一种,缓冲区溢出:简单的说,缓冲区溢出就是超长的数据向小缓冲区复制,导致数据超出了小缓冲区,导致缓冲区其他的数据遭到破坏,这就是缓冲区溢出。而栈溢出是缓冲区溢出的一种,也是最常见的。只不过栈溢出发生在栈,堆溢出发生在堆,其实都是一样的。

而在代码引例1中

系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一

直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出

合理使用递归

使用递归的宗旨是把大事化小

所以遇到问题时,我们应该明白是要把问题简单化,而不是习惯用递归,就一直用递归思考问题

我们应该清楚是不是用递归的思想会比较简单,或者换成递归的思想也可以实现,我们可以通过例题明白

代码引例3

求n的阶乘

用循环的方法,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
此代码由Java架构师必看网-架构君整理
int main()
{ 
   
	int n = 0;
	int ret = 1;
	scanf("%d", &n);
	//循环产生1~n的数字
	int i = 0;
	for (i = 1; i <= n; i++)
	{ 
   
		ret = ret * i;
	}
	printf("ret = %d\n", ret);

	return 0;
}

而采用递归的话,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int fac(int n)
{ 
   
	if (n <= 1)
		return 1;
	else
		return n * fac(n - 1);
}

int main()
{ 
   
	int n = 0;
	scanf("%d", &n);
	int ret = fac(n);
	printf("%d\n", ret);
	return 0;
}

很多人刚学递归,都是懂了,但不知道怎么用。

而这道题可以先用公式来理解题目,再来用递归就容易多了

再来对比一下函数的代码,是不是清晰明了呢

代码引例4

求第n个斐波那契数。(不考虑溢出)

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
此代码由Java架构师必看网-架构君整理
int fib(int n) { 
   
 if (n <= 2)         
 return 1;
    else
    return fib(n - 1) + fib(n - 2);
}

这道题同样我们也可以利用公式构造一个函数实现递归

具体思路如下:

解释要合理使用递归

通过以上俩个例题,我们可以发现俩个问题

在使用 fib 这个函数的时候如果我们要计算第50个斐波那契数字的时候特别耗费时间。

使用 factorial 函数求10000的阶乘(不考虑结果的正确性),程序会崩溃。

为什么呢?

我们发现 fib 函数在调用的过程中很多计算其实在一直重复。

如果我们把代码修改一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int count = 0;//全局变量
int fib(int n) { 
   
 if(n == 3)
 count++;
 if (n <= 2)         
 return 1;
    else
    return fib(n - 1) + fib(n - 2);

最后我们输出看看count,是一个很大很大的值。

那我们如何改进呢?

在调试 factorial 函数的时候,如果你的参数比较大,那就会报错: stack overflow(栈溢出)

这样的信息。

那如何解决上述的问题:

  1. 将递归改写成非递归。
  2. 使用static对象替代 nonstatic 局部对象。在递归函数设计中,可以使用 static 对象替代

nonstatic 局部对象(即栈对象),这不仅可以减少每次递归调用和返回时产生和释放 nonstatic 对象的开销,而且 static 对象还可以保存递归调用的中间状态,并且可为各个调用层所访问

比如,下面代码就采用了,非递归的方式来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//求n的阶乘
int factorial(int n) { 
   
        int result = 1;
        while (n > 1)
       { 
   
             result *= n ;
             n -= 1;
       }
        return result; }
//求第n个斐波那契数
int fib(int n) { 
   
     int result;
     int pre_result;
     int next_older_result;
     result = pre_result = 1;
     while (n > 2)
     { 
   
           n -= 1;
           next_older_result = pre_result;
           pre_result = result;
           result = pre_result + next_older_result;
     }
     return result; 
     }

提示:

  1. 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。
  2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。
  3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销

结束语

本人是学c小白,这些是近期学习整理总结,有什么不对欢迎大家指正,我会继续努力,谢谢~!

今天文章到此就结束了,感谢您的阅读,Java架构师必看祝您升职加薪,年年好运。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-182,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C语言的函数
1.我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。
绝活蛋炒饭
2024/12/16
830
C语言的函数
【C语言】函数递归总结
上述就是一个简单的递归程序,只不过上面的递归只是为了演示递归的基本形式,不是为了解决问题,代码最终也会陷入死递归导致栈溢出(Stackoverflow)。
用户11290673
2024/09/25
780
【C语言】函数递归总结
c语言函数递归与迭代详解(含青蛙跳台阶问题详解)
1.递归是什么? 递归是学习C语言函数绕不开的一个话题,那什么是递归呢? 递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。 这里有一个极其简单的递归代码:
fhvyxyci
2024/09/24
880
c语言函数递归与迭代详解(含青蛙跳台阶问题详解)
数据结构-递归
递归是一种应用非常广泛的算法(或者编程技巧)。之后我们要讲的很多数据结构和算法的编码实现都要用到递归,比如 DFS 深度优先搜索、前中后序二叉树遍历等等。所以,搞懂递归非常重要,否则,后面复杂一些的数据结构和算法学起来就会比较吃力。
acc8226
2022/05/17
5220
C 语言函数递归探秘:从基础概念到复杂问题求解的进阶之路
递归可以理解为一种分而治之的思想:将复杂问题拆分为若干规模更小但相似的子问题,直到可以直接解决。
学无止尽5
2024/11/29
1720
C 语言函数递归探秘:从基础概念到复杂问题求解的进阶之路
【C语言基础】:函数递归详解
函数递归指的是在函数内部调用自身的过程。 具体而言,递归函数通过将一个问题分解为更小的、类似的子问题来解决问题。
爱喝兽奶的熊孩子
2024/04/10
1K0
【C语言基础】:函数递归详解
【C语言初阶】C语言函数全解析:编写高效代码的秘密武器
前言: 在探索编程世界的浩瀚星图中,C语言无疑是一颗璀璨夺目的星辰,它不仅奠定了现代计算机编程语言的基础,更是无数软件与系统背后的基石。自其诞生以来,C语言以其高效、灵活、接近硬件的特性,赢得了开发者们的广泛青睐与深厚情感。而在这门语言的浩瀚海洋中,函数(Function)则是航行者手中的罗盘与风帆,指引着代码的方向,驱动着程序的运行
Eternity._
2024/07/20
1520
【C语言初阶】C语言函数全解析:编写高效代码的秘密武器
C语言函数:编程世界的魔法钥匙(2)-学习笔记
注:由于这部分内容比较抽象,而小编我又是一个刚刚进入编程世界的计算机小白,所以我的介绍可能会有点让人啼笑皆非。希望大家多多包涵!万分感谢!待到小编我学有所成,一定会把这块知识点重新介绍一遍,让大家更好地理解和掌握。
LonlyMay
2024/10/21
630
C语言函数:编程世界的魔法钥匙(2)-学习笔记
如何深入掌握C语言递归函数(详解)
递归的精髓在于通过不断地重复逼近一个最终的结果,它更多的是一种思想,用于解决某些问题
用户9645905
2022/11/30
8250
如何深入掌握C语言递归函数(详解)
函数(2)
再举一个简单的例子:假设有一位程序员写了一个能够求两数相加之和的函数,他想卖给别人使用,但又不想让别人看到他的源代码,他应该怎么做呢?
waves浪游
2024/01/23
1690
函数(2)
【C语言系列】函数递归
递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。 下面我们看最简单的递归代码:
四念处茫茫
2025/02/06
1130
【C语言系列】函数递归
c语言从入门到实战——函数递归
函数递归是指一个函数直接或间接地调用自身,以解决问题的一种方法。在C语言中,函数递归可以用来计算阶乘、斐波那契数列等数学问题。 函数递归是一种编程技术,其中函数直接或间接地调用自身来解决问题。它常用于处理可以分解为更小同类问题的复杂问题,如排序、搜索树等。递归的基本思想是将问题分解为更简单的子问题,然后组合子问题的解来得到原问题的解。然而,递归需要小心处理终止条件,否则可能导致无限循环。此外,递归可能消耗大量内存,因为它需要存储每个递归调用的状态。因此,在使用递归时,应仔细考虑其效率和适用性。
鲜于言悠
2024/03/20
2350
c语言从入门到实战——函数递归
C语言-递归和迭代
把一个大型问题层层转换成一个与原问题相似,但规模较小的子问题求解;直到子问题不能再被拆分,递归就结束了.--- 大事化小
ImAileen
2024/01/18
1670
C语言-递归和迭代
初识C语言·递归
递归,这两字的理解应该分开来理解,递推和回归,在C语言中,递归是函数自己调用自己,最后返回一个结果,比如写一段最简单的递归。
_lazy
2024/10/16
1240
初识C语言·递归
c语言基础知识帮助理解(函数递归详解)
"从前有座山,山里有座庙,庙里有个老和尚和一个小和尚。有一天老和尚对小和尚说:“从前有座山.山里有座庙,庙里有个老和尚和一个小和尚,有一天老和尚对小和尚说:“从前有座山.山里有座庙,庙里有个老和尚和一个小和尚......" (虽能体现递归特点,但又不是递归)
是Nero哦
2024/01/18
2110
c语言基础知识帮助理解(函数递归详解)
C语言--函数递归与迭代
当n≤2时,第n个斐波那契数都是1,当n>2时,第n个斐波那契数就可以通过前两个数相加计算
凯子坚持C
2024/09/23
710
抽丝剥茧C语言(中阶)函数
数学中我们常见到函数的概念。 例如:y=f(x) 但是你了解C语言中的函数吗? 维基百科中对函数的定义:子程序 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
有礼貌的灰绅士
2023/03/28
4670
抽丝剥茧C语言(中阶)函数
C语言进阶指南(6)(函数递归详解)(内含汉诺比塔,青蛙跳台阶问题)
在数学中,递归是将一个未知项逐渐拆分为小项来计算出未知项的值。那么根据这种数学思想,递归程序的思路应该是:
代码小豪
2024/06/07
1330
【c语言】一篇文章搞懂函数递归
递归是什么?其实,递归是一种解决问题的方法,体现在c语言中就是函数自己调用自己。让我们举一个最史上最简单的递归代码:
ephemerals__
2024/10/24
1610
【c语言】一篇文章搞懂函数递归
关于我、重生到500年前凭借C语言改变世界科技vlog.8——函数递归
在 vlog.2 的 printf 函数的返回值举例中,我们使用多次递归的方式实现了同一个函数的返回值调用,但这只是一个简易的递归,不算真正意义上的递归,那么什么是递归?
DARLING Zero two
2024/11/19
890
关于我、重生到500年前凭借C语言改变世界科技vlog.8——函数递归
相关推荐
C语言的函数
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文