内存函数memcpy与memmove,memcmp的介绍与模拟实现

一、memcpy

1:memcpy函数介绍

//memcpy:内存数据拷贝
void * memcpy ( void * destination, const void * source, size_t num );

参数1:void *destination 数据拷贝的目的地
参数2:const void * source 被拷贝的数据源头
参数3:size_t num 需要拷贝数据的长度,单位字节

描述:函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。这个函数在遇到 ‘\0’ 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。

样例:

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int brr[10];
	//拷贝arr数组中前五个数据到brr数组中
	memcpy(brr, arr, 20);//int大小为4个字节,因此5个数据为20个字节
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", brr[i]);
	}
	return 0;
}

在这里插入图片描述

2: memcpy模拟实现

#include<stdio.h>
#include<assert.h>
//void * memcpy(void * destination, const void * source, size_t num);
void *my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest&&src);
	while (num--)
	{
	//将src内容拷贝到dest中
		*(char*)dest = *(char*)src;//强制转换为char*类型, 一个字节一个字节拷贝才能不造成数据丢失
		//往后移动一个字节,
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
	int b[10] = {5,6,7,8,9,10,1,2,3,4};
	my_memcpy(b, a, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", b[i]);
	}
	printf("\n");
	printf("拷贝成功!!!");
	return 0;
}

在这里插入图片描述

图解

在这里插入图片描述

二、memmove

1:memmove函数介绍

//memmove:内存数据拷贝
//和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
//如果源空间和目标空间出现重叠,就得使用memmove函数处理。
void * memcpy ( void * destination, const void * source, size_t num );

参数1:void *destination 数据拷贝的目的地
参数2:const void * source 被拷贝的数据源头
参数3:size_t num 需要拷贝数据的长度,单位字节

描述:memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

样例:

//memmove:重叠内存空间数据拷贝
int main()
{
	int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	memmove(a + 2, a, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

在这里插入图片描述

2:memmove模拟实现

模拟memmove实现注意事项:数据拷贝时需要考虑重叠空间怎么拷贝才能不会导致数据丢失,需要注意两种情况。第一种dest>src;第二种就是dest<src,下面我将要代码和图解演示两种不同的情况该如何拷贝数据

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove( void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest&&src);
	if (dest > src)//当目标复制地地址dest大于src复制源时,需要从src后前拷贝数据
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	else//dest<src
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;

		}
	}
	return ret;
}
int main()
{
	int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	memmove(a + 2, a, 20);
	printf("库函数实现:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	printf("模拟my_memover实现(dest>src):");
	int a1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memmove(a1 + 2, a1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a1[i]);
	}
	printf("\n");
	printf("模拟my_memover实现(dest<src):");
	int a2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memmove(a2, a2 + 2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a2[i]);
	}
	return 0;
}

在这里插入图片描述

图解

在这里插入图片描述

在这里插入图片描述

三、memcmp

1:memcmp函数介绍

描述:将 ptr1 所指向的内存块的前 num 个字节与 ptr2 指向的第一个字节数进行比较,如果它们都匹配,则返回零,或者如果不匹配,则返回与零不同的值,表示哪个值更大。
请注意,与strcmp不同,该函数在找到空字符后不会停止比较,需要先计算好需要比较的空间大小

//memcmp:比较两个内存块,与strncmp相似
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
//返回值 ptr1>ptr2 return >0
//      ptr1<ptr2 return  <0
//      ptr1==ptr2  return 0

样例:

// ptr1>ptr2 return >0
#include<stdio.h>
#include<string.h>
int main()
{
	char ptr1[] = "b";
	char ptr2[] = "a";
	int ret=memcmp(ptr1, ptr2, 1);
	printf("%d", ret);
	return 0;
}

在这里插入图片描述

// ptr1<ptr2 return >0
#include<stdio.h>
#include<string.h>
int main()
{
	char ptr1[] = "a";
	char ptr2[] = "b";
	int ret=memcmp(ptr1, ptr2, 1);
	printf("%d", ret);
	return 0;
}

在这里插入图片描述

// ptr1==ptr2  return 0
#include<stdio.h>
#include<string.h>
int main()
{
	char ptr1[] = "a";
	char ptr2[] = "a";
	int ret=memcmp(ptr1, ptr2, 1);
	printf("%d", ret);
	return 0;
}

在这里插入图片描述

2:memcmp模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
//int memcmp(const void * ptr1, const void * ptr2, size_t num);
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	assert(ptr1&&ptr2);
	while (num--)
	{
		if (*(char*)ptr1 == *(char*)ptr2)//强制类型转换为*char,一个字节一个字节比较
		{
			ptr1=(char*)ptr1+1;
			ptr2=(char*)ptr2+1;
		}
		else if (*(char*)ptr1 > *(char*)ptr2)
		{
			return *(char*)ptr1 - *(char*)ptr2;//ptr1>ptr2  返回相减的数
		}
		else
		{
			return  *(char*)ptr1 - *(char*)ptr2;//ptr1<ptr2  返回相减的数
		}
	}
	return 0;
}
int main()
{
	int ptr1[] = { 1,2,3,5,4,6 };
	int ptr2[] = { 1,2,3,6,5,6 };
	int ret1=memcmp(ptr1, ptr2,sizeof(ptr1));
	printf("库函数模拟实现:%d\n", ret1);
	int ret2 = my_memcmp(ptr1, ptr2, sizeof(ptr1));
	printf("my_memcmp模拟实现:%d\n",ret2);
	return 0;
}

在这里插入图片描述

图解

在这里插入图片描述
希望分享的知识能对大家编程有帮助和理解学习,如果分享的内容有错误欢迎指出,有错误我将会进行修改,大家共同努力学习编程!!!

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值