0. memcpy、memmove函数介绍!
0.1 memcpy
通过cplusplus.com这个网站呢,我们可以查到memcpy参数有3个
第一个参数 代表目的地
第二个参数 代源头
第三个参数 代表多少个字节
由于参数类型是void * 类型,所以在进行复制的时候,是可以任意类型进行复制的!相比strncpy的功能就强大了很多!
下面看下函数实现效果!
int main()
{
int i = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr1[5] = { 0 };
memcpy(arr1, arr, 12);
for (i = 0; i < 5; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
我们可以看到输出结果为1 2 3 0 0因为第三个参数为12,一个整型为4个字节,12个字节为3个整型,所以这串代码,讲arr数组中前3个元素复制到arr1数组中,最后将arr1数组打印出来。
0.2 memmove
通过cplusplus.com这个网站呢,我们可以查到memcpy参数有3个
第一个参数 代表目的地
第二个参数 代源头
第三个参数 代表多少个字节
该函数功能更加强大!他可以复制本身的元素到自己这!
下面来看代码实现效果!
我们可以看到,它将1 2 3复制到了 3 4 5的位置!然后最终arr数组中元素就是1 2 1 2 3 6 7 8 9 10。
1. 模拟实现memcpy【不能拷贝本身到本身】
下面让我画个图为大家一起来分析下,代码应该如何写呢?
首先arr1数组为目的地,arr2数组为源头,分别用指针dest和指针src指向。
其次我们将src指向的内容赋值给dest,然后将两个指针分别向后移动,而移动的次数,取决于第三个参数 num。最终就将arr2数组内容复制到arr1数组中!
有了思路以后呢,我们来写代码!
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src); //判断两个指针是否为空
while (num--)
{
*(char*)dest = *(char*)src; //因为传的是void*类型,所以要进行强制转换
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
2. 模拟实现memmove【可以拷贝自身到自身】
我们先来画图分析一下!拷贝自身到自身时候会出现的几种情况
2.1 dest > src
从图中我们可以看出如果要将5 6 7 8 9 拷贝到 8 9 10 11
从后—>前,只有这样才不会覆盖!
2.2 dest < src
从图中看出,我们要将5 6 7 8 9 拷贝到 3 4 5 6 7
从前—>后,只有这样才不会覆盖!
经过以上分析之后,我们就有了思考!
2.3 代码实现
2.3.1 dest<src时 代码实现原理和memcpy一模一样
while (num--)
{
*(char*)dest = *(char*)src; //因为传的是void*类型,所以要进行强制转换
dest = (char*)dest + 1;
src = (char*)src + 1;
}
2.3.2 dest>src
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
这里因为num进入while循环内部以后,已经减1,所以就不用再减1.
2.3.3 代码最终结合
void* my_memmove(void const* dest, void* src, size_t num)
{
assert(dest && src);
if (dest < src) // 从 前---->后
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else //从 后----->前
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
}
2.3.4 运行结果
3.结束语
如果有疑问,记得评论哦!