你好哦,这里是云切月斩(Echo_Fish),本文章如果能加深你对于strlen的理解,那么我将不胜荣幸!如果本文章存在错误请不吝赐教!
首先我们要知道strlen的语法,以及它是做什么的,它如何使用。
strlen:语法为: strlen(字符串名); 计算一个字符串中的有效字符长度,并且需要包含头文件#include<string.h>
strlen在使用后会返回一个无符号整型(unsigned int / size_t)
既然它有返回值,这意味着我们能够进行链式访问(即一个函数的返回值作为另一个函数的参数)
例如:
![](https://i-blog.csdnimg.cn/blog_migrate/b80d90588b3339230d0bf36862ff2677.png)
箭头所指的那一行就叫“链式访问”。
或者我们可以用常规方法,创建一个新变量来接受它的值,也能够达到同样的效果。
![](https://i-blog.csdnimg.cn/blog_migrate/f37d5383936c29b79f5dbed30a88c3b6.png)
注意:因为strlen的返回值是无符号整型,打印无符号整型时使用的是%u 而不是 %d。
介绍完了strlen与它的使用方法,那我们来说第一种模拟方法:计数器式
本方法涉及到:函数的使用、指针与循环
代码如下
![](https://i-blog.csdnimg.cn/blog_migrate/3570238a4b692de51becd4ed312184d9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/262876619bb881bdb086a5f364e63fc4.png)
数组名的本质是数组首元素的地址。我们封装一个无返回值的函数Calculator,这里我直接在函数中打印结果了,所以就没有特意设置一个返回值。
我们将数组名传递给函数的时候能将其设置为两种形式:用数组接受/用数组指针接收
这里使用的是数组指针的形式接受。
如上文所说,strlen是计算字符串有效字符的数字,遇到'\0'后停止。那么我们就有了思路。
首先使用循环,并且设置为死循环,然后我们就要思考一个跳出的条件,也就是当遇到指针指向
数组中'0'的地址时结束循环。这样一来,指针就经过了'\0'之前的所有地址,我们就可以想象,当它每移动一次,就经过一个字符,这是不是代表着我们可以使用一个计数变量count,在它移动一次的时候,计数count变量就增加一。到循环结束的时候,计数变量也就算出了字符串中含有的有效字符数量!
接着是第二种:指针-指针式
注:指针减指针 得到的数是两个地址间函数的个数
那么我们就可以封装如下函数
![](https://i-blog.csdnimg.cn/blog_migrate/d7170e811d283a61b99dfe99da4f6dba.png)
这里是主函数内的代码↓
![](https://i-blog.csdnimg.cn/blog_migrate/df5633a327f7e9b16770b0cd04acca82.png)
注意:&数组名,代表着整个数组的地址被赋给了指针变量p。
此时我们进行+1操作,意味着跳过了整个数组,指向数组最后一个元素的后面一位的地址,这时候我们在传参的时候就需要将指针指向的位置修改回来,强转为char*类型的指针并且-1,回移一个字节,指向字符串中最后一个元素的地址。然后我们调用函数就能得到我们想要的结果。
最后是第三种:递归式(可能比较难理解)递归即函数自己调用自己,必须设置结束条件,否则就会造成栈溢出,这里不做解释,有兴趣的小伙伴可以自行研究。
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/89f3c1c068897adf4c3bff6751f11e0d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a28e2239c24f5f5e702ca5793c2e27f8.png)
递归将大事分解为具有相似或者相同结果的小事。
在我看来,这与指针有异曲同工之妙,函数每次自己调用自己,都将指针向后移动一位,并且+1,直至指针指向'0'的地址,此时无法满足if的条件,执行else内的条件开始逐步归还之前调用的函数的所有结果,一直1+1+1+1+...直至返回第一次调用函数,最终将一个整型返还给主函数内用于接受函数结果的ret”!
至此对于strlen的介绍与它的三种模拟方法就介绍完毕了!
![](https://i-blog.csdnimg.cn/blog_migrate/c551dab5fcb549aa8edd453e9abac65f.jpeg)