C语言——模拟实现memcpy函数和memmove函数

目录

一.memcpy函数

1.函数简介

2.具体代码

什么是断言

什么是size_t

3.对比截图

二.memmove函数

1.函数简介

2.具体代码

3.对比截图


一.memcpy函数

1.函数简介

函数原型void *memcpy(void *destin, void *source, unsigned n);

参数

  • destin -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。

  • source -- 指向要复制的数据源,类型强制转换为 void* 指针。

  • n -- 要被复制的字节数。

返回值:该函数返回一个指向目标存储区destin的指针。

函数功能:从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中。

头文件:C语言:#include<string.h>

               C++:#include<cstring>

2.具体代码

什么是断言:

断言概念:编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁用断言。

用法:void assert(int test);

头文件#include<assert.h>

作用:如果它的条件返回错误,则终止程序执行

注意:assert是宏,而不是函数。

什么是size_t:

        它是一种“整型”类型,里面保存的是一个整数,就像int、long那样。这种整数用来记录一个大小(size)。size_t的全称应该是size type,就是说“一种用来记录大小的数据类型”。

        在这里,我们可以简单理解为 unsigned int ( 无符号整型 ) 就可以了。

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

void *mymemcpy(void *destin, void *source, size_t n){
	assert(destin != NULL);
	for (int i = 0; i < n; i++){//会出现类型不匹配的警告
    //修改为
    //for (size_t i = 0; i < n; i++){
		*((char *)destin + i) = *((char *)source + i);
	}
	return destin;
}

void main()
{
	char destin[100] = { 0 };
	char source[] = "hello";
	printf("%s\n", mymemcpy(destin, source, 3));
	printf("%s\n", memcpy(destin, source, 3));
}

PS:在运行中可能会出现如下警告,这是因为 n 被定义为: unsigned int 类型,而 i 是int 类型,虽然不影响运行结果,但是想要解决的话就是把for循环中定义的i的类型由int 改为size_t,这样就不会出现该警告了。

3.对比截图

二.memmove函数

1.函数简介

原型void *memmove( void* dest, const void* src, size_t count );

功能:由src所指内存区域复制count个字节到dest所指内存区域。

头文件:<string.h>

说明:memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。

2.具体代码

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

void *mymemmove(void* dest, const void* src, size_t count){
	assert(dest != NULL&&src != NULL);
	char *d = (char  *)dest;
	char *s = (char  *)src;
	if (d > s && (s + count) > d) {//src在前且有重叠 从后往前拷贝
		d += count - 1;
		s += count - 1;
		for (size_t i = count - 1; i >= 0; i--){
			*d = *s;
			d--;
			s--;
		}
	}
	else{//没有重叠
		for (size_t j = 0; j < count; j++){//从前往后拷贝
			*d = *s;
			d++;
			s++;
		}
	}
	return dest;
}

void main()
{
	char destin[100] = { 0 };
	char source[] = "hello";
	printf("%s\n", mymemmove(destin, source, 3));
	printf("%s\n", memmove(destin, source, 3));
}

3.对比截图

如有建议或想法,欢迎一起交流学习~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值