c语言 深入理解函数的递归

前言:

 首先,递归是什么,递归就是在定义函数时,然后在函数里调用这个函数,通俗讲,就是函数自己调用自己。那么递归的好处是什么呢?它能够将复杂的问题,用少量的代码来表示,增加了代码的可读性。

但是递归有一个条件,就是每一次的重复调用都需要越接近这个限制条件。

1.用递归打印一个整数的每一位

题目的要求是打印一个整数的每一位,就比如说1234,打印的结果就是1234,我们学过用循环打印过4321,但顺着打印,用循环来做,相对于递归来解,就会有点复杂。

#include<stdio.h>//打印一个整数的每一位,用递归
print(int n)
{
	int i = 0;
	if(n>9)
	{
		print(n / 10);
	}
	printf("%d", n%10);
}
int main()
{
	int num = 0;
	printf("请输入一个整数:");
	scanf("%d",&num);
	print(num);
	return 0;
}

这道题就是利用了递归的思想,此时的递归函数就是print函数。

首先是递归中的“递”

当我们在scanf函数中输入一个整数1234时,第一次进入print函数里,通过if语句再次进入print函数里,注意这时还未进行printf打印出结果。

这就到了第二次进入print函数里,此时进入函数的数子不在时 1234,而是除以十后的123,进入print函数后,再次通过if语句,进入print函数,注意这时也还未进行printf打印出结果。

第三次进入print函数里,是除以十后的12,12依然大于9,所以再次通过if语句,进入print函数,这时进入print函数的是除以十后的1.注意这时也还未进行printf打印出结果

第四次调用print函数时,此时的n就是1,显然不满足大于9的条件。这时的1余以十的结果还是1,于是首先打印出1。

然后就是递归中的“归”

打印完1后,第四次进入循环的过程就结束了,此时,接着归回上一次的循环,我们知道上次的循环到进入if语句后,就没有再次往下进行,归时就接着上次的操作,往下进行运行,就打印12余十的结果2,同理,就打印出最终的1234.

2.递归求n的阶乘

你是否还记得上次求n的阶乘还是说在上次。这次用递归来求解n的阶乘,实际上也是非常的简单,先写出不用递归来求n的循环。

#include<stdio.h>//求n的阶乘
int main()
{
	int num = 0; int i = 0; int ret = 1;
	printf("请输入一个值:");
	scanf("%d",&num);
	for (i = 2; i <=num; i++)
	{
		ret *= i;
	}
	printf("%d", ret);
	return 0;
}

然后就是递归求n的阶乘:

#include<stdio.h>//求n的阶乘
int fac(int n)
{
	if (n > 1)
		return n * fac(n - 1);
	else
		return 1;
}
int main()
{
	int ret = 0;
	int num = 0;
	printf("请输入n的值:");
	scanf("%d", &num);
	ret=fac(num);
	printf("%d", ret);
	return 0;
}

这时的n就是输入的值,fac(n-1)就重复调用此函数,又可以无限接近这个n大于1的这个条件。这就用到了递归的思想。我们知道求n的阶乘,也可以表示成n乘以(n-1)的阶乘。以此重复,n-1等于1时就停止。就达到求n的阶乘的目的~~

3.用递归和非递归求字符串的长度

求字符串的长度,不就是strlen函数吗?

但是,不用这个库函数呢

我们依然可以用两种方法进行求解。

首先用非递归来求字符串的长度,也就是用我们自己的my_strlen函数。

#include<stdio.h>//用非递归求字符串的长度
my_strlen(char *arr)
{
	int a = 0; int ret = 0;
	char c = *(arr+a);
	while(arr[a] != '\0')
	{
		a++;
		ret++;
		}
	return ret;
}
int main()
{
	int ret = 0;
	char arr[] = "abc";
	ret=my_strlen(arr);
 	printf("%d", ret);
	return 0;
}

递归如下:

#include<stdio.h>
my_strlen(char* arr)
{
	int i = 0;
	if (*arr == '\0')
		return 0;
	if (*arr != '\0')
		return 1 + my_strlen(arr + 1);
}
int main()
{
	int ret = 0;
	char arr[] = "abc";
	ret = my_strlen(arr);
	printf("%d", ret);
	return 0;
}

这道题的思路就是一个一个字符来数,知道\0来结束此程序,我们知道“abc”是由abc\0四个字符组成,而递归的思路就是先数出a这个字符然后再数b,直到\0结束。

4.输入一个数求各位数之和

这题的意思就是求出一个整数个十百千位之和,比如1234结果为10;

