C语言内存函数

1.memcpy

该函数作用类似于strcpy,函数声明如下

从source地址拷贝num个字节的数据到destination地址处,这个函数强大之处在于不限制数据类型,可以是整型,浮点型,也可以是结构体。

#include<string.h>
#include<stdio.h>
int main()
{
    char dest[] = "abcd";
    char src[] = "efg";
    memcpy(dest, src, 2);
    printf("%s",dest);
    return 0;
}

用法如上。 结果是

但是这个库函数,在C语言该函数是处理两块内存空间没有重合的情况,也就是说

memcpy(p+1,p,4);

像这种用法尽量避免。但是也许在你的编译器上他是可以正常运行,这个可能是因为你所使用的编译器对其进行了优化。

2.memmove

memmove基本与memcpy相同,但是可以处理重合的内存区域。

#include<string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+3, arr1, 20);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);
	return 0;
}

这段代码就可以正常被处理,而如果使用memcpy是有可能会出错的。

 3.memmove模拟实现

我们可以尝试自己用代码实现类memmove函数,效果与memmove一样。

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, size_t num);
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+3, arr1, 20);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);
	return 0;
}

刚开始我们可能会想,直接用俩指针遍历就完事了,可能会这么写

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);//assert断言是为了不使用空指针
	void* tmp = dest;
	for (int i = 0; i < num; i++)
	{
		*((char*)dest)++ = *((char*)src)++;
	}
	return tmp;
}

运行结果会发现有错误

这是因为当1,2,3复制过去后,原来的4,5就被1,2覆盖了,因此接着向后复制就会重复拷贝1,2。

可以从后向前拷贝,把4,5,6,7,8向后赋值,就可以避免。

于是可以将代码完善

void* my_memmove(void* dest, void* src, size_t num)
{
	assert(dest && src);
	void* tmp = dest;
	if (dest < src)
	{
		while (num--)
		{
			*((char*)dest)++ = *((char*)src)++;
		}
		return tmp;
	}
	else if (dest > src)
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
		return tmp;
	}
	else
		return tmp;
}

结果正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值