第一个参数为目标地址,第二个参数是源地址,第三个参数是要拷贝的字节大小。
这个函数拷贝相对于strcpy函数来说不仅限于对字符串的拷贝。
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9 };
int arr2[10] = { 0 };
memcpy(arr2, arr1,20);
}
#include
void my_memcpy(void* dest, const void* src, size_t num)//为什么参数类型是void?
{
while (num--)
{
*(char*)dest = *(char*)src;//为什么要强转为char指针类型?
dest = (char*)dest + 1;//为什么(char*)dest++是错误的?
src = (char*)src + 1;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 20);
return 0;
}
以上模拟的memcpy当在拷贝自身数值时可能会出错
拷贝自身时有三种情况一种是源地址在目标地址的后面,一种是源地址和目标地址位置相同,一种是源地址在目标地址的前面
我们可以将它分为两种情况一种是源地址在目标地址前面时我们按照从前向后拷贝,一种是源地址在目标地址后面或相同时我们按照从后向前拷贝,为的是避免在拷贝过程中有的数据被覆盖掉。
#include
void my_memcpy(void* dest, const void* src, size_t num)//为什么参数类型是void?
{
void* ret = dest;
if (src >= dest)
{
//从前向后拷贝
while (num--)
{
*(char*)dest = *(char*)src;//为什么要强转为char指针类型?
dest = (char*)dest + 1;//为什么(char*)dest++是错误的?
src = (char*)src + 1;
}
}
else
{
//从后向前拷贝
while (num--)
{
/**(char*)dest + num = *(char*)src + num;*///这样写是错误的
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
不同编译器拷贝的结果不同,所以对自身进行拷贝时尽量使用memmove函数来进行拷贝
第一个参数为目标地址,第二个参数是源地址,第三个参数是要拷贝的字节大小。
memmove可以实现重叠内存的拷贝
#include
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
memmove(arr2, arr2 + 2, 20);
return 0;
}