(C语言)内存操作函数

建议可以先看一下往期的字符串函数,里面有些东西提到了,我在本期就没有提到。

链接:http://t.csdn.cn/lEz2d

目录

1、内存拷贝1——memcpy

模拟:

2、内存拷贝2——memmove

 模拟·:

3、内存设置——memset

模拟:

4、内存比较——memcmp

模拟:


1、内存拷贝1——memcpy

要点:

1、函数memcpy从src的位置开始向后复制count个字节的数据到dest的内存位置

2、这个函数在遇到'\0'的时候并不会停下来

3、如果src和dest有任何的重叠,复制的结果都是未定义的 

函数返回的是dest的起始地址 

memcpy函数是不用来处理重叠的内存之间的数据的拷贝(但VS编译器下是可以的)

使用:

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

模拟:

void* my_memcpy(void* dest, const void* sur,size_t count)
{
	assert(dest && sur);
	void* s = dest;
	while (count--)
	{
		*(char*)dest = *(char*)sur;
		dest = (char*)dest + 1;
		sur = (char*)sur + 1;
	}
	return s;
}
int main()
{
	int a[20] = { 1,2,3,4,5,6,7,8,9,10 };
	int b[5] = { 6,7,8,9,10 };
	int i = 0;
	my_memcpy(a, b, 3*4);
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

分析:

1、为什么用void*接收?

        拷贝内存里的内容到另一块内存中去,我们是无法得知内存中的内容是字符串还是整型或者是其他类型,我们无法得知,所以采用泛型的指针void*来接收

2、assert干嘛用?

 ——保证指针的有效性

3、为什么在复制时还要强制类型转换?

        因为我们无法预知dest和src的指针类型,而我们又要满足各类数据的复制,因此我们把复制时的内容压到最小(char)。为什么?在这里我们复制的内容是整型,我们大可以直接强制类型转换为int类型的,复制更快,但是如果我们要复制的是char类型的呢?你一次复制了int的四个字节,那我们的char只需要复制一个字节呀,这是不是就会乱套了。所以我们得把力度放到最小,如果是int的,大不了多复制几次呗!

4、指针s作用?

        这个函数返回的是dest的起始位置,我们在复制时改变了dest的指向,所以采用s来记住其起始位置 

2、内存拷贝2——memmove

 使用memmove函数来实现重叠内存之间的数据拷贝

 使用:

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

 模拟·:

void* my_memmove(void* dest, const void* sur,size_t count)
{
	assert(dest && sur);
	void* s = dest;
    //从前往后
	if (dest < sur)
	{
		while (count--)
		{
			*(char*)dest = *(char*)sur;
			dest = (char*)dest + 1;
			sur = (char*)sur + 1;
		}
	}
    //从后往前
	else
	{
		while (count--)
		{
			*((char*)dest + count) = *((char*)sur + count);
		}
	}
	return s;
}
int main()
{
	int a[20] = { 1,2,3,4,5,6,7,8,9 ,10 };
	int i = 0;
	my_memmove(a + 3, a, 3 * 4);
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

为什么分两种情况(从前往后,从后往前)? 

        想一想,如果和memcpy一样的话,那它存在的价值在哪儿呢?在于,memmove可以用来处理重叠内存的数据拷贝。

如果和memcpy就会出现上述问题,因此出现了memmove来优化了它。

想一想,上述情况下,我们怎么复制合适呢?

对,采用从后往前复制就可以啦!

情况划分: 

3、内存设置——memset

使用: 

int main()
{
	char a[10] = { 0 };
	memset(a, 3, 10);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

注意:我们是将每个字节都初始化为int c,所以,在使用处理整型时,一定要小心,

错误示范:

 因为int是四个字节,他将4个字节都变成了1,自然输出就不是预期结果了

模拟:

void* my_memset(void*dest, int c, size_t count)
{
	assert(dest);
	void* ret = dest;
	while (count--)
	{
		*((char*)dest) = c;
		dest=((char*)dest)+1;
	}
	return ret;
}
int main()
{
	char a[10] = { 0 };
	my_memset(a, 3, 10);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

4、内存比较——memcmp

 使用:类似于strcmp,上一期有详细讲解:http://t.csdn.cn/lEz2d

int main()
{
	int a1[] = {1,2,3,4,5};
	int a2[] = { 1,2,3,6,7 };
	int ret = memcmp(a1, a2);
	printf("%d\n", ret);
	return 0;
}

模拟:

int my_memcmp(const void* str1, const void* str2,size_t count)
{
	assert(str1 && str2);
	while (*(char*)str1 == *(char*)str2)
	{
		count--;
		str1=(char*)str1+1;
		str2=(char*)str2+1;
		if (count == 0)
			break;
	}
	return *(char*)str1 - *(char*)str2;
}
int main()
{
	int a1[] = { 1,2,3,5,5 };
	int a2[] = { 1,2,3,4,7 };
	int ret = my_memcmp(a1, a2,24);
	if (ret > 0)
		printf(">");
	else if (ret == 0)
		printf("=");
	else
		printf("<");
	return 0;
}

结束啦!如果有不太理解的地方,去看看上一期,应该就会解决的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙洋静

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

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

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

打赏作者

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

抵扣说明:

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

余额充值