c语言你不得不知道的内存操作函数(含模拟实现)

上文我们说到了几个能操作字符串的函数,但是如果我们想实现整形数组的拷贝,整形数组的比较还是做不到的,这一篇我们来谈谈内存操作的函数和他们的模拟实现吧.

1.memcpy

定义:

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

理解:将src中的num字节大小的空间拷贝到dest里

举例:

#include 
#include 
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5 };
	//把arr2中的前五个整形的数据拷贝放在arr1中
	//memcpy
	//void* memcpy(void* destination, const void* source, size_t num);
	//dest 目的地,src 源头 ,num 拷贝几个字节
	memcpy(arr1, arr2, 20);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

 

 2.实现my_memcpy


void* my_memcpy(void* dest,const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	
	while (num--)
	{
		//不能直接dest++,因为强制类型转换时临时的,前置++不准确有些平台跑不过去,++的优先级更高,所以是先++再强转不成立
		*(char*)dest = *(char*)src;
		dest = (char*)dest +1;
		src =(char*)src + 1;
	}
	return  ret;
}

再解释一下,因为dest和src是void*类型,所以不能直接进行++操作,先强制转换为char*类型再+1,有人会说可以++吗,我只能说不太准确,强制类型转换时临时的,++操作是在临时转换之后进行操作行不通,而前置++在有些编译器跑不过去,我建议使用+1操作.

3.引入 

注:memcmp只能拷贝不重叠的数据,比如说上面的数据,而在重叠数据的拷贝我们就要使用memmove函数,虽然VS2022在这里可以实现重叠数据的拷贝,但是c语言标准是只给了这个函数拷贝不重叠数据的要求,我们可以看到,我们模拟实现的函数在arr [10]= {1,2,3,4,5,6,7,8,9,10}中将 1 2 3 4 5 拷贝到3 4 5 6 7 最后出现的却是1 2 1 2 1 2 1 8 9 10

4. memmove

定义:

void * memmove ( void * destination, const void * source, size_t num );

使用和memcpy函数一样,只是它可以拷贝数据重叠的函数,功能更强大

5.my_memmove 

这里我们分情况讨论一下什么时候从前向后拷贝,什么时候从后向前拷贝

c语言你不得不知道的内存操作函数(含模拟实现)_第1张图片

c语言你不得不知道的内存操作函数(含模拟实现)_第2张图片

我们发现,当dest

当src+num>dest>src的时候 ,从后向前拷贝,

当dest>src+num时,随便怎么都可以

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(src && dest);
	void* ret = dest;
	if (dest < src)
	{
		
		for (int i = 0; i < num; i++)
		{
			//从前向后拷贝
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}

	}
	else {
		//dest = (char*)dest + num - 1;
		//src = (char*)src + num - 1;

		//for (int i = 0; i < num; i++)
		//{
		//	//从后向前拷贝
		//	*(char*)src = *(char*)dest;
		//	dest = (char*)dest - 1;
		//	src = (char*)src - 1;
		//}
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}

	}
	return ret;
}

6.memset

用的比较少,简单介绍

定义:void * memset ( void * ptr, int value, size_t num );

注:这里设置内存是以字节问单位,不能设置整形等,设置整形只能设置0

int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'x', 3);
	printf("%s\n", arr);
	return 0;
}

假设我们想把arr数组的第一个字节设置为1,

int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 4);
	printf( "%d",arr[0] );
	return 0;
}

c语言你不得不知道的内存操作函数(含模拟实现)_第3张图片

这也进一步说明了memset修改的是字节,不能用来操作整形

 

7.memcmp

//内存比较
//int memcmp ( const void * ptr1, const void * ptr2, size_t num );
//就是比较ptr1和ptr2前num个字节的大小,小于返回负数,等于返回0,大于返回正数

你可能感兴趣的:(C语言学习,c语言,开发语言)