1.memcpy
该函数作用类似于strcpy,函数声明如下
从source地址拷贝num个字节的数据到destination地址处,这个函数强大之处在于不限制数据类型,可以是整型,浮点型,也可以是结构体。
#include<string.h>
#include<stdio.h>
int main()
{
char dest[] = "abcd";
char src[] = "efg";
memcpy(dest, src, 2);
printf("%s",dest);
return 0;
}
用法如上。 结果是

但是这个库函数,在C语言该函数是处理两块内存空间没有重合的情况,也就是说
memcpy(p+1,p,4);
像这种用法尽量避免。但是也许在你的编译器上他是可以正常运行,这个可能是因为你所使用的编译器对其进行了优化。
2.memmove

memmove基本与memcpy相同,但是可以处理重合的内存区域。
#include<string.h>
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+3, arr1, 20);
for (int i = 0; i < 10; i++)
printf("%d ", arr1[i]);
return 0;
}
这段代码就可以正常被处理,而如果使用memcpy是有可能会出错的。

3.memmove模拟实现
我们可以尝试自己用代码实现类memmove函数,效果与memmove一样。
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, size_t num);
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+3, arr1, 20);
for (int i = 0; i < 10; i++)
printf("%d ", arr1[i]);
return 0;
}
刚开始我们可能会想,直接用俩指针遍历就完事了,可能会这么写
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);//assert断言是为了不使用空指针
void* tmp = dest;
for (int i = 0; i < num; i++)
{
*((char*)dest)++ = *((char*)src)++;
}
return tmp;
}
运行结果会发现有错误

这是因为当1,2,3复制过去后,原来的4,5就被1,2覆盖了,因此接着向后复制就会重复拷贝1,2。
可以从后向前拷贝,把4,5,6,7,8向后赋值,就可以避免。
于是可以将代码完善
void* my_memmove(void* dest, void* src, size_t num)
{
assert(dest && src);
void* tmp = dest;
if (dest < src)
{
while (num--)
{
*((char*)dest)++ = *((char*)src)++;
}
return tmp;
}
else if (dest > src)
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
return tmp;
}
else
return tmp;
}
结果正确

1652

被折叠的 条评论
为什么被折叠?



