<string.h>中部分库函数的模拟实现

在这里插入图片描述

前言

嗨,我是firdawn,本章将简单介绍,<string.h>中部分库函数的模拟实现,如strncpy,strncat,memcpy,memmove。在本文片末,还讲简单介绍判断机器大小端的函数实现,下面是本章的思维导图,那么,让我们开始吧!
在这里插入图片描述

一,模拟实现strncpy

1.1 strncpy的介绍

srtncpy的介绍参考cplusplus:strncpy,如下图是该介绍的机器翻译,有些地方可能翻译不准。从图中我们可以知道,strncpy用于将一个字符串拷贝到另一个字符数组中。
1.strncpy被包含在<string.h>这个头文件中。
2.它的函数声明为:char * strncpy ( char * destination, const char * source, size_t num );
3.其中包含三个参数,destination表示被拷贝的字符要放的目的地,source表示要拷贝到字符串的起始地址,num表示要拷贝几个字符。
4.返回值,返回值的类型为 char*,返回的是destination的值。
在这里插入图片描述

1.2 strncpy的使用

具体使用如图1.2-a
在这里插入图片描述
这里src数组被放入了4个字符。

1.3 实现strncpy

#include <string.h>

#include <assert.h>



char* my_strncpy(char* dest, const char* src, size_t num)

{

	assert(dest && src);

	char* p1 = dest;

	const char* p2 = src;

	//拷贝num个字符

	int i = 0;

	for (i = 0; i < num; i++)

	{

		*p1++ = *p2++;

	}

	*p1 = '\0';

	return dest;

}



//模拟实现strncpy

int main()

{

	char arr1[20] = "a cute cat";

	char arr2[20] = { 0 };

	my_strncpy(arr2, arr1, 6);

	return 0;

}

二,模拟实现strncat

2.1 strncat的介绍

srtncat的介绍参考cplusplus:strncat,同样的,因为该网站是国外的一个网站,所以有些地方可能翻译不准。如下图,是该介绍的机器翻译,从图中我们可以知道,strncat用于将一个字符串拼接到另一个字符数组的末尾。
在这里插入图片描述
1.使用函数所需的头文件:strncat 被包含在<string.h>这个头文件中。
2.函数声明:char * strncat ( char * destination, const char * source, size_t num );
3.参数:destination表示被拼接的字符要放的目的数组,source表示要被拼接到字符串的起始地址,num表示要拼接几个字符。
4.返回值:返回值的类型为 char*,返回的是destination的值。

2.2 strncat的使用

在这里插入图片描述
如上图,dest数组中被拼接了5个字符。

2.3 实现strncat

#include <string.h>

#include <assert.h>



char* my_strncat(char* dest, const char* src, size_t num)

{

	assert(dest && src);

	char* p1 = dest;

	const char* p2 = src;

	//让p1指向dest数组的'\0'位置

	while (*p1)

	{

		p1++;

	}



	//拷贝num个字符

	int i = 0;

	for (i = 0; i < num; i++)

	{

		*p1++ = *p2++;

	}

	*p1 = '\0';

	return dest;

}



//模拟实现strncat

int main()

{

	char arr1[20] = "a cute cat";

	char arr2[20] = "I have ";

	my_strncat(arr2, arr1, 6);

	return 0;

}

三,模拟实现memcpy

3.1 memcpy的介绍

memcpy的介绍参考cplusplus:memcpy,如下图,是该介绍的机器翻译,从图中我们可以知道,memcpy用于拷贝内存块的数据,拷贝大小单位是字节,不过,对于重叠内存块的拷贝,标准是未定义的。
在这里插入图片描述

1.使用函数所需的头文件:memcpy 被包含在<string.h>这个头文件中。
2.函数声明:void * memcpy ( void * destination, const void * source, size_t num );
3.参数:destination表示被拷贝的数据要放的目的数组,source表示要被拷贝的数据的起始地址,num表示要拷贝几个字节。
4.返回值:返回值的类型为 void*,返回的是destination的值。

3.2 memcpy的使用

在这里插入图片描述
如图,我们第一次将src数组中的数据拷贝到了dest数组中,第二次将src1数组中的数据拷贝到了dest1中。

3.3 实现memcpy

#include <assert.h>



void* memcpy(void* dest, const void* src, size_t num)

{

	assert(dest && src);

	char* p1 = (char*)dest;

	char* p2 = (char*)src;

	int i = 0;

	for (i = 0; i < num; i++)

	{

		*p1++ = *p2++;

	}

	return dest;

}



//模拟实现memcpy

int main()

{

	char arr1[20] = "beautiful girl";

	char arr2[20] = { 0 };

	memcpy(arr2, arr1, sizeof(arr1));

	return 0;

}

四,模拟实现memmove

4.1 memmove的介绍

memmove的介绍参考cplusplus:memmove,如下图,是该介绍的机器翻译,从图中我们可以知道,memmove用于拷贝内存块的数据,拷贝大小单位是字节,不过,它支持重叠内存块的拷贝,这在标准中是明确规定了的。
在这里插入图片描述

