字符串函数的模拟实现

简介: 字符串函数的模拟实现

今天我们来了解以下一些字符串函数的模拟实现:

strlen strcpy strcat strcmp

strlen函数的模拟实现

首先我们转到cplusplus中查找strlen的官方解释:

通过查找我们了解到,strlen是用来测量一个字符串长度的函数,函数的返回值就是字符的长度

字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )。

函数原型如下

size_t strlen ( const char * str )

下面我们来简单了解以下strlen函数的使用(strlen函数等字符串函数的头文件一般都是string.h)

例如:我们测量一下字符串“abcdef”的字符串长度

int main()
{
  char arr[] = "abcdef";
  int len = strlen(arr);
  printf("此字符串的长度是%d\n", len);
  return 0;
}

运行结果如下:

下面我们就可以开始strlen函数的模拟实现了:

我们在之前已经知道,strlen就是从字符串的第一个元素开始往后找"\0",知道找到"\0",一旦找到,函数就立即停止,返回元素个数,这样理解,我们就可以更好地开始它的模拟实现了

方法一:以计数的方式实现

我们定义一个count,用while循环实现count的++,str为字符串的第一个元素的地址,也就是我们常说的首地址,如果解引用后(str)不是"\0",的话,count就++,也就是说元素个数+1,count++后str的位置也要往后移动,所以str++,当str=="\0"时循环停止,count就是字符串的长度了

代码如下:

int my_strlen(const char * str)
{
 int count = 0;
 assert(str);//进行断言操作,防止str为空
 while(*str)
 {
 count++;
 str++;
 }
 return count;
}
方法二:以递归的方式实现(不能创建临时变量时)

有时候一些题目可能会要求咱们不能创建临时变量来模拟实现,这个时候我们就可以想到递归:

思路如下:

int my_strlen(const char * str)
{
 assert(str);
 if(*str == '\0')
 return 0;
 else
 return 1+my_strlen(str+1);
}
方法三:以指针的方式实现

在之前的指针学习中我们可以知道指针-指针=两个之间的元素个数,所以这里我们首先定义一个指针变量p为str(字符串首地址),然后用while循环将p移动到\0之前的位置,然后相减得出的值就是字符串str的长度了

代码如下:

int my_strlen(char *str)
{
 assert(str);
 char *p = str;
 while(*p != ‘\0’ )
 p++;
 return p-str;
}
strcpy函数的模拟实现

老规矩,cplusplus查一下:

函数原型如下:

char* strcpy(char * destination, const char * source );

这里我们要注意:

• 源字符串必须以 ‘\0’ 结束

• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间

• ⽬标空间必须⾜够⼤,以确保能存放源字符串

• ⽬标空间必须可变

例如,我们将abcde拷贝到des中去:

我们可以打开调试窗口调试一下,就可以看到des将src中的\0也拷贝过去了

下面我们开始strcpy函数的模拟实现,用指针可以轻松的解决问题:

这里我们要记得断言!如果不断言就是报警,因为*解引用了NULL

当 *src不等于\0时,while循环就继续进行,将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环跳出,拷贝完成

这里我们要将dest的首地址记录下来,因为官方的函数定义是要求这个函数返回dest的首地址的

char* my_strcpy(char* dest, const char* src)
{
  char* ret = dest;
  assert(dest != NULL);
  assert(src != NULL);
  while (*src)
  {
    *dest=*src;
    dest++;
    src++;
  }
  return ret;
}

也可以简化:

char *my_strcpy(char *dest, const char*src)
{ 
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}
strcat函数的模拟实现

strcat的作用时将src链接到dest后面,并且这里也要返回dest的首地址

这里需要注意几点:

• 源字符串必须以 ‘\0’ 结束。

• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。

• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• ⽬标空间必须可修改。

我们调试看一看:

我们发现,src的内容就是从dest的\0的位置开始追加的

下面我们就可以开始模拟实现了

同样的我们需要用ret保存dest的首地址,同时记得断言

我们首先将dest的位置右移到\0的位置,然后再将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环结束,追加完成

char *my_strcat(char *dest, const char*src)
{
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while(*dest)
 {
 dest++;
 }
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}
strcmp函数的模拟实现

strcmp时用于比较两个字符串的,此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止 null 字符为止,如果str1大于str2(⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩),返回 一个大于0的值,str1小于str2,返回 一个小于0的值,如果完全等于,就返回0

例如:

abcde和abcee比较,由于d的acs码值要小于e所以会返回一个小于0的值

我们直接用while循环,如果相等,就继续往下走,不相等就就直接放回他们的差值,也就是asc码值相减,如果相等就为0,大于就时大于0,小于就小于0

代码如下:

int my_strcmp (const char * str1, const char * str2)
{
 int ret = 0 ;
 assert(src != NULL);
 assert(dest != NULL);
 while(*str1 == *str2)
 {
 if(*str1 == '\0')//此时两个字符串都遍历完成,且相等,直接返回0
 return 0;
 str1++;
 str2++;
 }
 return *str1-*str2;
}