#include<stdio.h>//输入一个数求各位数之和
sum(int x)
{
	int ret = 0;
	if (x > 9)
	{
		return  x % 10 + sum(x / 10);
	}
	else
		return x;
}
int main()
{
	int num = 0;
	printf("请输入一个数之和:");
	scanf("%d", &num);
	printf("%d",sum(num));
	return 0;
}

5.用递归求n的k次方

#include<stdio.h>//用递归求n的k次方
tmp(int x,int y)
{
	if (y <= 0)
	{
		return 1;
	}
	else
		return x * tmp(x, y - 1);
}
int main()
{
	int k = 0; int n = 0;
	printf("请输入一个n和k:");
	scanf("%d %d",&n, &k);
	int ret=tmp(n,k);
	printf("%d", ret);
	return 0;
}

6.计算斐波那契数

#include<stdio.h>//计算斐波那契数
feibona(int n)
{

	if (n >= 3)
		return feibona(n - 1) + feibona(n - 2);
	else 1;
}
int main()
{
	int n = 0;
	printf("请输入一个n:");
	scanf("%d", &n);
	int ret=feibona(n);
	printf("%d", ret);
	return 0;
}

斐波那契数就是1 1 2 3 5 8 13……前两个数之和得到第三个数

这里给出不用递归的求解:

#include<stdio.h>//用非递归求斐波那契数\
int feibona(int N)
{
int i = 1;
int j = 1;
int sum = i + j;
for (i = 4; i <= N; i++)
{
	i = j;
	j = sum;
	sum = i + j;
}
return sum;
}
int main()
{
	printf("请输入一个n:");
	scanf("%d",&n);
	int ret=feibona(n);
	printf("%d", ret);
	return 0;
}

结语:

以上这些都利用到了递归函数的求解方法,思想都是差不多的,如果你仔细琢磨,会发现递归的魅力,这些例题可以拿来复习,欢迎大家支持 点赞 收藏~~

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

(0)

