当前位置:网站首页>【C语言】剖析函数递归(2)
【C语言】剖析函数递归(2)
2022-08-02 13:04:00 【凡人编程传】
作者:凡人编程传
系列:C语言初阶(适合小白入门)
说明:以凡人之笔墨,书写未来之大梦

₪前言
这一节我们继续讲函数递归的内容,进一步深入了解递归到底是怎么做的,好了,咱们直接进入正题。
₪自定义实现strlen函数(不能创建临时变量)
可能有的人还不知道 strlen函数是啥,没关系咱们先打开MSDN查一查。
由图可知,这个函数的功能是获取一个字符串的长度。且他所属的头文件是< string.h >,返回类型是size_t(就是无符号整形),参数是const char*string,这里的const以后会讲,大家先当他不存在。好了,知道了这个函数的基本情况,不妨来使用一下。
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "bit";
int len = strlen(arr); //这里的数组名字,相当于数组首元素地址,也就是char* arr
printf("len = %d", len);
return 0;
}
这里补充一点,每个字符串的都有一个结束字符’\0’,而strlen()函数刚好就是遇到这个结束字符而停止计数有多少个字符(不包括\0).
如bit这个字符串在数组中的存储如图:

运行结果:
所以strlen函数遇到\0就停止计数,那么\0之前就有3个字符,也就是3.
那么我们现在就来自己实现这个函数,咱们先不按照题目来不用创建临时变量。根据上面的情况知道,这个函数最大的特点就是遇到\0就开始不计数。那么我们是不是就可以以此来作为循环计数条件,我们把数组首元素的地址传过去,然后每次* 解引用看一看这个地址里面的元素是不是\0,如果不是就代表这个字符串至少有一个字符,那么我们的计数变量就自增记录下来这个字符串有一个字符,直到一次解引用地址里面的内容是\0代表这个字符串结束了,后面没有字符了。那么最终计数变量的长度就是字符串的长度.
代码如下:
#include<stdio.h>
int my_strlen(char* str)
{
int count = 0; //计数变量
while (*str != '\0') //如果str指针指向的地址里面的内容不是\0,那么代表字符串还没有结束
{
count++; //不是\0就代表是字符,记录字符个数
str++; //指针指向下一个地址
}
return count;
}
int main()
{
char arr[] = "bit";
int len = my_strlen(arr); //这里的数组名字,相当于数组首元素地址,也就是char* arr
printf("len = %d", len);
return 0;
}
运行结果:
虽然结果是正确的,但是我们不符合题意啊。题目让我们不创建临时变量。那么我们怎么改呢?唉,我们这节主要讲的是递归嘛!那肯定用递归来写啊!没错,咱们就是用递归。
咱们在回忆一下递归的两个必要条件和思想
一、 递归的两个必要条件:
1.递归一定要有限制条件
2.每次递归都越来越接近这个限制条件二、 递归的思考方式:
把大问题,拆分成一个个与原问题类似的小问题。
其实递归两字就能体现出他的算法方式,"递"就是先到最深,“归"就是又由最深到浅,也就是从后往前面算。所以我们就可以先找到\0,让后\0开始"归”。这里要注意二点:如果我们字符串不是空串那么字符个数至少是1吧,如果字符串是空串的情况(也就是里面只有一个\0),所以写的时候一定要考虑空串的情况。那么就可以写代码了:
代码如下:
#include<stdio.h>
int my_strlen(char* str)
{
if (*str != '\0') //如果str指针指向的地址里面的内容不是\0,那么代表字符串还没有结束
{
return 1 + my_strlen(str + 1); //如果地址里面的内容不是\0,那么代表至少有一个字符就是1+... ,另外我们的目的是先找到\0然后从后往前算
}
else
{
return 0; //空串的情况
}
}
int main()
{
char arr[] = "bit";
int len = my_strlen(arr); //这里的数组名字,相当于数组首元素地址,也就是char* arr
printf("len = %d", len);
return 0;
}
运行结果:
如果还是不懂,没关系请看看这张图:
这里还要强调二点:
1.一就是那个else情况的return 0一定要写,就算你不考虑空串的情况如果不写也会导致结果错误,因为递归"'归"的时候一定要有一个归的值,如果不写那个else返回一个0,那么编译器会自动给你返回一个随机值,那么后面1+…的时候值就会不对了。
2.二就是肯定有人会想知道那个str+1,能不能写成str++,很明确告诉你不能,因为我们想要的是当前地址的下一个地址,如果你写成str++的话那么传过去的是原来str的地址,然后传过去了str的地址再+1(后置自增,先引用,再自增),那么这就冲突了啊!
₪结言
由于时间关系,本来打算全部讲完的,但是太忙了,最后两道题我们明天补充,在这里请大家谅解,好了希望对你有收获,下一节见!
边栏推荐
- 企业用直播平台能实现什么
- 单例模式的七种写法,你都知道吗?
- 冰箱“扩容”的战事,在今夏格外猛烈
- Automatically generate code generator recommendation-code-gen
- 【typescript】使用antd中RangePicker组件实现时间限制 当前时间的前一年(365天)
- [b01lers2020]Welcome to Earth-1
- Wireless vibrating wire acquisition instrument remote modification method
- Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单。
- Win11怎么修改关机界面颜色?Win11修改关机界面颜色的方法
- 智能手表前景如何?
猜你喜欢
随机推荐
网络流详解(流网图一般能够反映什么信息)
设置代理服务器(谷歌+IE)「建议收藏」
Introduction to Scala Basic Syntax (3) Various Operators in Scala
图论之Floyd,多源图最短路如何暴力美学?
Four seasons of trees realized by svg
The uniapp/applet onload method executes the interpretation every time the page is opened
我的创作纪念日
节省50%成本!京东云重磅发布新一代混合CDN产品
Cannot determine loading status from target frame detached when selenium chrome driver is running
Detailed explanation of network flow (what information can the flow network diagram generally reflect)
openGauss数据库基本操作(超详细)
Object.entries()
鲁大师7月新机性能/流畅榜:性能跑分突破123万!
SQL Server database generation and execution of SQL scripts
PHP+MYSQL [Student Information Management System] (Minimalist Edition)
js stopwatch countdown plugin
RISC-V 指令格式和6种基本整数指令
不错的射击类js小游戏源码
RESTful 风格(详细介绍 + 案例实现)
How to implement waterfall flow layout (what is waterfall flow layout)









