<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;

}

在这里插入图片描述

  • 41
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

firdawn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值