模拟实现字符串有关函数(详细讲解)

在编写程序时,我们都喜欢写出简便并且效率高的代码,那么此时库函数中的有些函数就是我们的不二之选,那么,大家汇米你实现吗?下面就先从我们最简单的字符串函数说起:

1.strlen

这个是函数的格式,参数是const char* string,表示的是一个字符串的地址(就是在使用这个函数的时候,传参穿的是字符串的首地址),返回类型是无符号整数,那么,这个为什么是无符号整数呢?很简单,因为这个函数的功能是计算字符串长度,以字符'\0'结束,所以,再算长度的时候,总不能说是负数吧,所以返回类型是无符号整数。那么,介绍了这个函数的功能和形参还有返回类型,下面就是轮到我们模拟实现它了,请看下面代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

void test1()
{
	char arr[] = "abcde";
	//首先使用库函数
	int len = strlen(arr);
	printf("%d", len);
}
int main()
{
	test1();
	return 0;
}

首先使用的是库里面的函数,打印结果如下:

其次使用我们自己实现的函数,代码以及打印结果如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
	//先断言一下
	assert(str);
	//实现步骤
	int count = 0;
	while (*str++)
	{
		count++;
	}
	return count;
}
void test2()
{
	char arr[] = "abcde";
	//开始模拟实现
	int len = my_strlen(arr);
	printf("%d", len);
}
int main()
{
	test2();
	return 0;
}

 

和库里函数一样,在实现strlen这个函数的时候,有三种实现方法,分别是递归,指针减指针,还有就是我的这个方法,大家下来可以试试用其他方法实现。

2.strcpy

这个函数的形参有两个,第一个形参是目的地,也就是你要拷贝的地方,第二个形参是源头,也就是你要拷贝的字符串。返回类型是char*,也就是char*的地址。这个函数的作用其实在刚刚我已经无意中说了,就是拷贝字符串。下面来看看库里的和我们自己所实现的到底一不一样:

库里函数的使用代码以及调试过程外加打印结果:

int main()
{
	char arr[] = "hello world";
	char arr1[20] = { 0 };
	strcpy(arr1, arr);
	printf("%s", arr1);
	return 0;
}

下面是我们自己所实现的代码以及调试过程和打印结果:

char* my_strcpy(char* dest, const char* src)
{
	//先断言
	assert(dest && src);
	//实现步骤
	char* tem = dest;
	while (*dest++ = *src++);
	return tem;
}
int main()
{
	char arr[] = "hello world";
	char arr1[20] = { 0 };
	char* p = my_strcpy(arr1, arr);
	printf("%s", p);
	return 0;
}

 

由此可见我们模拟实现的这个函数和库里功能相同。

注:1.在使用strcpy这个函数的时候,一定要谨记的一个错误,那就是第一个参数不能是常量字符串,因为常量字符串是不能修改的,而我们使用这个函数的要求就是目的地的空间大小可以修改。2.其实这一条注意事项和上一条差不多,那就是目的地的空间大小要足够容纳你所要拷贝的内容,否则会发生的错误是越界,也就是所谓的栈被破坏。 

3.strcat

这个函数的参数与上面的strcpy是一样的,返回类型也是一样的,都是char*,重复的话就不说了,可以看上面,直接在这说这个函数的功能是追加,就是在自己想要的字符串后面追加上想要追加的字符串,我们直接来看看库里的函数与模拟的代码以及调试过程和打印结果。

库里的函数:

int main()
{
	char arr[20] = "abcdef";
	char arr1[] = "ghijk";
	strcat(arr, arr1);
	printf("%s", arr);
	return 0;
}

 

下面来看看我们自己模拟实现的这个函数:

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* tem = dest;
	while (*dest++);
	//一定要减减
	dest--;
	while (*dest++ = *src++);
	return tem;
}
int main()
{
	char arr[20] = "abcde\0xxxxxxxx";
	char arr1[] = "hijk";
	char* p = my_strcat(arr, arr1);
	printf("%s", p);
	return 0;
}

这个是我们自己模拟实现的strcat,可以看到的是与库里的函数功能一模一样,下面说一下这个函数的注意事项:

1.首先,包含上面的strcpy的两个注意事项

2.这个函数不可以自己给自己追加

3.因为是字符串函数,所以是寻找字符串的\0这个字符,从\0开始,也是从\0结束

4.strcmp

