您的位置:首页 > 编程语言 > C语言/C++

用C语言模拟实现memcpy函数,memmove函数和memset函数

2017-11-01 18:11 465 查看
模拟实现memcpy函数:
函数原型:void *memcpy (void *p,void *m, size_t num);
memcpy与strcpy相比,memcpy函数用来做内存拷贝,可以用它拷贝任何数据类型的对象,并且可以指定拷贝的数据长度。stycpy函数也是用来做内存拷贝,并且只能拷贝字符串类型的数据。memcpy并不是遇到"\0"就结束,而是一定会拷贝完num个字节。而strcpy 遇到"\0"就结束。
memcpy函数代码:
#include <stdio.h>
#include <assert.h>
void my_memcpy(void *p,const void *m,size_t num)
{
char *str1 = (char *)p;
const char *str2 = (const char *)m;
assert(p);
assert(m);
while(num)
{
*str1=*str2;
str1++;
str2++;
num--;
}
}
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9};
int i;
my_memcpy(arr,arr+3,sizeof(int)*5);
for(i=0;i<9;i++)
{
printf("%d",arr[i]);
}
return 0;
}
memcpy可以拷贝任何数据类型的对象,比如,上段代码中用memcpy实现了拷贝int 型的数组,用memcpy实现数组的拷贝只能是后面的拷贝前面的,上面代码中从数组的arr+3向arr拷贝,在main函数中存入形参(arr,arr+3,sizeof(int)*5),在调用函数中用void型的指针接收(void *p,const void* m,size_t num),void可以指向任何类型的指针,但是由于复制的时候要一个个字节去复制,所以我们需要把void转换成char类型,然后char类型的两个指针进行拷贝,指针地址加加。

模拟实现memmove函数;
memmove和memcpy函数都是C语言中的库函数,作用是拷贝一定长度的内存的内容,它们的作用是一样的,唯一的区别就是当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果是正确的。

memmove函数代码:
#include <stdio.h>
#include <assert.h>

void my_memmove(void *p,const void *m,size_t num)
{
char *str1 = (char *)p;
const char *str2 = (const char *)m;
assert(p);
assert(m);
if (str1>str2 && str1 < str2+num)
{
while (num--)
{
*(str1+num) = *(str2+num);
}
}
else
{
while(num)
{
*str1=*str2;
str1++;
str2++;
num--;
}
}
}

int main()
{
int arr[]={1,2,3,4,5,6,7,8,9};
int i;
//my_memmove(arr,arr+3,sizeof(int)*5);
my_memmove(arr+3,arr+1,sizeof(int)*5);
for(i=0;i<9;i++)
{
printf("%d",arr[i]);
}
return 0;
}
memmove分两种情况一种是拷贝时内存内部没有发生局部重叠的时候,它的拷贝方式跟memcpy是相同的,另一种是内存内部发生局部重叠时,相当于(str1>str2&&str1<str2+num),用memmove拷贝实现从最后一个往前拷贝,保证了结果的正确性。

模拟实现memset函数:
函数原型是:void *memset(void *src,int num,size_t len);

memset函数通常用来对一块已经分配地址的内存进行初始化,并且通常初始化为0.
#include <stdio.h>
#include <string.h>
void my_memset (void *src,int num,size_t len)
{
char *ptr=(char*)src;
while(len--)
{
*ptr=((char*)num);
ptr++;
}
}

int main()
{
int arr[10];
int i;
my_memset(arr,0,5*sizeof(int));
for (i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
一定需要注意的是,memset是按照字节对初始化空间进行初始化的,也就是说,函数里面的第二个参数的那个初值是按照一个一个字节往第一个参数所指区域赋值的,所以对于单字节数据类型(char)可以初始化为任何值,但对于非但字节数据类型只能初始化为0.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息