首先我们来了解memmove函数和memcpy函数的使用
memmove函数
他的函数所需参数如下
1.函数memcpy从source的位置开始向后复制num个字节的数据destination 指向的内存位置。
2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
3.如果source和destination有任何的重叠,复制的结果都是未定义的
void * memcpy ( void * destination, const void * source, size_t num );
我们要注意,这里的num是以字节为单位的,而不是元素个数,并且由于这里我们不知道memmove所移动的内容是什么数据类型,所以移动的目的和源头都用void来定义,由于memmove函数还需有返回目的的起始地址,所以函数类型定义为void**。
下面我们就可以对memmove函数进行模拟实现
我们定义此模拟实现函数为my_memmove
我们定义数组
arr[]={1,2,3,4,5,6,7}
我们想要将数组中数字3,4,5放入1,2,3的位置中,也就是说src中的内容从前向后移动到det中,反之,如果采用从后向前将不会达到我们想要的下图的数组,移动后的数组内容如下图所示
我们将数组移动的内容进行分析,此时det在src的前面,我们可以先将数字3放入arr[0],然后一次放入4,5
下面来看另外一种情况,就是如果det在src的后面呢,该如何移动呢
这个时候我们就会发现从前向后的方法并不适用与这种情况了,我们可以采用从后向前的方式,若依旧采用从前向后的方式的话,会是这种效果
这个时候我们就可以开始构思函数了
由于函数最终需要返回det的起始地址,所以我们定义一个void* ret=det
放入函数中,并且采用断言保证不为空指针
void my_memmove(void* det, void* src, size_t size) { assert(det && src); void* ret = det; }
接下来分析当det在src前面是的移动方式
由于不知道数据的类型,并且size的单位是字节,但是当数据的类型是int的时候,循环进行是该如何移动呢,我们就可以将det的指针类型强制转化为char*指针,就可以进行字节“++”操作了
if (det < src)//从前往后移动 { int i = 0; for (i = 0; i < size; i++) { *(char*)det = *(char*)src;//强制类型转换 arr1 = (char*)det + 1; arr2 = (char*)src + 1; }
反之,我们就写出det在src之后的部分
while (size--) { *((char*)det + size) = *((char*)src + size); }
到这里,memmove的模拟实现就完成了,我们还要记得返回ret,也就是det的起始地址
完整函数代码如下
void my_memmove(void* det, void* src, size_t size) { assert(det && src); void* ret = det; if (det < src)//从前往后移动 { int i = 0; for (i = 0; i < size; i++) { *(char*)det = *(char*)src; arr1 = (char*)det + 1; arr2 = (char*)src + 1; } } else { while (size--) { *((char*)det + size) = *((char*)src + size); } } return ret; }
memcpy函数
相对于memmove函数,memcpy的功能就没有怎么完整了,memmove和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的,所以,如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。但是,有一些编译器的memcpy也可以处理重叠的的情况,就比如vs。
memcpy的模拟实现和memmove的差别不大
代码如下
void * memcpy ( void * det, const void * src, size_t size) { void * ret = det; assert(arr1 && arr2); while (size--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return(ret); }
大家可以发现,memcpy函数的模拟实现就是memmove函数模拟实现的一部分,就是只采用了从前向后的方式进行内存更改,所以这里我就不做过多的解释了,大家自行理解。
好了,今天的分享就到这里了!