【C语言】模拟实现深入了解:字符串函数

news2024/11/28 18:55:50

请添加图片描述
🔥引言

本篇将模拟实现字符串函数,通过底层了解更多相关细节

请添加图片描述
Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述


文章目录

  • 一、模拟实现字符串函数
    • 1.1 模拟实现Strlen
      • 1.1.1 方法一
      • 1.1.2 方法二:
      • 1.1.3 方法三:
    • 1.2 模拟实现Strcpy
      • 1.2.1方法一
      • 1.2.2 方法二
    • 1.3 模拟实现Strcat
    • 1.4 模拟实现Strcmp
    • 1.5 模拟实现Strncpy
    • 1.6 模拟实现Strncat
    • 1.7 模拟实现Strncmp
    • 1.8 模拟实现Strstr

一、模拟实现字符串函数


1.1 模拟实现Strlen

1.1.1 方法一

int main()
{
	char arr[] = "abcdef";
	int count = 0;//用于计算累积数
	while (arr[count] != '\0')//'\0'是不在计算的范围
	{
		count++;
	}
	printf("长度为%d\n", count);
	return 0;
}

1.1.2 方法二:

int main()
{
	char arr[] = "abcdef";
	int tap = 0;
	char* count = arr;//标记字符串的首地址
	while (arr[tap] != '\0') // \0是不在计算的范围
	{
		tap++;
		count++;
	}
	printf("长度为%d", count - arr);//指针-指针等于它们的差值
	return 0;
}

说明】:

  • 通过获得该字符串\0的位置,运用**指针(\0的位置)-指针(首位置)**等于两个指针的差值

1.1.3 方法三:

int pc(char* arr)
{
	assert(arr);//断言下
	if (*arr == '\0')//设计出口
	{
		return 0;
	}
	{
		return 1 + pc(arr + 1);
	}
}
int main()/
{
	char arr[] = "abcdef";
	printf("长值为%d", pc(arr));
	return 0;
}

说明】:

  • 字符串可以考虑使用大事化小的思想(递归)
  • 观察变化的量,得到等价关系
    在这里插入图片描述

1.2 模拟实现Strcpy

1.2.1方法一

void my_strcpy(char* dest, const char* str)
{
	while (*str != '\0')//判断拷贝结束条件
	{
		*dest = *str;//进行拷贝
		dest++;
		str++;
	}
}

说明】:

  • 两个指针指向对应的字符串,逐一拷贝
  • 虽然形参deststr是指针变量,形参不会影响到实参
  • 这里dest传递过来是地址(数组名),对此可以修改dest指向的字符串
  • dest指向的字符串需要被修改,但是src指向字符串不希望被修改

1.2.2 方法二

char* my_strcpy(char* dest, const char* str
{
    assert(dest != NULL);
    assert(str != NULL);
    char* ret = dest;//标记初始地址
    while (*dest++ = *str++)//判断和后置++打配合
    {
    }
    return ret;
}

说明】:

  • 这里实现逻辑跟方法一类似,只是这里循环判判断条件不同
  • 在循环判断语句中,完成拷贝赋值操作
  • 当str指针指向\0的位置,则表示循环结束
  • \0的ASCII码值是0(为假)
    在这里插入图片描述

1.3 模拟实现Strcat

char* my_strcat(char* p, const char* pc)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;///标记初始地址
	while (*p != '\0')//找到目标字符串的结束标记
	{
		p++;
	}
	while (*p++ = *pc++)//在结束标记的位置上追加,直到pc找到'\0'
	{
	}
	return ret;///返回初始地址
}

说明】:

  • 第一次循环:找到目标字符串的结束标记
  • 第二次循环:在结束标记的位置上追加,直到pc找到’\0’完成追加操作
    在这里插入图片描述

1.4 模拟实现Strcmp

int my_strcmp(const char* p, const char* pc)
{
	assert(p != NULL);
	assert(pc != NULL);
	while (*p == *pc)//不相等才要对比
	{
		if (*p == '\0')//找到结束位置了,说明两个字符串是相等的
		{
			return 0;
		}
		p++;
		pc++;
	}
	return *p - *pc;//用四则运算判断正负
}

说明】:

  • 循环判断是否相同
  • 相同继续向后寻找
  • 不相等则通过四则运算判断正负

