内存函数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;
}
图解
希望分享的知识能对大家编程有帮助和理解学习,如果分享的内容有错误欢迎指出,有错误我将会进行修改,大家共同努力学习编程!!!