一、memcpy函数
上一篇博客我们已经实现了 strcpy函数,有同学可能会问已经有了 strcpy 函数,为什么还要有memcp函数呢? 其实strcpy函数他只能操作字符串,对其他类型它是没有办法操作的,比如 int arr[5] = {1, 2, 3, 4, 5}像这个整型数组strcpy函数是不能进行操作的,只能运用memcpy函数,下面我们先看一下memcpy函数:
可以看到它的形参有三个 目标空间地址void* dest, 数据来源的地址const void*src,以及需要拷贝的字节数 size_t count 。因为我们不知道需要拷贝的数据是什么类型,那么为了它的通用性所以用来接受地址的指针都是void*。需要注意的是:
1. 函数memcpy从src的位置开始向后复制count个字节的数据到dest的内存位置
2.这个函数在遇到'\0'时不会停止
3. 如果src 和dest 有任何的从叠,复制的结果都是无效的。
先来看一个memcpy函数的应用:
下面我们来实现这个函数:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;//无类型指针不能进行解引用操作(不确定访问几个字节)
//也不能进行 + -整数操作,所以要先进行强制类型转换
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[20] = { 1, 2, 3, 4 };
int arr2[] = { 7, 8 ,9, 10, 11, 12, 45, 56, 89 };
my_memcpy(arr1, arr2, 36);
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
我们刚刚讲了src和dest有重叠的部分,复制的结果是无效的,那么我们试一试
int main()
{
int arr1[20] = { 1, 2, 3, 4 };
my_memcpy(arr1+2, arr1, 14);
return 0;
}
这个代码的意思是将 1 2 3 4复制到从arr1[2]开始的四个数字,我们想要的结果应该是1 2 1 2 3 4;
但结果并不是这样,而是1 2 1 2 1 2。
为什么会这样呢?
其实你在将arr1[0]复制到arr[2]后,arr1[2]就变成了arr1[0]的值原来的值已经被覆盖掉了,你在将arr1[2]的值往后复制其实就是复制的arr1[0]的值,所以结果才会错误。为了解决这个问题就有了下面的函数memmove
二、memmove函数
我们先来看一下这个函数:
可以看到形参和memcpy函数相同,但是功能确是不同,它主要来处理目标空间和源空间出现重叠的情况;还是刚才的代码,把memcpy改成memmove我们看一下结果 :
这样结果就对了。
那么它是怎样实现的呢?其实它的实现分3种情况:
1. dest 在 src前(dest小于src)
这种情况下,我们采用从前端开始复制,即从后往后开始,先将4复制到1的位置,以此类推,这样的话在4被覆盖之前我们已经复制过了,也就不会影响结果。
2. dest 在 src后,(dest大于scr)
在种情况下我们采用从src的后端开始复制,即从后往前复制,先将4复制到6的位置,接着3复制到5的位置,以此类推。同样的在4被覆盖之前已经复制过了,当然也就不会影响结果;
3.当两者没有交集的时候,以上两种方式后可以。
代码实现:
#include
#include
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest && src);
//从前向后
void* ret = dest;
if (dest < src)
{
while (count--)
{
*(char*)dest = *(char*)src; //无类型指针不能进行解引用操作(不确定访问几个字节)
//也不能进行 + -整数操作,所以要先进行强制类型转换
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
//从后向前
else
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr1[20] = { 1, 2, 3, 4 };
my_memmove(arr1+2, arr1, 14);
int i = 0;
for (i = 0; i < 6; i++)
{
printf("%d ",arr1[i]);
}
return 0;
}
本篇博客到这就算结束了!感谢大家的观看,如果有错误请各位前辈指正!!!感激不尽