4.2 memmove的使用

在这里插入图片描述
在上图中,我们将src[ 2 ]的数据拷贝到了src后面,这里拷贝到内存块重叠了

4.3 实现memmove

#include <string.h>

#include <assert.h>



void* my_memmove(void* dest, const void* src, size_t num)

{

	assert(dest && src);

	const char* cur = (char*)src;

	char* p1 = NULL;

	if (dest > src)

	{

		p1 = (char*)dest + num - 1;

		for (cur = (char*)src + num - 1; cur >= (char*)src; cur--)

		{

			*p1-- = *cur;

		}

	}

	else

	{

		p1 = (char*)dest;

		for (cur = (char*)src; cur <= (char*)src + num - 1; cur++)

		{

			*p1++ = *cur;

		}

	}

	return dest;

}



//模拟实现memmove

int main()

{

	char arr1[30] = "a beautiful girl";

	my_memmove(arr1 + 2, arr1, sizeof(arr1));



	return 0;

}

五,机器大小端的判断

5.1 简单介绍大小端

大小端(Endian)是计算机数据存储的一种方式。在计算机中,数据存储的最小单位是字节(byte),每个字节由8个二进制位组成。在一个多字节数据(如整数、浮点数等)在内存中存储时,需要决定字节的排列顺序。

大端存储(Big Endian):字节的高位保存在低地址,字节的低位保存在高地址。即最高有效字节(Most Significant Byte)存储在最低内存地址,最低有效字节(Least Significant Byte)存储在最高内存地址。

小端存储(Little Endian):字节的高位保存在高地址,字节的低位保存在低地址。即最低有效字节(Least Significant Byte)存储在最低内存地址,最高有效字节(Most Significant Byte)存储在最高内存地址。

不同的计算机架构和处理器可能采用不同的存储方式。例如,x86架构的计算机通常使用小端存储,而PowerPC架构的计算机通常使用大端存储。为了在不同架构的计算机之间进行数据交换,通常需要进行字节序转换操作。

5.2 大小端的函数实现

int CheckSystem()

{

	int num = 1;

	return *((char*)&num);

}



//编写判断大小端程序

int main()

{

	int ret = CheckSystem();//小段返回1,大段返回0

	return 0;

}

在这里插入图片描述

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

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

相关文章

【Linux】LAMP集群分布式安全方案

LAMP集群分布式安全方案主要涉及确保Linux、Apache、MySQL和PHP&#xff08;LAMP&#xff09;组合构成的集群环境的安全性和稳定性。 本次实验通过网络层安全对防火墙配置&#xff1a;使用防火墙&#xff08;如iptables或firewalld&#xff09;来限制对集群的访问&#xff0c;只…

设计模式在芯片验证中的应用——单例

一、单例模式 单例模式(Singleton)是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c; 并提供一个访问该实例的全局节点。验证环境配置(configuration)类、超时(timeout)处理类等可以使用单例实现。比如说验证环境需要在特定场景中监测特定接口上的超时事…

AI+BI?国内期待值最高的4款智能问答类BI产品测评

AI大模型的这股风终是吹到了数据分析圈。与传统BI相比&#xff0c;问答BI进一步降低了数据获取门槛&#xff0c;通过对话的方式就可以访问数据并得出相应结论&#xff0c;更方便业务人员快速上手分析数据&#xff01; 问答BI&#xff08;Q&A BI&#xff09;在数据分析领域…

【论文笔记】| 定制化生成PuLID

PuLID: Pure and Lightning ID Customization via Contrastive Alignment ByteDance, arXiv:2404.16022v1 Theme: Customized generation 原文链接&#xff1a;https://arxiv.org/pdf/2404.16022 Main Work 提出了 Pure 和 Lightning ID 定制 (PuLID)&#xff0c;这是一种用于…

LaTeX 2022软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; LaTeX 2022是基于ΤΕΧ的一种排版系统&#xff0c;特别适用于生成科技和数学文档的高质量打印。它可用于各种文档类型&#xff0c;从简单信函到完整…

使用DataGrip连接Elasticsearch

使用DataGrip连接Elasticsearch 前言&#xff0c;公司需要使用ES来做数据的查询&#xff0c;我安装完ES&#xff0c;安装完Kibana的时候&#xff0c;想先开始尝试一下&#xff0c;插入查询数据能否可用&#xff0c;但是上次使用ES是好久前了&#xff0c;增删改查的请求根本记不…

学习Nginx(十四):配置SSL/TLS支持HTTPS

概念 SSL/TLS&#xff1a;安全套接字层&#xff08;SSL&#xff09;及其继任者传输层安全性&#xff08;TLS&#xff09;是为网络通信提供安全及数据完整性的一种安全协议。它们通过在应用程序协议&#xff08;如HTTP&#xff09;与TCP/IP协议族之间提供数据加密封面&#xff…

Three.js 研究:1、如何让物体动起来

