memcpy:
第一步:了解memcpy:
memcpy(数组a,数组b,多少个字符c)
就是将数组b中的第一个元素开始,向后数的c个字符与数组a的第一个元素开始向后数c个字符进行替换。
一个例子:
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8 };
int brr[30] = { 0,2,8 };
memcpy(brr, arr, 2 * sizeof(arr[0]));
for (int i = 0; i < 20; i++)
{
printf("%d ", brr[i]);
}
return 0;
}
我们就可以看到arr数组的第一个和第二个元素1,2替换了brr数组中的第一个元素和第二个元素,同时这里的2*sizeof(arr【0】)可以直接写成8,一个int=4,替换两个就是8,也可以像我一样写成2*sizeof(arr【0】);
第二个例子:
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8 };
int brr[30] = { 0,2,8,9,5 };
memcpy(brr+1, arr+2, 2 * sizeof(arr[0]));
for (int i = 0; i < 20; i++)
{
printf("%d ", brr[i]);
}
return 0;
}
我第二个例子就修改了brr+1,与arr+2,意思就是将从arr+2开始的2*sizeof(arr【0】)个元素(就是arr【2】开始)替换给brr+1(brr【1】)开始的2*sizeof(arr【0】)个元素
模拟实现memcpy:
void* mymemcpy(void* a, const void* b, int width)
我们作为memcpy的作者,不知道使用者会拿什么类型进行替换,所以a数组与b数组都是void*类型,而b数组不用改变,所以为了安全加上const修饰,最后加上一个宽度int width
因为返回void*所以我们首先讲a数组的首地址存储,然后为了安全加上assert函数
void* res = a;
assert(a && b);
因为最少单位是char,所以替换,我们强制转换到最小char类型,然后一个字节一个字节替换
while (width--)
{
*(char*)a = *(char*)b;
a = (char*)a+1;
b = (char*)b+1;
}
总代码:
#include<assert.h>
void* mymemcpy(void* a, const void* b, int width)
{
void* res = a;
assert(a && b);
while (width--)
{
*(char*)a = *(char*)b;
a = (char*)a+1;
b = (char*)b+1;
}
return res;
}
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8 };
int brr[30] = { 0,2,8,9,5 };
mymemcpy(brr+1, arr+2, 2 * sizeof(arr[0]));
for (int i = 0; i < 20; i++)
{
printf("%d ", brr[i]);
}
return 0;
}
模拟实现memmove:
因为memmove的原理和memcpy的原理一模一样,区别就在于,memmove能够替换重复而memcpy不能,所以我这里直接模拟实现memmove。
如果a数组的地址小于b数组的地址,那么memmove和memcpy一模一样,我这里就讲一下a数组的地址大于b数组的地址的情况,如图↓
我们可以看见b数组和a数组有一个交集,我们运行时,b数组的‘4’就会替换a数组中的‘1’;
然后我们就会发现,这时候原本应该拿b数组的‘1’去替换a数组的‘2’,变成了‘4’去替换‘2’。
这就出问题了,所以
while (width--)
{
*((char*)a + width) = *((char*)b + width);
}
我们这里还是强制转换为char类型,当width进来的时候,作为字符他已经减了1,
所以*((char*a)+width)表示的是
a数组中倒数第一个字符的位置和b数组倒数第一个字符的位置交换
总代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* mymemmove(void* a, const void* b, int width)
{
assert(a && b);
void* res = a;
if (a < b)
{
while (width--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
}
else
{
while (width--)
{
*((char*)a + width) = *((char*)b + width);
}
}
return res;
}