• 【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
    #include
    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
    #include
    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;
    }
    

  • 相关阅读:
    德鲁克《卓有成效的管理者》学习&读书-总结
    从Spring源码探究SpringMVC运行流程
    LeetCode_递归_中等_397.整数替换
    Passper for Excel v3.7.3.4 Excel 密码恢复工具
    AI语音电销机器人是如何工作的,电话机器人系统安装使用如何更高效?
    通过外部XAI技术解释的模型
    达梦数据库适配ServiceStack框架
    超全整理,Pytest自动化测试框架-多进程(pytest-xdist)运行总结...
    mysql入门,各种概念了解
    拼多多商品评论API接口(item_review-获得拼多多商品评论接口),拼多多评论API接口
  • 原文地址:https://blog.csdn.net/weixin_50486535/article/details/127084540