【C语言进阶】库函数memcpy和memmove的模拟实现


一、memcpy的模拟实现

1.memcpy功能

  • 函数声明:
void * memcpy ( void * destination, const void * source, size_t num );
  • 功能描述:
    从存储区 sourse 复制 num个字节到存储区destinaton。
  • 参数解释:
    destination:指向用于存储复制内容的目标数组的指针,类型转换为void类型。
    sourse:指向要复制的数据源的指针,类型转换为 const void
    类型。
    num:指要复制的字节数,类型为size_t(无符号整型)。
  • 返回值:
    该函数返回一个指向目标存储区 destination 的指针。

2.思路

  • 该函数用来复制内存块,但因为不知道要复制的数据类型。我们知道无论哪种类型的数据最小单位都是字节,因此我们可以采用逐个字节的复制方法。
  • 由于char类型数据每加一正好可以跳过一个字节数,所以可以将传进来的参数强制类型转换为char类型,然后根据要复制的字节数num逐个字节进行复制即可。
  • 图示:
    在这里插入图片描述

3.代码

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* arr2, const void* arr1, size_t num)
{
	assert(arr2 && arr1);
	int i = 0;
	char* dest = (char*)arr2;
	for (i = 0; i < num; i++)
	{
		*((char*)arr2) = *((char*)arr1);
		((char*)arr1)++;
		((char*)arr2)++;
	}
	return dest;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };
	int arr2[100] = { 0 };
	my_memcpy(arr2, arr1, 24);
	int i = 0;
	int len = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

二、memmove的模拟实现

1.memmove用法

  • 函数声明:
void* memmove(void * destination,const void * sourse,size_t num);
  • 功能描述:
    从 sourse 复制 num 个字符到 destination,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
  • 参数解释:
    destination:指向用于存储复制内容的目标数组的指针,类型转换为void类型。
    sourse:指向要复制的数据源的指针,类型转换为 const void
    类型。
    num:指要复制的字节数,类型为size_t(无符号整型)。
  • 返回值:
    该函数返回一个指向目标存储区 destination 的指针。

2.思路

  • 该函数与memcpy的不同只是在处理重叠内存块的时候会更安全,因此我们要考虑到处理重叠内存块的各种形式。
  • 当目标区域在源区域之后时,和memcpy是一样的使用方法,从前往后直接拷贝,并不会导致源区域被修改。
  • 当目标区域在源区域之前时,这时就要在拷贝过程中考虑到源区域是否已被修改,为保证数组拷贝的安全性,可以采用从后往前的拷贝方式。
  • 想要实现从后往前复制,即将原指针和而目标指针同时加上(num-1)找到最后一个数据,利用循环,逐个减一,直到拷贝完第一个数据结束。
  • 图示:
    在这里插入图片描述

3.代码

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* arr_d, const void* arr_s, size_t num)
{
	assert(arr_d && arr_s);
	int i = 0;
	char* dest = (char*)arr_d;
	if (arr_d < arr_s)
	{
		for (i = 0; i < num; i++)
		{
			*(char*)arr_d= *(char*)arr_s;
			((char*)arr_d)++;
			((char*)arr_s)++;
		}
	}
	else
	{
		for (i = 0; i < num; i++)
		{
			*((char*)arr_d + num-1) = *((char*)arr_s + num-1);
			((char*)arr_d)--;
			((char*)arr_s)--;
		}
	}
	return dest;
}
int main()
{
	int arr1[] = {1,2,3,4,5,6,7,8,9};
	my_memmove(arr1+3 , arr1, 20);
	int i = 0;
	int len = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值