一、strlen()的工作原理

二、模拟实现strlen的三种方法

  1. 计数器方法
  2. 指针-指针
  3. 递归的方法

三、库函数实现strlen的思路

四、库函数的strlen同上面模拟实现strlen的区别

一、strlen工作原理

strlen函数工作原理:是计算字符串str的长度,直到空字符串结束,但不包含空字符串。(即该长度算至/0结束,但不包含/0)

通过以下代码能有一个直观的感受:

int main(){
char arr[]="abcdef";
int len=strlen(a);//"abcdef"即 'a' 'b' 'c' 'd' 'e' 'f' '\0'
//计算的是'\0'之前的元素个数
printf("%d\n",len); // 输出结果为6
return 0; }

以上则为strlen的工作原理

即strlen计算的是字符串内'\0'之前的元素个数。(不包含'\0')

二、模拟实现strlen的三种方法

  1. 计数器方法
  2. 指针-指针
  3. 递归的方法

我们通过上述得知strlen的工作原理,那么我们接下来根据其工作原理实现strlen.

共有以下三种方式去实现:

ps:只有sizeof(数组名)&(数组名),此时代表的是整个数组的地址,其余时候

数组名 仅仅代表首元素地址。在本文中,数组名 只代表首元素地址。

int my_strlen(){}    //要实现的功能,如下三种方式
int main(){
char arr[]="abcdef";
int len=my_strlen(a);
printf("%d\n",len);
return 0; }

1.计数器方式(创建了临时变量)

思路如下:将arr传递到my_strlen中,我们创建一个变量 count ,当 *arr!=0 时则 count +1, arr也+1 ,此时 *arr='b' ,arr和count再同时+1, 直到 *a=='\0'时,

我们返回 count 的值,此时的 count 的值为元素的个数。

图解如下:

算法如下:

int my_strlen(const char *str){
int count=0;
while(*str!='\0'){ //当为'\0'时,即while(0),条件为假,退出循环
count++;
str++;
}
return count;
}

2.指针-指针(创建了临时变量)

思路如下:创建指针p指向arr,当p!='\0'时,p加上1,直到p='\0',用

指针p-指针arr,此时的指针p代表的是'\0'的地址,指针arr代表的是首

元素地址,两者相减得到的值为两地址之间的元素个数。

图解如下:

当p走到'\0'的地址时, p-arr=元素的个数

实现代码如下:

 int my_strlen(const char*str){
const char*p=str; while(*p){
p++;
}
return p-str;
}

3.递归(不创建临时变量)

思路如下:通过递归的思想。

图解吐下:

ps:递归的基本思想是把一个大型复杂的问题层层转化为一个与原问题相似的规

模较小的问题来求解。

算法如下:

int my_strlen(const char*str){
if(*str = = '\0'){
return 0;
}
else
return 1+my_strlen(str+1)
}

三、参考库函数如何实现strlen

对比自身用指针实现strlen,代码更为简洁,将 while(*p){p++;} 精简为

while(*p++);

图解如下:

ps:如何查看库函数实现strlen。可看链接:如何查看库函数实现的某些函数(strlen,strcmp,strcpy等)

四、库函数的strlen同上面模拟实现strlen的区别

可通过如下代码进行区别:

#include<string.h>
#include<stdio.h>
int main(){
if(strlen("abc")-strlen("abcdef")>0)
{printf("hehe\n");
}
else
{printf("haha\n");
}
}

很显然,我们应该是打印 haha,但结果是hehe,为什么打印的是hehe

因为在strlen()的函数声明如下:size_t strlen(const char*str)

定义的类型是size_t,那么size_t又是什么类型

通过如下操作可知:

可知size_t是无符号整型,于是:无符号整型-无符号整型=无符号整型

于是打印的是hehe

我们模拟实现函数strlen返回的是int,于是当我们

调用my_strlen时,打印的便是haha,效果如下

