C语言函数的递归调用详情

目录
  • 一、什么是递归
  • 二、递归与迭代

一、什么是递归

程序调用自身的编程技巧称为递归( recursion) 。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的主要思考方式在于:把大事化小

递归的两个必要条件:

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
  • 每次递归调用之后越来越接近这个限制条件。
int main()
{
	printf("hehe\n");
	main();
	return 0;
}

函数自己调用自己,一直打印 “hehe” 但是一会程序自己会停下来。这不是真正的递归,是一个死循环(不满住递归的两个条件)

递归实现:接收一个整型值(无符号),按照顺序打印它的每一位。

例如:

输入:1234

输出:4321

void print(unsigned int n)
{
	if (n > 9)
	{
		print(n / 10);
	}
	printf("%d", n % 10);
}
int main()
{
	unsigned int num = 0;
	scanf("%u", &num);
	//递归-函数自己调用自己
	print(num);
	return 0;
}

基本的实现逻辑如图:

写递归代码的时候注意:

  • 不能死递归,都有跳出条件,每次递归逼近跳出条件
  • 递归层次不能太深(可能会栈溢出)

二、递归与迭代

求第n个斐波那契数,(可以递归实现也可以迭代实现)(不考虑溢出)
我们知道像:1,1,2,3,5,8,13,21,34…… 这样第n个数等于第n-1个数加上n-2个数的和的一个数列就是斐波那契数列

  • 递归实现求斐波那契数,直接看代码:
