我们在使用memmove函数的时候,会疑问这个函数是如何实现的啦,为什么有了memcpy函数还要使用memmove函数啦,下面我们通过对该函数的模拟实现,来详细了解一下该函数到底是如何实现的,首先我们在MSDN上面看一下memmove函数信息
通过上面的信息,我们照着模拟下面一个类似的函数
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dis, const void* src, size_t count)
{
assert(dis&&src);
void* ret = dis;
//前->后拷贝
if (dis < src)
{
while (count--)
{
*(char*)dis = *(char*)src;
dis = (char*)dis + 1;
src = (char*)src + 1;
}
}
//后->前拷贝
else
{
while (count--)
{
*((char*)dis + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
//模拟实现memmove函数
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
//my_memmove(arr+2,arr,5*sizeof(arr[0])); //从后向前拷贝
//期待结果:1,2,1,2,3,4,5,8,9,10
my_memmove(arr + 5, arr, 5 * sizeof(arr[0])); //从前向后拷贝
//期待结果:1 2 6 7 8 9 10 8 9 10
for (i = 0; i < 10; i++)
{
printf("%d ",arr[i]);
}
return 0;
//结果:1 2 1 2 3 4 5 8 9 10
//结果:1 2 6 7 8 9 10 8 9 10
}
在该函数中,我们同样也设置了三个参数,my_memmove(arr+5,arr,5*sizeof(arr[0])),在调用该函数时,对应的三个形参分别是(void* dis, const void* src, size_t count),函数返回类型我们也和memmove函数一样为void*
其实最重要的还是函数内部的实现
我们在这里会遇到任何情况,比如用户传给我们的各类数据:数字、字符
所以为了方面计算,我们统一将形参中的强制转换为char*指针,这样就可以一个一个字符滴操作,在函数判断之前,我们要断言一下用户传给我们的是否为空指针,所以要用assert函数来断言,当然不要忘了头文件#include <assert.h>。
我们在完成用户传给我们数据时,要判断该数据是否和我们的源数据内容重叠,如果重叠,我们又要判断,最终数据的指针和目标指针的大小关系,下面看图
dis为目标指针(要输入的结果),src为原对象,要将src里面的内容拷贝到dis中去,有三种情况,第一种情况就是dis指针小于src指针时,就从前往后拷贝,也就是将src里面的4,5,6,7分别考到dis里面的2,3,4,5中去;第二种情况就是dis指针大于src指针,就从后往前拷贝,也就是将src里面的4,5,6,7分别考到dis中的5,6,7,8中去;第三种情况就是dis指针和src指针没有交集,这种情况,将src里面的内容从前往后拷贝或者从后往前拷贝都行。
所以综上就可以这样写代码
//前->后拷贝
if (dis < src)
{
while (count--)
{
*(char*)dis = *(char*)src;
dis = (char*)dis + 1;
src = (char*)src + 1;
}
}
//后->前拷贝
else
{
while (count--)
{
*((char*)dis + count) = *((char*)src + count);
}
}
好啦,上面就是整个memmove函数的模拟实现