提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
一、memmove是什么?
二、memmove使用步骤
1.引入库
2.输出结果:
三、my_memmove实现
3.1思路分析
3.2代码实现
3.3 结果复现
总结
前言
提示:这里可以添加本文要记录的大概内容:
本文仔细介绍一下,最近学习的内存函数memmove函数的实现过程和实际my_memmove的具体实现代码,学了些知识点,还是想记录一下并和大家分享!
一、memmove是什么?
? ? ? ?memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
原型:void *memmove( void* dest, const void* src, size_t count );
头文件:<string.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
二、memmove使用步骤
1.引入库
代码如下:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
?? ?int arr[] = { 1,2,3,4,5,6,7,8,9,10};
?? ?memmove(arr + 2, arr, 20);
?? ?for (int i = 0; i < 10; i++)
?? ?{
?? ??? ?printf("%d ", arr[i]);
?? ?}
?? ?return 0;
}
2.输出结果:
1 2 1 2 3 4 5 8 9 10
从上面的代码执行结果,我们可以看出来:是把原来的1 2 3 4四个整型(20个字节)拿起来放到了原来的3 4 5 6的位置,所以最后的结果是:1 2 1 2 3 4 5 8 9 10,但是这个结果是有缺陷的,没有考虑将原来的值先进行保留就直接粘贴上去了。
三、my_memmove实现
3.1思路分析
这里要分成两种情况来进行讨论:
第一种情况: dest > src
通过该函数的使用参数,我们可以知道,需要知道相应的:dest、src和size_t num一共三个参数的大小才能调用参数:
?上面的第一幅图是原来的顺序:src的四个数字是:3 4 5 6 要将其移动到dest的位置,移动后的位置后,其具体的形式图如下所示:3 4 5 6 5 6 7 8 9 10? 对于当dest的位置在src的前面是这种移动的形式是符合要求的!
//从前向后
while (count--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
第二种情况是:当dest<src时,或者说是 dest要移动的位置在src(src+count)的位置后面时:
其相应的图像如下所示:
?在上面的图里面,我们可以看到如果从前面进行相应的移动时,则会导致参数6 还未在移动时便被覆盖住了,就会产生错误的答案:1 2 3 4 5 3 4 5 3 10 其中,最后面的一个3是一个错误的参数,正确的参数应该如图上所示:1 2 3 4 5 3 4 5 6 10,这是改变了移动的顺序,将从前向后的移动改成了从后向前的移动:原本的移动顺序应该是 3 4 5 6 我们现在变换下位置改成了 6 5 4 3这样就很好的避免了这个问题。
//从后向前拷贝
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
3.2代码实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t count)
{
void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
/*if (dest<src || dest>(char*)src + count)
{
}*/
if (dest < src)
{
//从前向后
while (count--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else
{
//从后向前拷贝
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr3[] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(arr3, arr3+2, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr3[i]);
}
return 0;
}
3.3 结果复现
1 2 1 2 3 4 5 8 9 10
上面的代码块,跑出来后的结果是1 2 1 2 3 4 5?8 9 10 !
总结:
? 以上就是memmov函数和实现my_memmove的讲解和应用,在实现my_memmove的时要注意dest和src位置的比较,这里一定要注意,不然全部都应用从前面向后面复制的形式,则会导致错误,今天分享就到这里!
|