这个函数两个参数是字符串的首地址,返回类型是int型的一个函数,那么,这个函数的功能是什么呢?我们在编写代码的时候少不了要比较大小,在比较数字的的大小直接用大于号与小于号就行,但是字符串是不可以直接用这个比较的,所以此时这个函数就可以派上用场了,没错,这个函数的功能就是比较字符串大小的。我们先来看看库里的函数:

int main()
{
	char arr[] = "abcdef";
	char arr1[] = "abc";
	int ret = strcmp(arr, arr1);
	printf("%d", ret);
	return 0;
}

 

 

这个函数的返回值如果是字符串1大于字符串2的话,就返回大于0的数,等于返回0,小于返回小于0的数。

下面来看看我们自己模拟实现的这个函数:

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 && *str2)
	{
		if (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		else
		{
			return *str1 - *str2;
		}
	}
	if (*str1 == '\0' && *str2 == '\0')
	{
		return 0;
	}
	else
	{
		return *str1 - *str2;
	}
}
int main()
{
	char arr[] = "abcefghijk";
	char arr1[] = "abce";
	int ret = my_strcmp(arr, arr1);
	printf("%d", ret);
	return 0;
}

 

为什么返回值不一样呢?因为这个库里的函数,根据编译器的不同返回值也是不同的,在cplusplus上面的显示的是这样的

也就是我上面所说返回的值是大于0,小于0,等于0,因为在我用的这个编译器环境下,大于0会返回1,小于0会返回-1,等于0就是返回0,所以在我们模拟实现这个函数的时候,我个人认为还是根据库里函数的规则来写,所以返回的值只要是大于0或是小于0的就可以,当然这个看自己的喜好,没有强制要求。

以上函数是字符串长度不受限制的字符串函数,后面会更新字符串长度受限制的字符串函数的详细讲解,好了,如果本章内容对你有所帮助的话就留下一个赞吧,支持一下。谢谢! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

做了个springboot接口参数解密的工具,我给它命名为万能钥匙(已上传maven中央仓库,附详细使用说明)

前言&#xff1a;之前工作中做过两个功能&#xff0c;就是之前写的这两篇博客&#xff0c;最近几天有个想法&#xff0c;给它做成一个springboot的start启动器&#xff0c;直接引入依赖&#xff0c;写好配置就能用了 springboot使用自定义注解实现接口参数解密&#xff0c;普通…

SpringSecurity学习(七)授权

授权 什么是权限管理 权限管理核心概念 SpringSecurity权限管理策略 基于URL地址的权限管理 基于方法的权限管理 一、权限管理 二、授权核心概念 在认证的过程成功之后会将当前用户登录信息保存到Authentication对象中&#xff0c;Authentication对象中有一个getAuthorities…

ChatGPT-4震撼发布

3月15日消息&#xff0c;美国当地时间周二&#xff0c;人工智能研究公司OpenAI发布了其下一代大型语言模型GPT-4&#xff0c;这是其支持ChatGPT和新必应等应用程序的最新AI大型语言模型。该公司表示&#xff0c;该模型在许多专业测试中的表现超出了“人类水平”。GPT-4, 相较于…

基于Java+Springboot+vue高校资源共享交流平台设计和实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

SpringBoot介绍。

目录 一、SpringBoot简介 1、SpringBoot开发步骤 2、官网构建工程 3、SpringBoot概述 二、配置文件 1、配置文件格式 2、yaml格式 3、yaml配置文件数据读取 三、多环境配置 1、yam文件 2、properties文件 3、命令行启动参数设置 四、SpringBoot整合 1、SpringBo…

界面开发(4)--- PyQt5实现打开图像及视频播放功能

PyQt5创建打开图像及播放视频页面 上篇文章主要介绍了如何实现登录界面的账号密码注册及登录功能&#xff0c;还简单介绍了有关数据库的连接方法。这篇文章我们介绍一下如何在设计的页面中打开本地的图像&#xff0c;以及实现视频播放功能。 实现打开图像功能 为了便于记录实…

OCPC系列 - OCPC介绍扫盲贴来啦

本文对oCPC做个介绍&#xff0c;它是一种智能投放模式&#xff0c;系统通过对广告主转化数据的对接和深度理解&#xff0c;实时预估每一次点击的转化率并基于竞争环境智能出价&#xff0c;通过强化高转化率曝光机会的获取&#xff0c;弱化低转化率曝光机会的展现&#xff0c;以…

力扣-进店却未进行过交易的顾客

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1581. 进店却未进行过交易的顾客二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行…

文心一言正式对标GPT-4,是青铜还是王者?

