好久不见,今天也是回到了学校学习,今天我们就继续来更新我们C语言的部分。
我们先来简单解释一下这个函数的参数
函数memcpy从source位置开始向后复制num个字节的数据到destination上面我们看他的两个参数都是void*的,也就是说它可以拷贝任意类型的数据,这就是和strcpy的区别所在,它更加的灵活
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
memcpy(arr2, arr1, sizeof(arr1));
for (int i = 0; i < 20; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
memcpy这个内存函数简单的来说就是可以拷贝任意类型数据的strcpy函数,他们的用法也是及其的相似。
在模拟实现这个函数之前我们需要先理清楚这个函数最核心的问题是什么,我认为这个函数最核心的部分就是可以拷贝任意类型我们模拟实现上面就要从这个特点入手。
void* my_memcpy(void*dest,void*src,size_t num)
{
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
(char)dest = (char)src;这个代码就是最关键的我们无论在拷贝任意数据的时候都强制类型转换为char*类型的这样就可以实现拷贝任意类型。
我们在上面这个代码中可以看出memcpy是不支持重叠的内存拷贝所以这里我们就要介绍一个新的内存函数memmove
这两个的参数是一模一样的,所以这个函数和上面提到的memcpy函数的区别就在于memmove函数处理的目的内存和起始内存是可以重合的。
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
memmove(arr1 + 2, arr1, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
这里我们实现memmove的重点就在于他要怎么进行拷贝的顺序这里我们画个图来方便我们理解。
这里左边的就是我们上边提到的针对这种情况我们要从后向前进行拷贝,而后面这一种就是上面我们提到的模拟实现memcpy中写到的,从上面两种情况我们可以进行一个小小的总结就是目的函数在前就从前向后拷贝,目的函数在后就从后向前拷贝,也就是目的函数在哪就从哪里开始拷贝(这里的哪里指的是目的函数dest和起始函数src的比较,而前后的主语就是src)————进而上面的这一窜分析分装成代码就是
if (dest < src)
{
}
else
{
}
这样的,大概构造了解之后我们就可以开始写代码了。
void* my_memmove(void* dest, void* src, size_t num)
{
void* ret = dest;
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);
}
}
return ret;
}