memcpy函数和memmove函数
本篇博客只要涉及到memcpy函数与memmove函数的使用和模拟
文章目录
一、memcpy函数
1.1函数的定义
memcpy函数也就是内存拷贝函数,下面和strcpy比较一下:
memcpy函数有三个形式参数,因为是内存函数,所以对于传入形参的数据的类型不做任何限制,所以形式参数指针设置为void*,第一个参数是目的地址,第二个是原地址,第三个是拷贝多少个字节。
1.2memcpy函数使用
int main()
{
//int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//int arr2[10] = { 0 };
//memcpy(arr2, arr, 20);
float arr1[] = {
1.0f,2.0f,3.0f,4.0f };
float arr2[5] = {
0.0 };
memcpy(arr2, arr1, 8);
return 0;
}
计算机以小端存储,以16进制存储,32位机器 。所以两个16进制表示1个字节。
1.3memcpy函数模拟实现
#include <assert.h>
#include<stdio.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
void* ret = dest;
assert(dest);
assert(src);
while(num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
我们上述是实现memcpy函数,只可以处理没有重叠的字符串进行内存的拷贝,如果有重叠部分我们就要把它交给memmove函数去处理。
二、memmove函数
2.1memmove函数定义
2.2memmove模拟思路
因为没有重叠部分的话我们完全可以用memcpy函数实现,而memmove主要是用来处理有重叠部分的情况,所以我们的设计思路如下:
如上图红色的图,将1,2,3,4,5要拷贝到3,4,5,6,7这个时候我们应该从拷贝的部分从后往前拷贝,这样才可以保证拷贝的部分还是之前的部分,如果从前向后我们把1给了3,2给了4,之前的3已经变成了1有拷贝到5,就会发生错误。
上图绿色的图,想把4,5,6,7,8拷贝到1,2,3,4,5这个时候就要从前向后拷贝,4给1,5给2依次类推。
我们发现有时需要从后向前拷贝,有时候需要从前向后拷贝,我们总结规律如下:
情况一:
如果目的地址在原地址之前并且有重叠部分我们从前向后拷贝。
情况二:
如果目的地址在原地址之后并且有重叠部分我们选择从后向前拷贝。
情况三:
如果目的地址和原地址没有重叠部分,什么顺序拷贝都可以。
代码如下(示例):
void* my_memmove(void* dest, void* src, size_t num)
{
void* ret = dest;
assert(dest);
assert(src);
if (dest < src)//1 前->后
{
while(num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else //2 3 后->前
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main()
{
int arr1[] = {
1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+2, arr1, 20);
return 0;
}
memcpy只需要实现不重叠的拷贝就可以了 。
memmove是需要实现重叠内存的拷贝的。
总结
本篇博客主要涉及了memcpy函数(没有重叠部分的内存拷贝)的使用和模拟函数,以及memmove函数(有重叠部分的内存拷贝)的使用和模拟,希望对大家有所帮助,我们明天见~