昨天&#xff0c;OpenAI正式发布GPT-4模型 号称史上最先进的AI系统 今天&#xff0c;百度文心一言在万众瞩目中闪亮登场 这款产品被视为中国版ChatGPT 在这一个多月内备受关注 文心一言某种程度上具有了对人类意图的理解能力 回答的准确性、逻辑性、流畅性都逐渐接近人类…

Go 微服务开发框架 DMicro 的设计思路

Go 微服务开发框架 DMicro 的设计思路 DMicro 源码地址: Gitee:dmicro: dmicro是一个高效、可扩展且简单易用的微服务框架。包含drpc,dserver等 背景 DMicro 诞生的背景&#xff0c;是因为我写了 10 来年的 PHP&#xff0c;想在公司内部推广 Go, 公司内部的组件及 rpc 协议都…

多模态特征融合:图像、语音、文本如何转为特征向量并进行分类

多模态特征融合前言输入层&#xff0c;数据集转为特征向量图像语音什么是时域信号&#xff0c;什么是频域信号语音信号转换 - 1.傅立叶变换语音信号转换 - 2.梅尔频率倒谱系数文本词袋模型词嵌入模型输出层&#xff0c;多模态模型合并前言 学习多模态的话题可以从深度学习的分…

【YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进NO.57】引入可形变卷积

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv8&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列…

[JS与链表]普通链表

为什么要用链表要储存一系列数据&#xff0c;最常用的数据结构是数组。数组有个缺点就是在中间插入或删除元素需要移动元素&#xff0c;成本很高。什么是链表链表也是有序元素的集合结构。链表中的元素在内存中并不是连续放置的。每个元素都可以理解为一个对象。包含了本身元素…

简单了解JSP

JSP概念与原理概念: Java Server Pages&#xff0c;Java服务端页面一种动态的网页技术&#xff0c;其中既可以定义 HTML、JS、CSS等静态内容&#xff0c;还可以定义Java代码的动态内容JSP HTML Java, 用于简化开发JSP的本质上就是一个ServletJSP 在被访问时&#xff0c;由JSP容…

博途PLC开放式以太网通信TRCV_C指令应用编程(运动传感器UDP通信)

博途PLC开放式以太网通信TSENG_C指令应用,请参看下面的文章链接: 博途PLC 1200/1500PLC开放式以太网通信TSEND_C通信(UDP)_plc的udp通信_RXXW_Dor的博客-CSDN博客开放式TSEND_C通信支持TCP 、UDP等,关于TSEND_C的TCP通信可以参看下面这篇文章:博途PLC 1200/1500PLC开放式…

opencv识别车道线(霍夫线变换)

目录1、前言2、霍夫线变换2.1、霍夫线变换是什么&#xff1f;2.2、在opencv中的基本用法2.2.1、HoughLinesP函数定义2.2.2、用法3、识别车道3.1、优化3.1.1、降噪3.1.2、过滤方向3.1.3、截选区域3.2、测试其它图片3.2.1、代码3.2.2、图片13.2.3、图片23.2.4、图片31、前言 最近…

C++模拟实现红黑树

目录 介绍----什么是红黑树 甲鱼的臀部----规定 分析思考 绘图解析代码实现 节点部分 插入部分分步解析 ●父亲在祖父的左&#xff0c;叔叔在祖父的右&#xff1a; ●父亲在祖父的右&#xff0c;叔叔在祖父的左&#xff1a; 测试部分 整体代码 介绍----什么是红黑树 红…

2023年江苏省职业院校技能大赛中职网络安全赛项试卷-教师组任务书

2023年江苏省职业院校技能大赛中职网络安全赛项试卷-教师组任务书 一、竞赛时间 9:00-12:00&#xff0c;12:00-15:00&#xff0c;15:00-17:00共计8小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 基础设施设置与安全加固、网络安全事件响应、数…

链表相关oj题

1.Leetcode203 移除链表元素 解题思路&#xff1a;从头节点开始进行元素删除&#xff0c;每删除一个元素&#xff0c;需要重新链接节点 struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode*dummyheadmalloc(sizeof(struct ListNode));dummyhea…

spring5(四):IOC 操作 Bean 管理(基于注解方式)

IOC操作Bean管理&#xff08;基于xml方式&#xff09;前言一、注解1、概述二、入门案例1、Bean 的创建2、Bean的自动装配2.1 Autowired2、Qualifie3、Resource4、Value3、扫描组件3.1 配置文件版3.2 注解版4、测试前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心…