模拟实现strlen的三种方法的更多相关文章

  1. JS模拟实现封装的三种方法

      前  言  继承是使用一个子类继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承!  JS中有很多实现继承的方法,今天我给大家介绍其中的三种吧. 1.在 Object类上 ...

  2. 三种方法教你如何用PHP模拟post提交数据

    php模拟post传值在日常的工作中用到的不是很多,但是在某些特定的场合还是经常用到的. 下面,我整理了三种php模拟post传值的方法,file_get_contents.curl和socket. ...

  3. Chrome模拟手机浏览器(iOS/Android)的三种方法,亲测无误!

    大网站都有推出自己的手机访问版本页面,不管是新闻类还是视频网站,我们在电脑是无法直接访问到手机网站的,比如我经常访问一个3g.qq.com这个手机站点,如果在电脑上直接打开它,则会跳转到其它页面,一般 ...

  4. 用Fiddler可以设置浏览器的UA 和 手动 --Chrome模拟手机浏览器(iOS/Android)的三种方法,亲测无误!

    附加以一种软件的方法是:用Fiddler可以设置浏览器的UA 以下3种方法是手动的 通过伪装User-Agent,将浏览器模拟成Android设备. 第一种方法:新建Chrome快捷方式 右击桌面上的 ...

  5. Javascript定义类(class)的三种方法

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  6. javascript生成对象的三种方法

    /** js生成对象的三种方法*/ // 1.通过new Object,然后添加属性 示例如下: var people1 = new Object(); people1.name = 'xiaohai ...

  7. php生成随机数的三种方法

    php生成随机数的三种方法 如何用php生成1-10之间的不重复随机数? 例1,使用shuffle函数生成随机数. <?php$arr=range(1,10);shuffle($arr);for ...

  8. [转]Javascript定义类的三种方法

    作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...

  9. php发送post请求的三种方法示例

    本文分享下php发送post请求的三种方法与示例代码,分别使用curl.file_get_content.fsocket来实现post提交数据,大家做个参考. php发送post请求的三种方法,分别使 ...

  10. java 获取随机数的三种方法

    方法1(数据类型)(最小值+Math.random()*(最大值-最小值+1))例:(int)(1+Math.random()*(10-1+1))从1到10的int型随数 方法2获得随机数for (i ...

随机推荐

  1. JUnit 5 单元测试教程

    点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 在软件开发过程中,我们通常都需要测试 ...

  2. 【Android逆向】rpc调用某安App的X-App-Token签名函数

    阅读此文档的过程中遇到任何问题,请关注公众号[移动端Android和iOS开发技术分享]或加QQ群[309580013] 1.目标 在学习的过程中,会遇到有些算法比较麻烦,没有办法直接还原.那我们就另 ...

  3. AIR32F103(六) ADC,I2S,DMA和ADPCM实现录音播放功能

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  4. windows使用pyinstaller 打包sklearn模块出现死循环报错

    前言 解决这个让我花费了很长时间, 我这里说的死循环,不是正常通过 --hidden-import能解决的问题. 因为我也查询了很多资料 但是无一例外都失败了(能通过 –hidden-import 解 ...

  5. 【每日一题】【map存值】2022年2月25日-NC112 进制转换

    描述给定一个十进制数 M ,以及需要转换的进制数 N .将十进制数 M 转化为 N 进制数. 当 N 大于 10 以后, 应在结果中使用大写字母表示大于 10 的一位,如 'A' 表示此位为 10 , ...

  6. Selenium4+Python3系列(十一) - Page Factory设计模式

    写在前面: Page Object模式,目的是将元素定位和元素操作分层,只接触测试内容,不写基础内容,便于后续对自动化测试用例体系的维护,这是中心思想,也是核心. 那么我们继续将简洁延续,这里沿用Ja ...

  7. BOM与DOM之BOM操作

    目录 一:BOM与DOM操作 1.BOM与DOM操作 二:BOM操作 1.常用的Window方法: 2.案例实操 3.打开新窗口 4.关闭当前页面 三:window的子对象 1.navigator对象 ...

  8. python 实现DES加解密

    from pyDes import * import base64 class Des3(object): def __init__(self, key, iv): # 这里密钥key长度必须为16/ ...

  9. vue实现移动端左右菜单双向联动效果

    话不多说,上demo <template> <div id="app"> <header>左右列表双向联动</header> < ...

  10. sql根据团队树一级一级汇总统计

    ​ 1.需求描述 最近碰到了一个需求,是要统计各个团队的员工的销售金额,然后一级一级向上汇总. ​编辑 架构团队树是类似于这种样子的,需要先算出每个员工的销售金额,然后汇总成上一级的团队金额,然后各个 ...