内存操作函数(memcpy,memmove,memset)

前言:

C 语言中对字符和字符串的处理很是频繁,但是 C 语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数。

memcpy

函数 memcpy source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。 这个函数在遇到 '\0' 的时候并不会停下来。 如果source destination 有任何的重叠,复制的结果都是未定义的。
void *my_memcpy(void *dest,const void *src,size_t count)
{
	assert(dest!=NULL && src!=NULL);
	char *p = (char*)dest;
	char *q = (char*)src;
	while (count--)
	{
		*p = *q;
		p++;
		q++;

	}
	return dest;
}

memcpy和strcpy的区别:strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。strcpy复制如下图所示:

memcpy复制如下图所示:

 memmove

void *my_memmove(void *dest, const void *src, size_t count)
memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。 如果源空间和目标空间出现重叠,就得使用memmove 函数处理。
例如对于一个数组arr[]={1,2,3,4,5,6,7,8,9,10},要把1,2,3,4复制arr+2上去,正确的结果是1,2,1,2,3,4,7,8,9,10,但是用 memcpy他的结果如下图所示:1,2,1,2,1,2,7,8,9,10.出现了重叠部分,未能得到理想结果。

 具体原因是把1,2,3,4,5,6,7,8,9,10中前四个数1,2,3,4复制到中间的3,4,5,6的位置时,1替换3,2替换4,3替换5,4替换6,但是此时的3不再是3而是1,4不再是4而是2,被新值覆盖。所以此时从前往后赋值不行,应该从后往前赋值。memmove则是这样实现的。

但是问题是什么时候从前往后赋值,什么时候从后往前赋值?

同样以arr[]={1,2,3,4,5,6,7,8,9,10}为例。

我们想把3,4,5,6赋值到dest的空间里面去,为了不重复覆盖,当dest在3之前时,应该从前到后赋值,当dest在3-6之间时,从后往前赋值,6之后,从前可前往后,后往前赋值。

 memmove自实现:根据上面的分析可以分两种情况分别赋值,当dest在3-6的时候从后往前赋值,当dest不在3-6这个范围的时候,统一从前往后赋值。

void *my_memmove(void *dest, const void *src, size_t count)
{
	assert(dest != NULL&&src != NULL);
	char *des = dest;
	if ((dest>src)&&dest<((char*)src+count))
	{
		while (count--)//后向前
		{
			*((char*)des + count) = *((char*)src + count);
		}
	}
	else
	{
		while (count--)//前向后
		{
			*(char *)des = *(char *)src;
			dest = (char *)des + 1;
			src = (char*)src + 1;
		}
	}
	return dest;


}

memset

void *memset(void *dest,int c,size_t count)

内存设置函数,把目标函数count字节设置为c,例如:

int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    my_memest(arr, 0, 16);
    return 0;
}

 memset自实现:

void *my_memest(void *dest,int c,size_t count)//内存初始化
{
	for (int i = 0; i < count;i++)
	{
		((char*)dest)[i] = c;
	}
	return dest;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值