【C语言】模拟实现memcpy库函数

目录

函数基本介绍

模拟函数具体实现步骤 

1、第一步给模拟函数起名

 2、第二步写模拟函数主体

3、实现具体功能

代码实现  


 

我相信大家在打开这篇博客之前一定都大致了解memcpy的的功能和函数原型了吧,

如果你还不太了解它的具体细节,不妨看一下这篇博客:memcpy函数详解

函数基本介绍

我们在实现memcpy库函数之前,我们不妨回忆一下memcpy都有几个参数,都是什么类型,函数返回值是什么?

void *memcpy( void *dest, const void *src, size_t count );  

 如上,memcpy有三个参数

        第一个参数是void*类型的,是目的空间地址。

        第二个也是void*类型的,是要拷贝内容空间地址。

        第三个是size_t类型的(也就是无符号整型),是考拷贝内容的字节数。

        返回值是一个指针类型为void*,是目标地址的起始空间 

大致内容都了解完了,接下来就是该实现该函数了

模拟函数具体实现步骤 

1、第一步给模拟函数起名

在模拟函数之前我们要先给我们的函数起个好听的名字,就叫my_memcpy吧(我的memcpy)

然后把目标空间地址、要拷贝内容空间地址、字节数传入进去

 

 2、第二步写模拟函数主体

这一步我们要模仿着memcpy函数原型,来写我们的模拟函数

3、实现具体功能

 memcpy函数的功能是把内存块拷贝到目标空间,但是问题来了,memcpy第三个参数是字节数,不是要拷贝数据的个数,这我们要怎么办呢?

接下来我将用下面的例子讲解实现的具体细节

 

上面要arr1中前5个数传递给arr2,共20个字节,我把他们在计算机中存储方式大致展示出来(以16进制存储)

 (注:vs中是小端存储所以小端在前面,具体细节可查看:大小端字节序详解

 一般我们用地址赋值都会先把地址解引用并赋值,然后让地址++。

*dest = *src;
dest++;
src++;

可是,在模拟函数中,传参的地址都是void*类型的,当我们让地址++,地址不知道要跳几个字节。

比如:char* 类型的指针++,向后跳1个字节。int* 类型的指针++,向后跳4个字节

现在我们面临两个问题

        1.指针类型为void*,无法++

        2.要拷贝内容的个数不知道,通俗点就是我们不知道要拷贝几次或者两个指针要++几次

 对于第一个问题,我们把指针强制类型转换,这样就可以++了。但是如果让指针类型转换成int*话,我们就要循环count/sizeof(int)次,这样太麻烦我们还带确定用户要拷贝内容的类型。

对于这个问题我们可以把指针类型转换成char* ,因为char*类型指针++向后跳一个字节(一个字节一个字节访问),不管是什么类型我们都可以一个一个字节的拷贝,这样我们也容易确定循环次数,为count

 同时我们也不要忘了,要拷贝一下目标地址的起始位置,因为函数要返回目标空间起始地址

void* my_memcpy(void* dest, const void* src, size_t count)
{
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

 最后为了函数的健壮性,避免用户传递空指针,我们可以用assert判断一下dest和src的是否为空指针(在使用assert()函数时,别忘了引用头文件#include<assert.h>)

assert(dest && src);

代码实现 

#include<stdio.h>
#include<assert.h>

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}


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

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱躺平的威威

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

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

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

打赏作者

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

抵扣说明:

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

余额充值