目录
一、memcpy
1、函数声明
void * memcpy ( void * destination, const void * source, size_t num );
其中的参数分别是:
destination——目的地,
source——源头,
num——要复制的字节数(size_t是无符号整型)。
2、功能
从上面的参数,我们也可以想到,这是个内存拷贝的函数,将数字字节的值从源头指向的位置直接复制到目标所指向的内训块。
3、举例
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
int sz = sizeof(arr1) / sizeof(arr1[0]);
memcpy(arr2, arr1, sizeof(int) * sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr2[i]);//输出结果为1——10
}
return 0;
}
4、模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现memcpy
void* my_memcpy(void* str1, const void* str2, size_t num)
{
assert(str1 && str2);
char* str = str1;
while (num--)
{
(*(char*)str1) = (*(char*)str2);
/*((char*)str1)++;
((char*)str2)++;*/
//有些编译器跑不过去
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
return str;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
int sz = sizeof(arr1) / sizeof(arr1[0]);
my_memcpy(arr2, arr1, sizeof(int) * sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
但是如果我们想把arr1中的前3个元素,即1,2,3拷贝到3,4,5的位置上去,就会出现不一样的结果,我们用调试的方式来看一看。
这里我们还没执行my_memcpy,再按一次F10,走!
数组里的内容变了,但是不是我们想要的结果,这是为什么呢?
那有没有一个函数能做到拷贝重叠内存块呢?
这里我们就扯到了memmove函数了。
二、memmove
1、函数声明
void * memmove ( void * destination, const void * source, size_t num );
2、功能
其实它的功能和memcpy差不多,区别就是在于memcpy不可以拷贝重叠的内存块,而memmove可以。
3、举例
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr + 2, arr, sizeof(int) * 3);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);//输出结果1 2 1 2 3 6 7 8 9 10
}
return 0;
}
4、模拟实现
实现思路:
可以理解为memmove是memcpy的plus版本,所以我们只需要在memcpy的基础上加一个能拷贝重叠内存块的功能。
我们把重叠部分的拷贝分为3种情况:
1、如果目的地在源头的后面
所以,当目的地在源头的后面时,从后面开始拷贝。
2、如果目的地和源头的地址相同,则不需要考虑。
3、如果目的地在源头的前面
所以, 如果目的地在源头的前面时,从前面开始拷贝。
这样我们就可以理解为当目的地在源头的后面时,从后面开始拷贝,当目的地在源头的前面或者目的地和源头的位置相同时,从前面开始拷贝。
思路有了,开始写代码:
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* my_memmove(void* str1, void* str2, size_t num)
{
void* ret = str1;
assert(str1 && str2);
if (str1 < str2)
{
while (num--)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
}
else
{
while (num--)
{
*((char*)str1 + num) = *((char*)str2 + num);
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1 + 3, arr1, sizeof(int) * 5);
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}