1.先来看下memcpy库函数的返回值以及参数,让我们更对这个库函数更加熟悉
上图可以看到memcpy返回值是(void*)类型的指针
第一个参数dest指的是被复制内容的目标空间位置类型强转为void*。
第二个参数src指的是要复制的数据源类型是const修饰的void*,为什么要强转为void* 因为这样memcpy库函数不会因为类型的限制变的局限,可以接受多种类型。
第三个参数是需要拷贝的字节数。
下面是模拟实现出的memcpy函数
#include<stdio.h>
#include<assert.h>
void* My_memcpy(void* s1, const void* s2, size_t count) //s1就是p2 是被拷贝的目标空间
{ //s2就是p1 是需要拷贝的数据源
assert(s1 && s2);
void* flag = s1;
while (count--)
{
*(char*)s1 = *(char*)s2;
s1 = (char*)s1+1;
s2 = (char*)s2+1;
}
return flag;
}
int main()
{
int p1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int p2[5] = { 0 };
My_memcpy(p2, p1, 20);
int i = 0;
int sz = sizeof(p2) / sizeof(p2[0]); //打印p2数组的内容
for (i = 0; i < sz; i++)
{
printf("%d ", p2[i]);
}
return 0;
}
2.接下来再看memmove库函数的返回值与参数。
我们可以看到memmove这个库函数的返回值与参数与memcpy是一模一样的,那memmove的作用是什么呢?
memcpy在同一个数组内进行操作的时候,dest的起始位置与src的起始位置重叠的情况下会差生覆盖的效果,从而导致程序没有达到我们想要的效果,下图有详细解释。
当我们想要在同一个数组内进行修改的时候就可以使用memmove这个库函数了,它就完美填补了memcpy库函数的缺点,从而达到我们想要的效果。
下面是模拟实现的memmove函数
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* My_memmove(void* s1, const void* s2, size_t count)
{
assert(s1 && s2);
void* flag = s1;
if (s1 < s2)
{
while (count--) //从前向后
{
*(char*)s1 = *(char*)s2;
s1 = (char*)+1;
s2 = (char*)+1;
}
}
else
{
while (count--)
{
*((char*)s1 + count) = *((char*)s2 + count); //从后向前拷贝
}
}
return flag;
}
int main()
{
int p1[10] = { 1,2,3,4,5,6,7,8,9,10 };
My_memmove(p1+2, p1, 20);
int i = 0;
int sz = sizeof(p1) / sizeof(p1[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", p1[i]);
}
return 0;
}
详细图解: