C语言函数递归
前言与概述
本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。
函数递归定义
程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。递归策略只需要少量的程序便可以描述出解题过程中所需要的多次重复计算,大大节省了程序的代码量,递归的主要思考方式在于大事化小。
最简单的递归
在main()函数体内调用main()函数,这是最简单的函数递归。当然,这样的函数递归是错误的,因为main()函数被不断的调用,导致陷入死递归。
示例代码:
//最简单的函数递归
#include <stdio.h>
int main()
{printf("Good!!\n");main();return 0;
}
运行结果:
栈溢出
Stack overflow:栈溢出。在计算机内存中,主要分为三大区:栈区、堆区、静态区。栈区存放着局部变量、函数形参、函数返回值等临时性变量。堆区主要用于动态内存分配。静态区主要存放全局变量和静态变量。如果我们把栈区单独拿出,当程序进入main()函数中,main()函数会向栈区申请空间,于是,main()函数会得到一片空间,称为main()函数的栈帧空间。在main()函数体内定义的局部变量会存放在main()函数的栈帧空间里。如果main()函数调用了函数,调用的这个函数同样也会向栈区申请空间。但是栈区的空间是有限的,如果不停的调用函数,就会不停的占用栈区空间,直到栈区空间被耗尽,就会导致栈溢出。当函数完成调用,就会自动销毁,并释放空间。
打印一个数的每一位
算法
现在有一个整数1234,按照顺序打印这个数的每一位。
整数1234最容易打印的数是4,只需要将这个整数模10(%10)就可以得到。然后将整数1234除10,就可以去掉最后一位数字。接着将得到的整数123模10,打印得到的数字3。再将这个整数除以10,去掉最后一位3,得到整数12。以此类推,当这个整数小于10,就可以直接打印。
% 10 用于得到最后一位;/ 10 用于去掉最后一位。
定义一个函数,用于打印整数的每一位;定义变量number将读取的数值作为实参传给函数。函数会通过对10取模,打印整数的最后一位。接着将整数的值除以10,作为新的实参传给函数。如果整数的值大于9,就重复执行打印、调用函数。否则,只打印不调用函数。
如果函数体内先打印后调用函数,得到的结果就是将原整数逆序打印。
所以可以先调用函数后打印,这样得到的结果就是将原整数顺序打印。
示例代码
//先调用后打印
#include <stdio.h>
void print(int x)
{if (x > 9){print(x / 10);printf("%d ", x % 10);}else{printf("%d ", x);}
}
int main()
{int number = 0;scanf("%d", &number);print(number);return 0;
}
运行结果
函数递归运行过程
如果我们想在屏幕上按顺序打印整数123的每一位。在控制台上输入数字123,scanf()函数读入用户输入的数值,并赋予变量number。main()函数调用print()函数,把变量number的值作为形参传给print()函数(步骤1)。此时形参x的值是123。x的值大于9,条件成立,将变量x的值除以10的结果作为实参传给print()函数(步骤2)。此时,形参x的值是12,大于9,条件成立,将变量x的值除以10的结果作为实参传给print()函数(步骤3),此时,形参x的值是1,条件不成立。在屏幕上打印变量x的值1。遵循着“从哪里来回到那里去”的原则,返回到上一个函数(步骤4),并直接向下执行,此时,形参x的值是12,在屏幕上打印数字2,并返回到上一个函数(步骤5)此时,形参x的值是123,在屏幕上打印数字3。返回到main()函数(步骤六)。
求n的阶乘
算法
一个数的阶乘就是从1开始,每次乘的数都比上一个乘的数多一,直到乘的数等于它本身。0的阶乘等于1。如4的阶乘就等于1*2*3*4=24。下面设计一个函数,用于根据用户输入的值,求出对应的阶乘。
如果用户输入的数小于等于1,那么n的阶乘就是1;否则,n的阶乘就是n *(n - 1)的阶乘。
示例代码:
//求n的阶乘
#include <stdio.h>
int times(int x)
{if (x <= 1){return 1;}else{return x * times(x - 1);}
}
int main()
{int number = 0;scanf("%d", &number);int result = times(number);printf("%d", result);return 0;
}
运行结果
函数递归调用过程
如果我们想知道3的阶乘,在控制台中输入数字3。scanf()函数从控制台中读取数字3,并赋予变量number。定义变量result,调用times()函数,将变量number的值作为实参传给函数(步骤一)。形参x得到变量number的值3。形参x的值大于1,条件不成立。调用times()函数,并将x - 1的值作为新的实参传给times()函数(步骤2)。此时形参x的值是2,条件不成立,调用times()函数,并将x - 1的值作为新的实参传给times()函数(步骤3)。此时形参x的值是1,条件成立,返回数字1。返回到上一个函数(步骤4),计算x * 1(2 * 1)的值并返回到上一个函数(步骤5)。函数得到返回值2,并将x * 2(3 * 2)的值返回到原调用函数处(步骤6)。变量result得到返回值6,并打印变量result的值。
递归与迭代
区别
迭代具有运行效率高的优点,但是代码量相对较大。递归整体上代码更加简洁,可读性高,但是可能出现栈溢出、运行效率低等问题。
求第n个斐波那契数(递归)
计算方法
什么是斐波那契数列?
1 1 2 3 5 8 13 21 34 55
斐波那契数列的第n个数(n >= 3)等于前两个数之和。
如果n的值小于等于2,那斐波那契数是1,如果n的值大于2,那么该斐波那契数等于第n - 1的斐波那契数加上第n - 2的斐波那契数。
示例代码(递归实现)
//求第n个斐波那契数
#include <stdio.h>
int fib(int x)
{if (x <= 2){return 1;}else{return fib(x - 1) + fib(x - 2);}
}
int main()
{int number = 0;scanf("%d", &number);int result = fib(number);printf("%d", result);return 0;
}
运行结果 (递归实现)
不足之处
虽然使用递归可以求出第n个斐波那契数,但如果输入n的值较大,就可能需要计算很长时间,甚至会导致程序崩溃。这主要是因为代码进行大量重复多余的计算。比如求第40个斐波那契数,仅第3个斐波那契数就重复计算了39088168次。于是,我们可以使用迭代来快速寻找到想要的值。
示例代码(迭代实现)
//求第n个斐波那契数非递归
#include <stdio.h>
int main()
{int number = 0;scanf("%d",&number);int a = 1;int b = 1;int c = 0;int temp = number;if (temp <= 2){c = 1;}else{while (temp - 2 >= 1){c = a + b;a = b;b = c;temp = temp - 1;}}printf("%d", c);return 0;
}
运行结果 (迭代实现)
代码分析
定义变量a保存第一个元素,定义变量b保存第二个元素,定义变量c保存第三个元素。如果输入的值小于等于2,那么变量c的值就是2。如果输入的值大于2,那么变量c的值就等于变量a的值加上变量b的值。把变量b的值赋予变量a,变量a就成为新的第一个元素,把变量c的值赋予变量b,变量b就成为新的第二个元素。
相关文章:

C语言函数递归
前言与概述 本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。 函数递归定义 程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它…...

【python数据分析11】——Pandas统计分析(分组聚合进行组内计算)
分组聚合进行组内计算 前言1、groupby方法拆分数据2、agg方法聚合数据3、apply方法聚合数据4、transform方法聚合数据5 小案例5.1 按照时间对菜品订单详情表进行拆分5.2 使用agg方法计算5.3 使用apply方法统计单日菜品销售数目 前言 依据某个或者几个字段对数据集进行分组&…...

高性能web服务器
目录 一、简介 (一)nginx-高性能的web服务端 (二)用户访问体验 二、I/O模型 (一)概念 (二)网络I/O模型 (三)阻塞型 I/O 模型 (四…...

微服务案例搭建
目录 一、案例搭建 1.数据库表 2.服务模块 二、具体代码实现如下: (1) 首先是大体框架为: (2)父模块中的pom文件配置 (3)shop_common模块,这个模块里面只需要配置pom.xml,与实体…...

SAP负库存
业务示例 在系统中,对于一些物料而言,不能立即将收到的交货输入为收货。如果要使发货无论如何都是可以过帐的,则需要允许这些物料的负库存。 负库存 发货数量大于预订数量时,过帐该发货就会出现负库存。如果由于组织原因&#…...

集团数字化转型方案(三)
集团数字化转型方案通过系统整合人工智能(AI)、大数据、云计算和物联网(IoT)技术,建立了一个全面智能化的业务管理平台,涵盖从业务流程自动化、数据驱动决策支持,到客户体验优化和供应链管理的各…...
ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)
本文将介绍如何实现一个功能丰富的ESP32项目,集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目,您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…...