1、制作模型动画 2、模型动画在代码中的调用 使用这个例子进行修改&#xff0c;使他能动作webgl_animation_skinning_morph.html 制作好的模型放到如下路径 /three.js-master/examples/models/gltf/无标题.gltf修改加载模型文件的地址 修改动画名称 运行 点击动画后&…

Python TinyDB库:轻量级NoSQL数据库的终极指南

更多Python学习内容&#xff1a;ipengtao.com TinyDB是一个轻量级的NoSQL数据库&#xff0c;适用于需要嵌入式数据库的小型项目。它使用JSON文件存储数据&#xff0c;并提供了简单易用的API&#xff0c;支持多种查询和索引操作。TinyDB非常适合那些不需要复杂数据库功能的小型应…

子比主题ACG美化插件[全开源]

WordPress插件是一种可以扩展和增强WordPress网站功能的应用程序。子比主题ACG美化插件听起来像是一个专门为ACG&#xff08;动画、漫画、游戏&#xff09;爱好者设计的美化插件&#xff0c;它可能包含多种功能来改善网站的外观和用户体验。 内置功能开关100意味着这个插件提供…

【Spring】SpringMVC基本概念

1、介绍 1.1简介 Spring MVC 是 Spring Framework 中的一个模块&#xff0c;它基于 Java 实现了 Web MVC 设计模式&#xff0c;用于构建 Web 应用程序。Spring MVC 提供了清晰的职责划分&#xff0c;使得开发者能够更加简洁和直观地开发 Web 层。 1.2优点 松耦合&#xff1a…

专业的ADAS测试记录仪ETHOS 2

随着ADAS驾驶辅助系统技术的快速发展及日臻成熟&#xff0c;近年来ADAS在全球汽车市场已开始快速普及和商业化&#xff0c;而如何确保ADAS系统的可靠和安全俨然成为汽车领域的重要问题。因此&#xff0c;ADAS驾驶辅助系统的测试也成为了各大整车厂及零部件厂商所关注的焦点。 一…

蓝海卓越计费管理系统 agent_setstate.php SQL注入漏洞复现

0x01 产品简介 蓝海卓越计费管理系统是一套以实现网络运营为基础,增强全局安全为中心,提高管理效率为目的的网络安全运营管理系统,提供“高安全、可运营、易管理”的运营管理体验,基于标准的RADIUS协议开发,它不仅支持PPPOE和WEB认证计费,还支持802.1X接入控制技术,与其…

轻松拿捏C语言——二分查找

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; 目录&#x1f389; 一、介绍&#x1f308; 二、步骤&#x1f319; 三、代码☀️ 一、介绍 二分查找是一种在有序数组中…

小程序丨公告栏功能,自动弹出提醒

发布查询时&#xff0c;您是否遇到这样的困扰&#xff1a; 1、查询发布时间未到&#xff0c;学生进入查询主页后发现未发布任何查询&#xff0c;不断咨询原因。 2、有些重要事项需要进入查询主页就进行强提醒&#xff0c;确保人人可见&#xff0c;用户需要反馈“我知道了”才…

Day48 Javascript详解

Day48 Javascript详解 文章目录 Day48 Javascript详解一、什么是javascript二、javascript特点三、 Javascript的历史四、Javascript vs Java五、JS的基本数据类型六、JS基本数据类型的特殊点七、数组 一、什么是javascript JavaScript是一种高级的、解释型的编程语言&#xf…

ST-SLAS Technology 实验室自动化与筛查学会技术

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、出版支持 一、期刊简介 SLAS Technology ——SLAS技术强调促进和改进生命科学研发的科学和技术进步;药物递送;诊断;生物医学和分子成像&#xff1b;以及个性化和精准医疗。这包括高通量和其他实验室自动化技术;…

eclipse配置JDK和Tomcat

eclipse配置JDK jdk配置 配置JDK&#xff1a; 首先&#xff0c;确保JDK已经安装并配置了环境变量。这包括设置JAVA_HOME环境变量&#xff0c;指向JDK的安装目录&#xff0c;以及更新CLASSPATH和PATH环境变量以包含JDK的bin目录。 在Eclipse中&#xff0c;通过Window > Pre…

EFuzz:基于程序环境的通用模糊测试工具

关于EFuzz EFuzz是一款功能强大的模糊测试工具&#xff0c;该工具支持基于程序运行环境来执行模糊测试&#xff0c;广大安全研究人员可以使用该工具对几乎任何程序组件执行安全模糊测试。 该工具在运行之后&#xff0c;会将所有的环境交互信息&#xff08;包括用户输入数据&am…

Linux —— 信号量

Linux —— 信号量 什么是信号量P操作&#xff08;Wait操作&#xff09;V操作&#xff08;Signal操作&#xff09;信号量的类型 一些接口POSIX 信号量接口&#xff1a;其他相关命令&#xff1a; 基于循环队列的生产者和消费者模型同步关系 多生产多消费 我们今天接着来学习信号…