手把手带你用c语言模拟实现memcpy,memmove内存操作函数

目录

1.为什么要引入内存操作函数

2.memcpy函数的功能并模拟

3.memmove函数的功能并模拟 


1.为什么要引入内存操作函数

问题:我们知道字符串操作函数strlen,strcat,strcpy,strcmp,strncat,strncpy,strstr等等,但这些字符串函数只是针对字符串的,如果遇到整形数组呢?结构体数组呢?浮点型数组呢?好像就没有具体类型来说明了。

解决:如果要把一个arr1[]={1,2,3,4,5,6,7,8,9,10}的1,2,3,4,5拷贝到arr2[20]={0}中去,字符串操作函数strcpy是没办法完成的,因此可以使用内存操作函数memcpy把它当作内存块空间移到arr2数组中来解决这个问题

2.memcpy函数的功能并模拟

函数原型 

手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第1张图片

函数功能:将src所指向的内容拷贝到dest所指的空间里区,但拷贝的多少是由count决定的。

代码如图

#include
#include
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 20);
	int sz = sizeof(arr2) / sizeof(arr2[0]);
	for (int i = 0; i < sz; i++)
	{
	printf("%d ", arr2[i]);
	}
	return 0;
}
//运行结果 1 2 3 4 5

函数模拟实现思路

手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第2张图片

 代码实现

#include
#include
char* my_memcpy(void* dest, const void* src, size_t count)
{
	//因为要对指针解引用,而空指针是不能解引用
	//为了保证指针有效性,需要对dest和src断言
	assert(dest && src);
	void* ret = dest;//保存目标空间的起始地址
	while (count--)//字节数
	{
		*(char*)dest = *(char*)src;//源头数据拷贝到目标空间里
		dest = (char*)dest + 1;//转化为char*地址+1
		src = (char*)src + 1;//转化为char*地址+1
	}
	return ret;//返回目标空间的起始地址
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	int arr2[5] = { 0 };
	my_memcpy(arr2, arr1, 20);
	//arr2的打印
	int sz = sizeof(arr2) / sizeof(arr2[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

3.memmove函数的功能和模拟

问题:如果要在同一个数组里面对进行拷贝,memcpy是实现不了的,假设要把arr1里的1 2 3 4 5拷贝到3 4 5 6 7的位置,就会出现一下结果

#include
#include
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 ,10};
	memcpy(arr1 + 2, arr1, 20);

	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

原因:

手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第3张图片

上述问题需要用函数memmove来解决

函数原型

手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第4张图片

函数功能:可以实现同一块内存空间重叠内容的拷贝

代码如图

#include
#include
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 ,10 };
	memmove(arr1 + 2, arr1, 20);

	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}
//打印 1 2 1 2 3 4 5 8 9 10

函数模拟思路

手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第5张图片

 手把手带你用c语言模拟实现memcpy,memmove内存操作函数_第6张图片

代码实现(这里选简单理解的思路1) 

#include
#include
void* my_memmove(void* dest, const void*src, size_t count)
{
	//因为要对指针解引用,而空指针是不能解引用
    //为了保证指针有效性,需要对dest和src断言
	assert(dest && src);
	void* ret = dest;///保存目标空间的起始地址
	//1
	if (dest < src)
	{
		//前->后
		while (count--)
		{
			*(char*)dest = *(char*)(src);//源头数据拷贝到目标空间里
			dest = (char*)dest + 1;//转化为char*地址+1
			src = (char*)src + 1;转化为char*地址+1
		}
	}
	else
	{
		//后->前
		while (count--)
		{    //count是字节数,从源头数据的末尾开始拷贝到目标空间的末尾
			//逐个向前拷贝
			*((char*)dest+count) = *((char*)src + count);
		}
	}

	return ret;
}

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	              // 1 2 1 2 3 4 5 8 9 10
	//my_memmove(arr1+2, arr1, 20);//可以实现重叠内存的拷贝
	my_memmove(arr1, arr1+2, 20);//可以实现重叠内存的拷贝
	int i = 0;
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

      以上是关于memcpy函数和memmove函数的介绍和模拟实现,如果有什么需要改进的地方,希望大家指出,创作不易,我们共同进步。

你可能感兴趣的:(c语言)