一.内存函数是什么
二.
1.memcpy的相关知识
memcpy的实现
2.memmove的相关知识
memmove的实现
在学习C语言时,很多时候都会需要使用内存函数, 接下来就让我们先来了解一下内存函数。
一.内存函数
内存函数是通过访问地址的方式操作对象,可应用于任何类型的对象。
二.
1.memcpy函数
1.函数从源指针指向的位置,向后拷贝n个字节到目标指针所指向的内存块中
2.源指针和目标指针的基础类型可以任意(因为该函数的参数为void类型)
3.遇到’\0’并不会停下来,他始终复制精准字节(即n个字节)
4.目标和原参数所指向的数组的大小应大于等于n个字节,且不能重叠(重叠的情况应使用memmove函数,接下来会讲到)
memcpy的模拟实现
思路
1.从原函数中一个字节一个字节的拷贝(注意是一个字节),因此指针应强制转化为char类型
2.因为memcpy的返回值是要求返回,目的函数的起始位置的地址,所以我们应该
在一开始时用一个同类型void的指针来存放该地址
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
void* ret = dest;
assert(dest);//这里的源指针和目的指针都不能为空指针
assert(src);
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
2.memmove
void * memmove ( void * destination, const void * source, size_t num );
memmove和memcpy两个函数的作用差不多,但由上面我们可知,memmove可以处理目的函数的内存块和原函数的内存块重叠的情况
memmove的模拟实现
1.这里也是一个字节一个字节的拷贝,因此也要将指针强制转化为char*类型
2.memmove的返回值和memcpy的返回值是一样的,我们也应该在一开始就用一个同类型的void*类型的指针存放目的函数起始位置的地址
但是在模拟实现的过程中可能会有困难,因为两块内存空间是重叠的。
重叠也有多种情况,这些情况的总结以及解决办法如下:
因此我们总结出当目的指针即dest在1,3区域时,采取从前向后拷贝
当dest在2区域时采取从后向前拷贝
最后的实现代码如下图所示
#include <stdio.h>
#include <string.h>
void* my_memmove(void* dest, void* src, size_t num)
{
void* ret = dest;
if (dest < src)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
else
{
while (num--)
*((char*)dest + num) = *((char*)src + num);
return ret;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+2, arr1, 5);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", arr1[i]);
}
return 0;
}