【内存操作】C语言内存函数介绍以及部分模拟实现【初学者保姆级福利】超详细的解释和注释

C语言 内存函数的使用以及部分模拟实现

求个赞求个赞求个赞求个赞 谢谢🙏

先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️

看完这篇博客,除了学会这个几个内存函数之外,相信你会对计算机的内存,以及指针的理解和应用会提高一个层次

强烈建议本篇收藏后食用

memcpy函数

原型:void* memcpy(void* destination, const void* source, size_t num);

函数介绍
图片取自:www.cplusplus.com
在这里插入图片描述
该函数可以将内存中固定字节数拷贝到另一块内存空间中
例子:

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };

	memcpy(arr2,arr1,20);
	//将arr1所指向的内存中取20个字节的内容拷贝到arr2中
	return 0;
}

我们f10并打开监视就可以看到arr2已经被拷贝了20个字节的结果:1,2,3,4,5.

memcpy的模拟实现

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	//为了防止dest在后续操作中丢失地址
	//我们用一个ret来记录dest一开始的地址
	//拷贝完成后我们直接返回ret即可
	assert(dest && src);//断言dest和src都不是空指针
	int i = 0;
	for (i = 0; i < num; i++)
	{
		*((char*)dest) = *((char*)src);//因为void*类型指针
		//不能够解引用,因此强制转化成char*类型,每次拷贝一个字节即可。
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		//每次拷贝完一个字节,拷贝下一个字节,一共拷贝num次
	}
	return ret;//返回拷贝完的地址
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	int i = 0;
	my_memcpy(arr2, arr1, 24);
	for (i = 0; i < 6; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

在这里插入图片描述
这样我们就成功拷贝了
注意:这种模拟实现方式是不可以处理重叠的内存的,因为我们一个一个字节拷贝,如果前面的拷贝改变了后面即将要拷贝的内存,就会使得我们得不到想要的答案。

而此时,我们就需要memmove函数,这个函数是可以处理重叠的内存的

memmove函数

图片取自:www.cplusplus.com
在这里插入图片描述

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

memmove是可以处理重叠的内存的

模拟实现memmove

为了可以处理重叠的内存,我们要分两种情况。
第一种:从前向后拷贝
第二种:从后向前拷贝。

如果我们的src在dest后面我们就必须从后向前拷贝
如果我们的dest在src后面,我们就必须从前向后拷贝。
这样才能使得我们在拷贝内存的时候不会有因为重叠而造成错误的结果。
对于这一部分不明白的伙伴可以给我私信留言。

void*my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)//判断拷贝方向
	{
		//从前向后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//从后向前
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
			//因为这里的num--所以,我们这样写就可以了,每次--交换一次
			//直到循环跳出

		}
	}
	return ret;
}

//memcpy-只是先了不重叠的拷贝,而vs中的实现既可以拷贝不重叠,也可以拷贝重叠内存
//vs库里面的memcpy是可以拷贝重叠的,过程和我们写的memmove一样
//但是不保证每一种编译器都可以,所以,我们操作重叠内存的时候,就用memmove就可以了

对于这一部分不明白的伙伴可以给我私信留言。

memcmp函数

图片取自:www.cplusplus.com
在这里插入图片描述

内存比较函数
这个函数与strcmp函数十分相似
原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
使用过程:

int main()
{
	float arr1[] = { 1.0,2.0,3.0,4.0 };
	float arr2[] = { 1.0,3.0 };
	int ret = memcmp(arr1, arr2, 4);
	printf("%d\n", ret);
	//返回值和strcmp很相似
	return 0;
}

这个函数比较简单,在这里就不给大家模拟实现了,相信你看了上面两个函数的模拟实现过程,模拟实现这个函数不成问题。

memset函数

图片取自:www.cplusplus.com
在这里插入图片描述

memset内存设置函数
原型:void * memset ( void * ptr, int value, size_t num );
可以将ptr指向的num个字节的内存设置成想要的值。
使用过程

int main()
{
	int arr[10] = { 0 };//前20个字节设置成1
	memset(arr,1,20);//以字节为单位设置,每个字节都是1
	//01 01 01 01肯定不是1

	//如果想把每个元素设计成1,不能用memset
	//字符可以
	char arr2[10] = { 0 };
	memset(arr2, 'a', 5);
	printf("%s ", arr2);
	return 0;
}

注意,这里得到的结果肯定不会是1的,我们是把20个字节设置成1,不是20个整型设置成1

以上就是这四个函数的全部内容了,非常感谢你能看到这里,别忘了点关注,点收藏,点大拇指,一键三连再走哦!

posted @ 2021-10-26 20:14  背包Yu  阅读(0)  评论(0编辑  收藏  举报  来源