相关推荐

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

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

  • C语言的递归函数详解

    目录 函数递归 什么是递归? 递归的俩个必要条件 代码引例1 栈溢出(Stack Overflow) 合理使用递归 代码引例3 代码引例4 解释要合理使用递归 总结 函数递归 程序调用自身的编程技巧称为递归 recursion) 函数自己调用自己就是递归 你也可以理解成是一种嵌套结构,但递归分为俩部分,第一是“递”,进入嵌套结构.第二是”归“,最终会一步一步返回.第一次接触递归都会很懵,慢慢理解这个过程就明白了. 什么是递归? 递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或

  • 使用C语言递归与非递归实现字符串反转函数char *reverse(char *str)的方法

    代码如下所示: 复制代码 代码如下: // 递归实现字符串反转   char *reverse(char *str)   {    if( !str )    {     return NULL; } int len = strlen(str);       if( len > 1 )       {           char ctemp =str[0];           str[0] = str[len-1];              str[len-1] = '/0';// 最后一

  • 一篇文章带你了解C语言函数递归

    目录 什么是递归? 递归的两个必要条件 递归实例 实例1(按照顺序打印一个数的整形值) 画图讲解 完整代码 实例2 (使用函数在不创建变量的情况下求字符串长度) 画图讲解 程序运行结果 完整代码 递归与迭代 实例1 (求n的阶乘) 方法一(使用递归) 方法二(使用迭代) 实例2 (求解斐波那契数列) 方法一 (递归求解) 方法二(迭代求解) 总结 什么是递归? 递归(recursion):程序调用自身的一种编程技巧. 如何理解函数递归: 1.从调用自身层面:函数递归就是函数自己调用自己. 2.从

  • C语言函数的基本使用和递归小结

    本章目标 秃头侠们好呀,今天我们一起学习函数! 目标: 本章主要掌握函数的基本使用和递归 函数是什么 数学中我们常见到函数的概念.但是你了解C语言中的函数吗? 维基百科中对函数的定义:子程序 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method,subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组成.它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性. 一般

  • C语言 function recursion函数递归详解

    目录 function recursion(函数递归) 递归的中心思想为: 程序一 递归的两个必要条件 程序一: 程序二: 练习 求n的阶乘 再来道例题 function recursion(函数递归) 函数递归: 是在 一个 过程 或 函数 在其定义或说明中有 直接 或 间接 调用自身 的一种方法 通常把一个 大型复杂的问题 层层 传化 为一个与 原理相似的 ,规模较小 的问题 递归策略 只需 少量的程序 就可以描述出 解题过程 所需的 多次 重复 计算,大大减少了程序的代码量 递归的中心思想

  • C语言函数的基本使用和递归详解

    目录 本章目标 函数是什么 C语言中函数的分类 库函数 如何学会使用库函数? 自定义函数 函数的参数 函数的调用: 函数的嵌套调用和链式访问 嵌套调用 链式访问 函数的声明和定义 函数递归 什么是递归? 递归的两个必要条件 递归与迭代 总结 本章目标 秃头侠们好呀,今天我们一起学习函数! 目标: 本章主要掌握函数的基本使用和递归 函数是什么 数学中我们常见到函数的概念.但是你了解C语言中的函数吗? 维基百科中对函数的定义:子程序 在计算机科学中,子程序(英语:Subroutine, proced

  • C语言用递归函数实现汉诺塔

    目录 汉诺塔(Hanoi)是什么? 那么,C语言如何实现汉诺塔呢? 汉诺塔的基本思路是: 具体代码见下(注意点在代码下面): 总结 汉诺塔(Hanoi)是什么? 一个简单的汉诺塔就如上图所示,有三个放置点,放置物必须遵循上小下大的规则,依次将1中的放置物全部放置到3中.就比如该图中有4个放置物,若将A上的放置物全部移至C上,具体的步骤是:A->B A->C B->C A->B C->A C->B A->B A->C B->C B->A C->

  • c语言 深入理解函数的递归

    前言:  首先,递归是什么,递归就是在定义函数时,然后在函数里调用这个函数,通俗讲,就是函数自己调用自己.那么递归的好处是什么呢?它能够将复杂的问题,用少量的代码来表示,增加了代码的可读性. 但是递归有一个条件,就是每一次的重复调用都需要越接近这个限制条件. 1.用递归打印一个整数的每一位 题目的要求是打印一个整数的每一位,就比如说1234,打印的结果就是1234,我们学过用循环打印过4321,但顺着打印,用循环来做,相对于递归来解,就会有点复杂. #include<stdio.h>//打印一

  • C语言超细致讲解函数递归

    目录 前言 什么是递归 递归的两个必要条件 题解递归 递归与迭代 练习题 结束语 前言 最近被函数递归困恼许久,今天就带领大家一起探秘递归. 什么是递归 程序调用自身的编程技巧称为递归( recursion). 递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接 调用自身的 一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略 只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量. 递归的主

  • 关于c语言中回调函数的理解

    前言 在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序. 这段话不是那么好理解,不同语言实现回调的方式有些许不同.其实可以这样理解,回调就是在一个函数中调用另外一个函数. 在c语言中,回调是使用函数指针来实现的. 函数指针--顾名思义,是指向一个函数的指针.通常函数指针有两个方面的用途,一个是转换表(jump table),另一个是作为参数传递给一个函数. 下面是两个函数指针的声明 int(*f)(i

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

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

  • C语言运用函数的递归实现汉诺塔

    目录 1.汉诺塔是如何实现的 2.汉诺塔问题画图详解 3.汉诺塔问题代码解释 总结 1.汉诺塔是如何实现的 下面是有三个盘子的示例: 从左到右一次是 A柱 B柱 C柱 A柱:起始位置 B柱:目标位置 C柱:过度位置 汉诺塔为题即是,将A柱上的所有盘子移动到B柱上,且每次只能移动一个盘子,并且小盘子必须在大盘子上面 2.汉诺塔问题画图详解 下面的例子是以A柱为起始位置,B柱为中间位置,C柱为目标位置的 如果初始状态下:A柱只有一个盘子:A->C A柱有两个盘子:A->B A->C B-&g

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

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

  • C语言植物大战数据结构二叉树递归

    目录 前言 一.二叉树的遍历算法 1.构造二叉树 2.前序遍历(递归图是重点.) 3.中序遍历 4.后序遍历 二.二叉树遍历算法的应用 1.求节点个数 3.求第k层节点个数 4.查找值为x的节点 5.二叉树销毁 6.前序遍历构建二叉树 7.判断二叉树是否是完全二叉树 8.求二叉树的深度 三.二叉树LeetCode题目 1.单值二叉树 2. 检查两颗树是否相同 3. 对称二叉树 4.另一颗树的子树 6.反转二叉树 " 梧桐更兼细雨,到黄昏.点点滴滴." C语言朱武大战数据结构专栏 C语言

  • Go语言入门之函数的定义与使用

    目录 1.前言 2.函数声明 2.1 函数例子 2.2 Go 函数支持多返回值 2.3 变量函数 2.4 闭包 2.5 递归 3.总结 1.前言 函数是一段代码的片段,包含连续的执行语句,它可以将零个或多个输入参数映射到零个或多个参数输出.函数像一个黑盒,对它的使用者隐藏实现细节.还可以在代码中通过函数调用来执行它们. 学到现在,我们使用的 Go 函数只有 main 函数: func main() { } 2.函数声明 每个函数都包含 func 关键字.函数名.输入参数列表.一个可选的返回列表以

随机推荐