1.5 模拟实现Strncpy

char* my_strncpy(char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;//标记初始地址
	while (sz--)//拷贝次数
	{
	  *p = *pc;//拷贝开始啦!
	   p++; 
       pc++;
	}
	return ret;//返回初始地址
}

说明】:

  • 跟模拟实现strcpy逻辑类似,只是通过一个变量控制循环次数

1.6 模拟实现Strncat

char* my_strncat(char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;//标记初始地址
	while (*p != '\0')//找到目标字符串的结束标记
	{
		p++;	
	}
	while (sz)//追加次数,注意上篇文章可能的问题
	{
		*p = *pc;
		p++;
		pc++;
	    sz--;	
	}
	return ret;//返回初始地址
}

说明】:

  • 跟模拟实现strcat逻辑类似,只是通过一个变量控制循环次数

1.7 模拟实现Strncmp

int my_strncmp(const char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	
		while (*p == *pc && sz--)//注意不同就是,次数作为判断条件
		{
			if (*p == '\0')//找到结束位置了,说明两个字符串是相等的
			{
				return 0;
			}
			p++;
			pc++;
		}
		return *p - *pc//用四则运算判断正负
	}

说明】:

  • 跟模拟实现strcmp逻辑类似,只是通过变量控制循环次数和是否不出现不相等

1.8 模拟实现Strstr

char* my_strstr(char* p, char* pc)
{
    assert(p && pc);
    char* dest = p;//标记初始地址
    char* str = pc;//标记初始地址
    
    if (*pc == '\0')//如果是空字符就没有不要了!
    {
        return p; 
    }
    
    while (*dest)//字符串寻找子字符串的次数
    {
        while (*p == *pc  &&  *p  && *pc)//实现逻辑
        {
            p++;
            pc++;
            if (*pc == '\0')//子字符串都对应上了
            {
                return dest;//找到位置的指针返回
            }
        }
        pc = str;//上面可能找到子字符串了,但是可惜不是回归子字符串的地址			
        dest++;
        p = dest;//dest的位置推进,地毯式搜索
    }
    
    if (*dest == '\0')//匹配完,找不到子字符串
    {
        return NULL;
    }
}

在这里插入图片描述

请添加图片描述

说明】:

  • 假设原字符串是ccpd,目标字符串cp
  • 当匹配第一个字符时,可能后继都是匹配的,也可以只是部分匹配
  • 对此需要记录这个匹配位置,通过内循环遍历一次判断是否匹配
  • 如果从这个位置不匹配,则推进一位,继续循环(暴力解法)

请添加图片描述

以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1659142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flowable多对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…

塑胶ERP系统都有什么用处

在当今竞争激烈的塑胶市场中,企业如何高效地管理从原料采购到产品销售的整个生产链,直接关系到企业的生存与发展。ERP系统作为一种先进的管理信息系统,正逐渐成为塑胶企业不可或缺的工具。那么,一款优秀的ERP系统,究竟…

C语言自定义类型——枚举

枚举 枚举定义枚举 与 #define使用写一个简易计算器的程序。 枚举定义 格式: enum name(枚举什么类型) {//数据 ... };枚举,顾名思义一 一 列举。 在生活当中有很多可以列举的东西。 如: //电脑桌面上的软件 enum App {QQ ,WeChat,CCtalk,…

ESG榜单冲击数据集(2000-2022年)

参照《财经研究》中刘柏(2024)的做法,以2015年为中点,根据商道荣绿2015年6月公开的ESG榜单数据,构建ESG榜单冲击的DID数据,如果公司属于ESG榜单冲击的公司,且年份≥2015,则为1&#…

OBS插件--视频回放

视频回放 视频回放是一款源插件,它可以将指定源的视频缓存一段时间(时间可以设定),将缓存中的视频添加到当前场景中后,可以快速或慢速不限次数的回放。这个功能在类似体育比赛的直播中非常有用,可以捕获指…

Leetcode - 周赛396

目录 一,3136. 有效单词 二,3137. K 周期字符串需要的最少操作次数 三,3138. 同位字符串连接的最小长度 四,3139. 使数组中所有元素相等的最小开销 一,3136. 有效单词 本题就是一道阅读理解题: 字符串长…

Docker Compose常用命令与属性