好了,今天的分享到这里就结束了,谢谢大家!

相关文章
fbh
|
Web App开发 缓存 Linux
Chrome浏览器强制刷新页面(不使用缓存)
在Chrome浏览器中按下F5或 Ctrl+F5 都没用,Chrome总是会强制使用页面缓存进行刷新,如何不使用页面缓存进行刷新? Chrome官方推荐使用如下快捷键,就可以不使用页面缓存进行刷新 Windows和Linu...
fbh
12047 0
|
11月前
|
数据采集 搜索推荐
《从数据到转化:游戏地域偏好驱动的精准推送指南》
本文聚焦游戏行业地域化精准推送的核心痛点,提出基于玩家地域偏好的差异化推送体系构建思路。文章从无干扰数据采集与伪偏好筛滤入手,通过三维立体数据模型获取真实需求,再从行为、审美、需求、付费四个维度拆解地域偏好,形成可量化标签。进而搭建“偏好-内容-场景-时段”动态联动机制,定制适配不同地区的推送内容与策略,并依托数据和玩家双轮反馈实现闭环迭代,同时规避过度标签化、静态思维等认知误区。这套方法打破“一刀切”运营模式,助力游戏实现全域用户的长效激活与留存。
500 1
|
5月前
|
存储 人工智能 API
从软件订阅到基础设施计费:AI双轨制如何破解包月制成本错配困局
本文剖析AI订阅制的结构性困局——固定月费难承浮动算力成本,导致限速、降智与用户信任崩塌。提出“双轨制”(存算分离)新范式:存储轨按月固定收费,保障对话记忆永续;算力轨按Token用量计费,谁用谁付。借鉴电信“月租+流量”逻辑,实现公平、透明、可迁移的基础设施级计费。
665 7
|
6月前
|
安全 Java 编译器
【Java基础】面向对象三大特性、重载 vs 重写、接口 vs 抽象类(附《面试背诵版》+《自测题》)
本文系统梳理Java面向对象核心知识:详解封装、继承、多态三大特性及实现要点;清晰对比重载(编译时多态)与重写(运行时多态)的语法与语义差异;深入剖析抽象类(is-a、代码复用)与接口(can-do、多实现)的本质区别;涵盖面试高频考点、典型易错点及速记口诀,助你高效掌握并应对技术面试。
|
7月前
|
存储 小程序 关系型数据库
移动端毕设技术选型指南:基于阿里云生态的H5/小程序/APP架构实践与成本优化
本文面向2026届计算机毕设学生,提出“云原生毕设”新范式:针对移动端项目部署难、成本高、演示易翻车等痛点,结合阿里云Serverless(FC/SAE)、数据库(RDS)、存储(OSS)等产品,提供微信小程序、H5、原生APP三类架构方案,辅以智码方舟智能生成与高校优惠策略,助你百元内高效交付生产级毕设。
|
12月前
|
消息中间件 安全 Java
java消费消息且保证消息不丢失
本文介绍Java中如何安全消费消息并防止消息丢失或篡改,涵盖Kafka与RabbitMQ的消息持久化、手动确认机制及偏移量控制,强调事务处理与元数据保留,确保消息完整性与可靠性。
453 0
|
8月前
|
存储 机器学习/深度学习 缓存
RAG 技术在消费医疗场景落地的实践分享:抗干扰语义近邻过滤机制的设计与实现
本文分享RAG在消费医疗场景落地的关键实践:针对知识库中低质营销内容导致的语义污染问题,提出“抗干扰语义近邻过滤机制”。该机制基于局部近邻密度分析,通过无监督聚类识别营销簇,在检索后纯语义层面动态过滤干扰项,无需人工标注。实测污染率从28.4%降至4.7%,NPS提升至89,延迟仅增8ms。(239字)
367 1
|
10月前
|
数据采集 机器学习/深度学习 人工智能
AI智能体外包的开发流程
AI智能体外包不同于传统软件开发,需聚焦大模型调优、RAG构建与工作流编排。其核心在于迭代与评测。流程涵盖需求评估、数据处理、工具集成、多维测评及持续优化。雇主应避免“一口价”合同,重视边界处理与资产交付,确保可控可演进。#AI智能体 #AI应用 #软件外包公司(239字)
|
监控 数据可视化 算法
基于高德MCP2.0的智能旅游攻略系统设计与实现
MCP2.0(Map-based Collaborative Planning)是新一代旅游攻略系统,通过Web端可视化界面与高德地图API深度集成,实现了从静态攻略到动态智能规划的升级。系统核心功能包括可视化地图生成、高德地图APP深度集成、智能行程规划、实时路况优化和多端同步。技术栈采用Vue.js、Node.js、MongoDB和WebSocket,支持实时通信和数据同步。系统通过智能算法优化行程,结合实时路况动态调整路线,提升用户体验。未来发展方向包括AI推荐、AR导航和多语言支持,进一步扩展系统的
1024 4
基于高德MCP2.0的智能旅游攻略系统设计与实现