memcpy函数说明: msdn 中对该函数的函数原型和返回值的描述为:
函数原型:void *memcpy( void *dest, const void *src, size_t count );
返回值: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 函数不仅可以处理字符串,还能处理数组。