模拟实现 memcpy memmove 函数

来源:互联网 发布:淘宝讲师 编辑:程序博客网 时间:2024/05/24 04:54

memcpy函数说明: msdn 中对该函数的函数原型和返回值的描述为:

函数原型:void *memcpy( void *dest, const void *src, size_tcount );

返回值:memcpy returns the value of dest.

与 strcpy 不同,该函数该函数可以拷贝任意类型,最典型的它可以实现数组的拷贝;在拷贝时它是以字节为单位进行的,第三个参数串的一定是 N 个字节,该函数能实现很多情形下的拷贝,说到这里,有朋友不禁会问什么情况下就不能了,这个问题下面会解决。根据这里的说明实现该函数的代码如下:

#include<stdio.h>#include<windows.h>#include<string.h>#include<assert.h>void *my_memcpy(void *dest,const void *src,int count){void *ret = dest;  assert(dest);assert(src);while(count--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;}int main(){int i = 0;int arr1[30] ={0};int arr2[10] = {-12,3,3,4,-5,6,7,8,-9,0};int count_1 = sizeof(arr1)/sizeof(arr1[0]);int count_2 = sizeof(arr2);my_memcpy(arr1,arr2,count_2);  //数组拷贝for(;i < count_1;i++){printf("%d ",arr1[i]);}printf("\n");system("pause");return 0;}
在回答上面提出的问题之前,这里先提出一个概念---内存重叠,当上题中的 arr1 在内存中的整体位置比 arr2 在内存中的整体地址高或者低时,这是我们说二者不存在内存重叠问题,这里的高或低对我们函数实现拷贝功能无任何影响;反之,我们已经建立了内存重叠的概念;二者出现内存重叠时,当 arr1 的位置高于 arr2 时,由 memcpy 函数的实现过程中发现此时能完成我们预期的拷贝工作,当 arr1 的位置低于 arr2 时,不难发现用 memcpy 函数处理得不到我们想要的结果,下面的 memmove 函数能弥补该函数在这种情况下的不足。
memmove 函数说明:msdn 中对该函数原型和返回值的描述为:函数原型:void *memmove( void *dest, const void *src, size_t count );返回值:

memmove returns the value of dest.

这个函数能弥补 memcpy 函数的不足是因为她在拷贝开开始前先做了判断,对上述的特殊情况从高地址依次拷贝。根据这里的说明,实现该函数的代码如下:
#include<stdio.h>#include<windows.h>#include<assert.h>void *my_memmove(void *dest,const void *src,int count){void *ret = dest;assert(dest);assert(src);if(dest > src && dest < (char*)src + count){dest = (char*)dest + count - 1;src = (char*)src + count -1;while(count--){*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}else{while(count--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}return ret;}int main(){char dest[20] = {0};char *src = "hello word!";int count = strlen(src) + 1;printf("%s",my_memmove(dest,src,count));system("pause");return 0;}
注: memcpy 和 memmove 函数不仅可以处理字符串,还能处理数组。