int Fib(int n)
{
	if (n <= 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main()
{
	int n = 0;
	scanf("%d",&n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

当我们求很小的斐波那契数时,计算机计算很快。但是当我们要求的一个很大的,比如第50个斐波那契数,计算机就会算很久(大概要五分钟)。大家可以试一试。

为什么会这么慢呢。因为递归实现效率太低,要重复大量的计算(计算层次太多)。

代码实现的基本逻辑如图:

我们可以看一下代码在计算过程中 n=3(计算第三个斐波那契数) 这一步要执行的次数:

在计算第40个斐波那契数时,要计算三千多万次第三个斐波那契数。可想而知递归实现的效率有多低。而且计算太大还会造成程序崩溃。

  • 循环迭代实现求斐波那契数,直接看代码:
int Fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n > 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

循环迭代的方式计算很快

提示

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

到此这篇关于C语言函数的递归调用详情的文章就介绍到这了,更多相关C语言递归调用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言函数的递归和调用实例分析

    一.基本内容: C语言中的函数可以递归调用,即:可以直接(简单递归)或间接(间接递归)地自己调自己. 要点: 1.C语言函数可以递归调用. 2.可以通过直接或间接两种方式调用.目前只讨论直接递归调用. 二.递归条件 采用递归方法来解决问题,必须符合以下三个条件: 1.可以把要解决的问题转化为一个新问题,而这个新的问题的解决方法仍与原来的解决方法相同,只是所处理的对象有规律地递增或递减. 说明:解决问题的方法相同,调用函数的参数每次不同(有规律的递增或递减),如果没有规律也就不能适用递归调用. 2

  • C++函数的嵌套调用和递归调用学习教程

    C++函数的嵌套调用 C++不允许对函数作嵌套定义,也就是说在一个函数中不能完整地包含另一个函数.在一个程序中每一个函数的定义都是互相平行和独立的. 虽然C++不能嵌套定义函数,但可以嵌套调用函数,也就是说,在调用一个函数的过程中,又调用另一个函数. 在程序中实现函数嵌套调用时,需要注意的是:在调用函数之前,需要对每一个被调用的函数作声明(除非定义在前,调用在后). [例]用弦截法求方程f(x)=x3-5x2+16x-80=0的根. 这是一个数值求解问题,需要先分析用弦截法求根的算法.根据数学知

  • C语言函数的递归调用详情

    目录 一.什么是递归 二.递归与迭代 一.什么是递归 程序调用自身的编程技巧称为递归( recursion) .递归做为一种算法在程序设计语言中广泛应用.一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量.递归的主要思考方式在于:把大事化小 递归的两个必要条件: 存在限制条件,当满足这个限制条件的时候,递归便不再继续. 每次

  • PHP 无限分类三种方式 非函数的递归调用!

    php无限分类大致有三种方式, 1.数据库通过设置父类ID来进行唯一索引,然后使用函数的递归调用实现无限分类: 2.数据库设计通过特定格式进行排列,然后使用mysql查询关键函数:concat.程序实现比较简单: 3.第三种不是太了解, 好像要使用到算法和数据结构进行排列. 今天我主要分享下第二种方式,一开始也是找了很多资料,确实比较难理解.不过最终还是给搞明白了,因此记下随笔,希望通过这篇文章能够帮助到大家. 一.数据库设计: 复制代码 代码如下: -- -- Table structure

  • JavaScript中匿名函数的递归调用

    不管是什么编程语言,相信稍微写过几行代码的同学,对递归都不会陌生. 以一个简单的阶乘计算为例: function factorial(n) { if (n <= 1) { return 1; } else { return n * factorial(n-1); } } 我们可以看出,递归就是在函数内部调用对自身的调用. 那么问题来了,我们知道在Javascript中,有一类函数叫做匿名函数,没有名称,怎么调用呢?当然你可以说,可以把匿名函数赋值给一个常量: const factorial =

  • C语言 函数缺省参数详情

    目录 一.函数简介 1.函数声明 2.函数定义 3.函数调用 4.函数形参和实参 二.函数缺省参数 1.函数全缺省参数 2.函数半缺省参数 三.注意事项 一.函数简介 1.函数声明 函数声明只是一个空壳,不会有具体的函数实现,而定义要实现函数的实现,例如: int sub(int x,int y); //只需要声明即可,不需要实现这个函数的功能 2.函数定义 函数的定义需要实现这个函数的功能,例如: int sub(int x,int y) ////需要实现这个函数的功能 { return (x

  • Go语言函数的延迟调用(Deferred Code)详解

    目录 基本功能 示例一:延迟调用执行顺序 示例二:多defer使用方法 实例三:defer与局部变量.返回值的关系 先解释一下这篇Blog延期的原因,本来已经准备好了全部内容,但是当我重新回顾实例三的时候,发现自己还是存在认知不足的地方,于是为了准确表述,查阅了大量的资料,重新编写了第三部分,导致延期.感谢持续关注本笔记更新的朋友,后期我将逐步通过3-5分钟视频方式为大家对笔记内容进行讲解,帮助更多的朋友能够快速掌握Go语言的基础. 本节将介绍Go语言函数和方法中的延迟调用,正如名称一样,这部分

  • 详解Javascript函数声明与递归调用

    Javascript的函数的声明方式和调用方式已经是令人厌倦的老生常谈了,但有些东西就是这样的,你来说一遍然后我再说一遍.每次看到书上或博客里写的Javascript函数有四种调用方式,我就会想起孔乙己:茴字有四种写法,你造吗? 尽管缺陷有一堆,但Javascript还是令人着迷的.Javascript众多优美的特性的核心,是作为顶级对象(first-class objects)的函数.函数就像其他普通对象一样被创建.被分配给变量.作为参数被传递.作为返回值以及持有属性和方法.函数作为顶级对象,

  • Python函数递归调用实现原理实例解析

    函数的递归调用: 是函数嵌套调用的一种特殊形式 具体是指: 在调用一个函数的过程中又直接或间接地调用到了本身 # 直接调用本身 def func(): print('我是func') func() func() # 函数会不断的运行永远不会结束,但Python不允许这种情况,会默认限制只能调1000次. # 间接调用本身 def f1(): print('我是f1') f2() def f2(): print('我是f1') f1() f1() # 此时也相当于直接调用本身,f1-->f2-->

  • javascript高级编程之函数表达式 递归和闭包函数

    定义函数表达式有两种方式:函数声明和函数表达式. 函数声明如下: function functionName(arg0,arg1,arg2){ //函数体 } 首先是function关键字,然后是函数的名字. FF,Safrai,Chrome和Opera都给函数定义了一个非标准的name属性,通过这个属性可以访问到函数指定的名字.这个函数的值永远等于跟在function关键字后面的标识符. //只在FF,Safari,Chrome和Opera有效 alert(functionName.name)

随机推荐