大家好,今天给大家分享Docker Compose的常用命令,以及docker-compose文件的属性。Docker Compose 是一个用于定义和运行多容器 Docker 应用应用的重要工具。它通过一个配置文件(docker-compose.yml)来详细定义多个容器之间的关联、…

爬虫-无限debug场景 解决方式

解决无限debug 场景1 1. 鼠标右键 选择 continue to here(此处不停留)2. 鼠标右键 选择 edite breakpoint 设置 10 保证条件不成立 这行永远不执行3.方法置空 1. 方法调用加断点2. 控制台 setInterval function name() {}4. 替换文件 5. hoo…

如何使用phpMyAdmin删除数据库中的表?

本周有一个客户,购买Hostease的Linux虚拟主机,询问我们的在线客服,如何使用phpMyAdmin删除数据库中的表?我们为用户提供相关教程,用户很快解决了遇到的问题。在此,我们分享这个操作教程,希望可以…

LeetCode63:不同路径Ⅱ

题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上角…

飞凌嵌入式FET113i-S核心板在国产FTU中的适配性分析

智能电网建设的不断推进,使配电自动化成为了提升电网运行效率、保障供电质量的关键技术。在配电自动化系统中,馈线终端单元(FTU)作为连接电网与用户的重要节点,承担着实时监控、故障检测与隔离、远程控制等多项关键任务…

SpringMVC传递参数

1.RequestMapping RequestMapping本身可以处理,get或post,指定了get或post之后,就只能处理对应的请求。 RequestMapping(value{"haihiyo","goodMoring"},methodRequestMethod.POST)2.RestFul风格 RestFul是一种风格 比如:网站的访…

知识付费系统怎么搭建_轻松拥有知识付费平台

在信息爆炸的时代,知识的获取已不再局限于传统的课堂和书籍。随着科技的进步和互联网的普及,我们迎来了一个全新的知识获取方式——知识付费。今天,就让我们一起探讨如何搭建一个专属于您的知识付费系统,开启智慧的大门&#xff0…

VScode查看以十六进制查看文件的插件说明

找到插件并下载 打开指定的文件 选择打开方式即可 结果如下

AI写的论文AI疑似度太高怎么办?教你一招解决

随着 AI 技术迅猛发展,各种AI辅助论文写作的工具层出不穷! 为了防止有人利用AI工具进行论文代写,在最新的学位法中已经明确规定“已经获得学位者,在获得该学位过程中如有人工智能代写等学术不端行为,经学位评定委员会…

诊所医院超常规运营管理思维课程

本课程旨在引领医疗机构管理者超越传统思维,探索创新运营管理策略。学员将学习领先的医疗管理理念、创新的运营模式,以及如何应对挑战和变革。课程内容涵盖战略规划、资源优化、服务创新等,帮助管理者提升运营效率,提供更优质的医…

什么是MVC?什么是SpringMVC?什么是三层架构?

文章目录 应用分层什么是MVC?什么是 SpringMVC?三层架构三层架构和MVC的关系 应用分层 在讲解什么是MVC之前,先来理解一下什么是应用分层。 应用分层是一种软件开发设计思想,将应用程序划分成N个层次,每个层次都分别负责自己的…

一对一WebRTC视频通话系列(五)——综合调试和功能完善

本系列博客主要记录一对一WebRTC视频通话实现过程中的一些重点&#xff0c;代码全部进行了注释&#xff0c;便于理解WebRTC整体实现。 本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习&#xff0c;梳理总结后写下文章&#xff0c;对音视频相关内容感…

燃料电池发电系统详解

目录 前言 组成结构 系统参数 常见问题 参考资料 前言 见《氢燃料电池技术综述》 见《燃料电池工作原理详解》 组成结构 燃料电池发电系统&#xff0c;由多个子系统和子模块组成&#xff0c;示例如下&#xff1a; 燃料处理系统&#xff08;fuel processing system&#xf…

开启短剧新纪元,短剧小程序开发等你来探索

一、引言 在信息爆炸的时代&#xff0c;短视频已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;随着人们对内容品质要求的不断提高&#xff0c;短剧作为一种新兴的内容形式&#xff0c;正逐渐崭露头角。为了满足广大用户对短剧内容的需求&#xff0c;我们倾力打造了…