C之内存函数

一.memcpy

了解一个函数,从参数开始。观察官方给出的memcpy函数定义,参数一个一个来看,void* destination是目的地,是copy拷贝的目的地地址,是将内容拷贝到此处,而后const void* source是源头,const修饰保证源头不被修改保证安全性,拷贝的内容就从这个地址开始,当然拷贝不可能是无限制的,而后的size_t类型的num就是拷贝的字节个数,返回类型void*返回的目的地地址,便于使用者使用拷贝后的内容。

 随后就是实际运用该函数了,在使用该函数前应包含头文件<string.h>,该函数以字节为单位进行拷贝,如果我们要拷贝4个int整形,那么就需要拷贝16的字节(一个int类型4个字节)于是我们可以如下使用。

 知道了用法后,可以尝试进行自己实现该函数功能,创建my_memcpy函数来加深自己的理解。实现该函数的关键在于找出一个字节的内容进行拷贝,那么什么类型是一个字节的呢?没错,char类型,于是将void*强制转化为char*再解引用就能实现一个字节的拷贝了。实现如下。

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);//检验指针是否为空,需要包含头文件<assert.h>
	void* ret = dest;//返回目的地地址
	while (num--)//循环执行num次,即拷贝num个字节
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

	return ret;
}

memcpy函数固然好用,但存在一个缺陷,该函数在destination和source有任何重叠的时候可能无法生效,于是我们就要使用加强版——memmove 

二.memmove 

可以看见,memmove和memcpy在参数上是一模一样的,这里不在过多赘述。比较一下相同的数组arr1和arr2在拷贝20个字节的情况下有何不同?可以看见memcpy似乎是对同一个数组一个一个字节顺序进行拷贝,需要拷贝重叠区段arr1[2]时使用的是改变后的值,而memmove似乎拷贝的是改变前数组的值,难道memmove的实现原理是复制了一个相同数组再进行拷贝?

 其实也许没这么麻烦,如以上的情况,转换一下思路,从后往前拷贝不就能避免这种错误了吗?不过一直从后往前拷贝就能彻底解决重叠区段的问题了吗?反问自己,想问题要全面仔细,作者思考了以下两种情况:

从图中就算一个一个来试,也能很容易试出,得出以下结论:1.dest在src之前,从前往后拷贝。2.dest在src之后 ,从后往前拷贝。如此便能实现在重复区段下的拷贝,实现库函数memmove的效果。自己实现的代码如下:

void* my_memmove(void* dest,const void* src,size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest > src)//dest在src前
	{
		while (num--)
		{
			*((char*)dest + num ) = *((char*)src + num );
		}
	}
	else//dest在src后
	{
		while (num--)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	return ret;
}

三.memset

 

memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。注意是以字节为单位,可参数中是int类型的value的的值,因此只能取value后的8位(1字节)为有效值进行设置。当然,我们也可以直接使用一字节的字符类型进行设置,如下:

int main()
{
	char arr[] = "Hello world";
	memset(arr, 'A', 5);
	printf("%s\n", arr);
	return 0;
}
//输出结果就是“AAAAA world”


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值