当前位置: 首页 > news >正文

【c语言初阶】函数递归

前言:

对应b站鹏哥c语言视频46课,感谢鹏哥

软件版本dev c++

内容:

什么是递归?

程序调用自生的编程技巧叫做函数递归

递归的主要思考方式是:把大事化小。

递归的两个必要条件

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

每次递归调用之后越来越接近这个条件

练习题 

//接受一个整型值(无符号),按照顺序打印他的每一位
//例如:
//输入:1234, 输出 1 2 3 4 

主要的函数实现

变量名重复也没事,因为是存放的不同的地址,

主要原理就是利用函数自己调用自己,然后不满足条件就会一直调用,最终调用到

123 / 10=12

12 /10 =1

等于1时,就不满足num > 9(这里是判断个位数的,因为个位数不大于9,)

然后就执行后面的printf打印操作,打印1,

然后这个函数调用完成,继续实现上面的函数

所以先打印的是

1 然后是 2 3 4 

void print(unsigned int num)
{
	if(num>9)
	{
		print(num / 10);
	}
	printf("%d ", num % 10);
 } 
 

常见的报错形式

stack overflow(栈溢出)

栈区(存放的是局部变量,函数的形参)

每一次函数的调用都会在栈区申请空间

将if(num > 9)去掉,就会造成造成栈溢出,因为进去这个函数就会调用这个,进去就调用,无限循环

void print(int num)
{
//	if(num>9)
	{
		print(num / 10);
	}
	printf("%d ", num % 10);
 } 

 

实现代码 

#include <stdio.h>
//接受一个整型值(无符号),按照顺序打印他的每一位
//例如:
//输入:1234, 输出 1 2 3 4 

//%d 是打印有符号的整数(有正负数)
//%u 是打印无符号的整数

//int main() 
//{
//	unsigned int num = 0;
//	scanf("%u", &num);
//	
//	while(num)
//	{
//		printf("%d ", num % 10);
//		num = num / 10;
//	}
//	return 0;
//}

//函数递归的方式实现
void print(int num)
{
	if(num>9)
	{
		print(num / 10);
	}
	printf("%d ", num % 10);
 } 
 
int main()
{
	unsigned int num = 0;
	
	scanf("%u", &num);
	print(num);
	return 0;
 } 

第二道题,用一个函数来实现strlen的功能,然后不能创建局部变量

好奇怪,就是这个递归就是思想好奇特,我想不到这个

函数的主要功能的实现代码

int my_strlen(char arr1[])
{
	if(*arr1 != '\0')
	{
		return 1+my_strlen(arr1 +1);
	 }
	else
	{
		return 0;
	}

}

这个my_strlen(arr1 + 1);

arr1 + 1就是是地址加一,数组就是地址加一,

数组里的地址是连续的,只需要加1就可以了,

arr1就是相当于数组的第一个地址,那为啥不直接就是*arr1,这个好像是解引用了,就是相当于他的值,arr1就相当于地址哦, 

 就是不知道那个怎么来的

这里就是说值不等于\0,就加1,然后再调用自身函数,在判断,在加一,

一直调用,然后再回来打印自己的值

最后调用的值是\0,然后调用就停止,因为他返回了return 0,所以他返回的值就是1

        return 1+my_strlen(arr1 +1);

返回倒数第二个就是

        return 1+1

第一个就是

        return 1+2

结果就是等于三

那他的条件是\0,为啥不是while循环

if(*arr1 != '\0')

{

        return 1+my_strlen(arr1 +1);

}

while循环也可以,这样写就好了,需要把else去掉

int my_strlen(char arr1[])
{
    while(*arr1 != '\0')
    {
        return 1+my_strlen(arr1 +1);
     }
    
    return 0;
}

//编写函数不允许创建临时变量,求字符串的长度

//求字符串的长度
//模拟实现strlen 

//先模拟正常函数的实现功能
//int my_strlen(char arr1[])
//{
//	int count = 0;
//	while(*arr1 != '\0')
//	{
//		my_strlen(*)
//	}
//	return count;
//}
//
//int main()
//{
//	char arr[] = "abc";
//	//char*
//	int len = my_strlen(arr);
//	
//	printf("%d", len); 
//	return 0;
// } 






int my_strlen(char arr1[])
{
	if(*arr1 != '\0')
	{
		return 1+my_strlen(arr1 +1);
	 }
	else
	{
		return 0;
	}

}

int main()
{
	char arr[] = "abc";
	//char*
	int len = my_strlen(arr);
	
	printf("%d", len); 
	return 0;
 }  

相关文章:

  • 玩机日记 12 在PVE Windows11上部署本地AI模型,使用群晖反代https转发到外网提供服务,配合沉浸式翻译插件翻译网页
  • 复现论文:DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization
  • 蓝桥杯 Java B 组 之堆的基础(优先队列实现 Top K 问题)
  • 链表_反转链表
  • 矿用机车移动逆变电源设计(论文+源码)
  • 机器学习实战(8):降维技术——主成分分析(PCA)
  • 深入浅出:0 - 1 背包问题的滚动数组解法
  • 延迟任务的11种实现方式(下)!!
  • 机器学习实战(7):聚类算法——发现数据中的隐藏模式
  • 【C++八股】野指针和悬空指针
  • SOME/IP--协议英文原文讲解9
  • golang面试题:两个interface{} 能不能比较?
  • SprutCAMX16数控软件介绍
  • uniapp图像转换(获取本地选取或拍照的图片的base64、Blob、图像和base64的转换)
  • vscode复制到下一行
  • 什么是网络安全审计?网络安全审计的作用...
  • 【Mastering Vim 2_04】第三章:追随最佳实践:插件管理之道
  • 用PyInstaller构建动态脚本执行器:嵌入式Python解释器与模块打包 - 简明教程
  • 第四天面试题
  • Kafka消息服务之Java工具类
  • 牛市早报|中方调整对美加征关税措施,五部门约谈外卖平台企业
  • 受美关税影响,本田预计新财年净利下降七成,并推迟加拿大建厂计划
  • 香港暂停进口美国北达科他州一地区禽肉及禽类产品
  • 火车站员工迟到,致出站门未及时开启乘客被困?铁路部门致歉
  • 美国“贸易战”前线的本土受害者:安静的洛杉矶港和准备关门的小公司
  • 耿军强任陕西延安市领导,此前任陕西省公安厅机场公安局局长