大家好,这篇文章主要是为大家做一些两个函数的模拟实现,在开始之前若不认识这两个函数可以去cplusplus了解一下再来继续阅读本篇文章。
首先我们写一个平平无奇的主函数
int main()
{
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
int brr[20] = { 0 };
my_momcpy(brr, arr, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", brr[i]);
}
return 0;
}
在我们写函数之前,看图
因为这个函数实现的是对所有类型的copy操作
所以我们在不确定是那种类型数据是可以使用void*来实现
void my_momcpy(void* a, void* b, size_t n)
已知a目的地,b源头,c要复制的地址大小
那么首先排除a,b为空的情况
assert(a);
assert(b);
那么我们现在需要处理的就是怎么把b里面的内容放到a里面
ab都是void*类型的直接进行赋值操作是不被允许的
那么就可以对他进行强制转换,那我们如何结束呢?
我们可以看见还有一个参数n他代表着要复制过去地址大小
那么综合起来
while (n--)
{
*(char*)a = *(char*)b;
}
我们再加一点点点缀让他后移
while (n--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
将a强制转换为char*类型加一使它指向后面的地址
现在我们来运行试一下
可以看见这就是我们想要的结果
但是细心一点你可能发现了,我们的函数与原版还差了一笔
函数类型是void*,而我所写的类型是void
那么让我们稍作修改
void* my_momcpy(void* a, void* b, size_t n)
{
void* c = a;
assert(a);
assert(b);
while (n--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
return c;
}
memcpy就已经写完了
下面让我们再来看memmove
其实两个函数的不同就在于memmove是在可能重叠的位置进行复制
那么我们就需要考虑两个空间前后的问题
第一种情况,目的地在源除之前,那么如果我们从前往后复制的话,没有很大的问题,但是我们并不确定那个在前面那个在后面,所以如果要从前到后复制就需要加上一个判断条件才能进行操作
if (a < b)
{
while (n--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
}
这样在我们确定的情况下我们才能进行从前到后的操作
第二种情况就是,目的地在源地之后,如果我们此时进行了从前往后的操作,那么图中4,5两个数字就会被覆盖出现问题,这就是为什么上一种情况加上一个判断的原因,既然已经判断过,那么从后向前的代码就比较简单了
while (n--)
{
*((char*)a + n) = *((char*)b + n);
}
第三种情况就是源地址与目的地没有接触,那么前后操作就没有什么区别了
下面让我们看看全部的代码
void* my_momove(void* a, void* b, size_t n)
{
void* c = a;
assert(a);
assert(b);
if (a < b)
{
while (n--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
}
else
{
while (n--)
{
*((char*)a + n) = *((char*)b + n);
}
}
return c;
}
int main()
{
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
my_momove(arr+2, arr, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
return 0;
}
我们如期得到了自己想要的结果
好了本篇文章到这里就结束了,谢谢大家的支持,如果文章内容有所不对欢迎大家指出改正。