目录
1.为什么要引入内存操作函数
2.memcpy函数的功能并模拟
3.memmove函数的功能并模拟
问题:我们知道字符串操作函数strlen,strcat,strcpy,strcmp,strncat,strncpy,strstr等等,但这些字符串函数只是针对字符串的,如果遇到整形数组呢?结构体数组呢?浮点型数组呢?好像就没有具体类型来说明了。
解决:如果要把一个arr1[]={1,2,3,4,5,6,7,8,9,10}的1,2,3,4,5拷贝到arr2[20]={0}中去,字符串操作函数strcpy是没办法完成的,因此可以使用内存操作函数memcpy把它当作内存块空间移到arr2数组中来解决这个问题。
函数原型
函数功能:将src所指向的内容拷贝到dest所指的空间里区,但拷贝的多少是由count决定的。
代码如图
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
memcpy(arr2, arr1, 20);
int sz = sizeof(arr2) / sizeof(arr2[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
//运行结果 1 2 3 4 5
函数模拟实现思路
代码实现
#include
#include
char* my_memcpy(void* dest, const void* src, size_t count)
{
//因为要对指针解引用,而空指针是不能解引用
//为了保证指针有效性,需要对dest和src断言
assert(dest && src);
void* ret = dest;//保存目标空间的起始地址
while (count--)//字节数
{
*(char*)dest = *(char*)src;//源头数据拷贝到目标空间里
dest = (char*)dest + 1;//转化为char*地址+1
src = (char*)src + 1;//转化为char*地址+1
}
return ret;//返回目标空间的起始地址
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9 };
int arr2[5] = { 0 };
my_memcpy(arr2, arr1, 20);
//arr2的打印
int sz = sizeof(arr2) / sizeof(arr2[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
问题:如果要在同一个数组里面对进行拷贝,memcpy是实现不了的,假设要把arr1里的1 2 3 4 5拷贝到3 4 5 6 7的位置,就会出现一下结果
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9 ,10};
memcpy(arr1 + 2, arr1, 20);
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
原因:
上述问题需要用函数memmove来解决
函数原型
函数功能:可以实现同一块内存空间重叠内容的拷贝
代码如图
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9 ,10 };
memmove(arr1 + 2, arr1, 20);
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
//打印 1 2 1 2 3 4 5 8 9 10
函数模拟思路
代码实现(这里选简单理解的思路1)
#include
#include
void* my_memmove(void* dest, const void*src, size_t count)
{
//因为要对指针解引用,而空指针是不能解引用
//为了保证指针有效性,需要对dest和src断言
assert(dest && src);
void* ret = dest;///保存目标空间的起始地址
//1
if (dest < src)
{
//前->后
while (count--)
{
*(char*)dest = *(char*)(src);//源头数据拷贝到目标空间里
dest = (char*)dest + 1;//转化为char*地址+1
src = (char*)src + 1;转化为char*地址+1
}
}
else
{
//后->前
while (count--)
{ //count是字节数,从源头数据的末尾开始拷贝到目标空间的末尾
//逐个向前拷贝
*((char*)dest+count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
// 1 2 1 2 3 4 5 8 9 10
//my_memmove(arr1+2, arr1, 20);//可以实现重叠内存的拷贝
my_memmove(arr1, arr1+2, 20);//可以实现重叠内存的拷贝
int i = 0;
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
以上是关于memcpy函数和memmove函数的介绍和模拟实现,如果有什么需要改进的地方,希望大家指出,创作不易,我们共同进步。