web渗透测试 学习导图
web渗透学习路线 前言 一、web渗透测试是什么? Web渗透测试分为白盒测试和黑盒测试,白盒测试是指目标网站的源码等信息的情况下对其渗透,相当于代码分析审计。而黑盒测试则是在对该网站系统信息不知情的情况下渗透,以下所说的Web…...
WordPress禁止后台自定义功能
wordpress后台可以彻底禁止主题的自定义菜单功能,下面这段代码添加到functions.php文件中,后台外观菜单中的”自定义”就会消失不见了。 add_filter(map_meta_cap, function($caps, $cap){if($cap customize){return [do_not_allow];}return $caps; },…...
(六)Flink 窗口计算
窗口(Window)是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中,再对每个“桶”加以处理。 目录 时间概念 窗口类型 窗口划分 窗口的生命周期 Window Assigners 窗口函数 Triggers 窗口触发器 Evictor 数据剔除器 Allowed Lateness 旁路输出 时间…...

SQL 布尔盲注 (injection 第六关)
简介 SQL注入(SQL Injection)是一种常见的网络攻击方式,通过向SQL查询中插入恶意的SQL代码,攻击者可以操控数据库,SQL注入是一种代码注入攻击,其中攻击者将恶意的SQL代码插入到应用程序的输入字段中&am…...

OpenAI 重回巅峰:ChatGPT-4O 最新模型超越谷歌 Gemini 1.5,多项测试夺冠!
谷歌上周发布的Gemini 1.5 Pro模型,在LMSYS办的聊天机器人竞技场Chatbot Arena中获得第一名。但是,OpenAI迅速反应,推出了最新的chatgpt-4o-latest模型,重新夺回了冠军头衔。 chatgpt-4o-latest模型简介 OpenAI最近推出了名为gpt-…...
软件工程(2)面向对象方法:Booch方法与开发实例
Booch方法(Booch Method)是由Grady Booch提出的一种面向对象的软件开发方法。它是一种系统分析与设计的框架,主要用于设计和建模面向对象的系统。Booch方法特别关注对象模型的构建,以及类、对象和它们之间的关系。以下是Booch方法…...
高阶面试-concurrentHashMap的整理
算不上死磕,里面太痛苦了,现在很多位移等操作还看不懂,只是先理清大致思路,面试用 concurrentHashMap的实现原理 为啥会用到?并发安全。之前都用的hashtable实现线程安全的map,但是太过笨重,不…...

VSCode系列 - 如何用VSCode搭建C++高效开发环境(1)
VSCode是笔者用过的最好用的开发工具,没有之一。笔者14年的码龄生涯中,先后用过Eclipse、 IntelliJ IDEA、 WebStorm、 PyCharm、 Visual Studio(2010/2013/2015)、 NetBeans、 Sublime Text等,但自从用VSCode之后,就再没换过其他…...

【人工智能】Python融合机器学习、深度学习和微服务的创新之路
1. 🚀 引言1.1 🚀 人工智能的现状与发展趋势1.2 📜 机器学习、深度学习和神经网络的基本概念1.3 🏆 微服务架构在人工智能中的作用 2. 🔍 机器学习的演变与创新2.1 🌟 机器学习的历史回顾2.2 🧠…...

Stability AI发布了单目视频转4D模型的新AI模型:Stable Video 4D
开放生成式人工智能初创公司Stability AI在3月发布了Stable Video 3D,是一款可以根据图像中的物体生成出可旋转的3D模型视频工具。Stability AI在7月24日发布了新一代的Stable Video 4D,增添了赋予3D模移动作的功能。 Stable Video 4D能在约40秒内生成8…...

网站如何被Google收录?
想让你的网站快速被Google收录?试试GSI快速收录服务吧,这是通过谷歌爬虫池系统来实现的。这套系统吸引并圈养Google爬虫,提高你网站的抓取频率。每天有大量Google爬虫抓取你的网站页面,大大提高了页面的收录概率,从而增…...

LearnOpenGL——法线贴图、视差贴图学习笔记
LearnOpenGL——法线贴图、视差贴图学习笔记 法线贴图 Normal Mapping一、基本概念二、切线空间1. TBN矩阵2. 切线空间中的法线贴图 三、复杂模型四、小问题 视差贴图 Parallax Mapping一、基本概念二、实现视差贴图三、陡峭视差映射 Steep Parallax Mapping四、视差遮蔽映射 P…...

界面优化 - 绘图
目录 1. 基本概念 2. 绘制各种形状 2.1 绘制线段 2.2 绘制矩形 2.3 绘制圆形 2.4 绘制文本 2.5 设置画笔 2.6 设置画刷 3. 绘制图片 3.1 绘制简单图片 3.2 平移图片 3.3 缩放图片 3.4 旋转图片 1. 基本概念 虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...