内存函数即其模拟实现

相对于字符串函数,内存函数像是它们的升级版,不局限于字符类型,任何类型都可使用。

让我们来看看常见的内存函数:memcpy, memmove, memcmp,memset

目录

1. memcpy

1.1 memcpy 模拟实现

2. memmove

2.1 memmove 模拟实现 

3. memcmp

3.1 memcmp 模拟实现

4. memset

4.1 memset 模拟实现


1. memcpy

 此函数能将源地址内的num个元素放入目标地址中,任何类型都可以。

用法如下:

int main()
{
	int a1[10] = {1,2,3,4,5,6,7,8,9,10};
	int a2[20] = { 0 };
	memcpy(a2, a1, 10 * sizeof(int));
	int i;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", a2[i]);
	}
	return 0;
}

1.1 memcpy 模拟实现

由于任何类型都可以,一定要注意强转类型

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);//断言,防止空指针
	void* ret = dest;//之后dest会被改变,创造一个空间存储dest的值
	while (count--)
	{
		*(char*)dest = *(char*)src;//由于void不能运算,强转char* 一字节的来进行存储
		dest = (char*)dest + 1;//先强转后运算
		src = (char*)src + 1;
	}
	return ret;
}

  

2. memmove

当想实现下面的这种内存重叠,在一个数组内进行操作,memcpy函数还能实现吗?

int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	memcpy(a + 2, a, 16);
	int i;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

答案是有的编译器可以。但是通常情况下,我们遇到这种内存重叠的情况,多使用memmove函数,比memcpy更加安全。

2.1 memmove 模拟实现 

要搞懂内存重叠的实现,需要分两种情况

从前往后传,需要从后往前来进行数据覆盖,相反亦然。

void* my_memmove(void* dest, const void* src, size_t count)
{
	void* ret = dest;
	//第一种情况:从后往前重叠
	if (dest < src)
	{
		while (count--)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
		return ret;
	}
	//第二种情况:从前往后重叠
	else
	{
		while (count--)
		{
			//一字节一字节覆盖,count也在减减
			*((char*)dest + count) = *((char*)src + count);
		}
		return ret;
	}
}

  

3. memcmp

此函数用来比较两块内存中num个元素大小返回值与strcmp函数相同

3.1 memcmp 模拟实现

int my_memcmp(const void* dest, const void* src, size_t count)
{
	while (count--)
	{
		if (*(char*)dest == *(char*)src)
		{
			dest = (char*)dest + 1;
			src = (char*)src + 1;
			continue;
		}
		else
			return *(char*)dest - *(char*)src;
	}
	return 0;
}

   

4. memset

这个函数用于将 dest地址 内 count个地址元素 改为整数c,如下:

int main()
{
	int a1[] = { 1, 2, 3, 4, 5 };
	memset(a1, 1, 20);
	return 0;
}

在内存中的情况: 

4.1 memset 模拟实现

void* my_memset(void* dest, int c, size_t count)
{
	assert(dest);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = (char)c;
		dest = (char*)dest + 1;
	}
	return ret;
}

  

感谢你能看到这,如有帮助,希望能点个👍。

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丶chuchu丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值