超详解内存函数(memcpy,memmove,memcmp),及其模拟实现

目录

  目录:

        1:memcpy函数及其模拟实现

        2:memmove函数及其模拟实现

        3:memcmp函数及其模拟实现


1:memcpy函数及其模拟实现

        

作用:从source地址开始后中拷贝num个字节的内容到目的地字符串,遇到'\0'也不会停止,类型是void*的原因是因为它可以拷贝任意类型的内存块 ,但是它dest目的地与source目的地地址不能重叠,如果重叠了则结果可能是不对的。

memcpy函数的模拟实现:

void* my_memcpy(const void* dest, const void* src, size_t num)
{assert(dest != NULL && src != NULL);void* p = (char*)dest;while (num--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}return p;
}
int main()
{char arr1[] = "xxxxxxxxxxxxxxxxxxx";char arr2[] = "hello";my_memcpy(arr1, arr2, 5);printf("%s\n", arr1);return 0;
}

思路:因为要实现任意类型的num个字节的拷贝,所以我们需要将函数参数设置为void*的指针,然后利用循环来拷贝num个字节的内容,将dest与src指针强制类型转化为char*的指针,然后给dest所指向的指针赋值,然后一次循环过后dest+1,又因为dest指针是void*类型的指针所以不能直接进行+1,所以因该先将其转化为char*类型的指针在+1.

2:memmove函数及其模拟实现

        memmove的用法与作用与memcpy函数是一样的,唯一区别就是memmove可以处理有内存快重叠的部分。

memmove函数的模拟实现:

void my_memmove(void* dest,void*src,int num)
{while (num--){if (dest < src){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}else{*((char*)dest + num) = *((char*)src + num);}}
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1 , arr1+2, 20);int j = 0;for (j = 0; j < 10; j++){printf("%d ", arr1[j]);}return 0;
}

思路:这里得分情况讨论一下,上图比较好理解:

dest>src的时候如果我们还是从前往后进行赋值的话,那么可能会导致数据的丢失,比如说我们第一次的时候结果是: 1 2 1 4 5 6 7 8 9 10  第二次:1  2 1 2 5 6 7 8 9 10,所以导致了本来应该是3 和4 的地方的值被覆盖了,所以就不能形成自己给自己赋值,所以我们需要从后往前来进行赋值,来避免这种情况,同理当dest<src的时候也可能会覆盖,当他们两没有交集的时候就随便怎么赋值。

3:memcmp

作用:比较两指针前num个字节处内容的asc码值,如果前面大于后面则返回大于0的数,如果等于则返回0,小于则返回小于0的数

void* my_memcmp(const void* p1, const void* p2, int num)
{while (num--){if (*(char*)p1 > *(char*)p2){return 1;}else if (*(char*)p1 < *(char*)p2){return -1;}else{p1 = (char*)p1 + 1;p2 = (char*)p2 + 1;}}return 0;
}int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,2,5,6 };int ret =my_memcmp(arr1, arr2, 9);printf("%d\n", ret);return 0;
}

思路:比较每一个字节的内容,一共比较num次,前面>后面返回1,<返回-1  =返回0。

得用到强制类型转换。

感谢大家的耐心观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/20095.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript的简要介绍

什么是JavaScript&#xff1f; JavaScript 是一种高级的、面向对象的、多范式编程语言。 javascript在网站开发中的作用 这三种语言在一起可以构建好看的和动态网站或者网络应用从程序&#xff1b; HTML、CSS、JavaScript是构建网站的三种基本技术。它们各自负责以下方面&…

机器学习原理

此次主要是由分类来引出 由于宝可梦的图片比较简洁&#xff0c;而数码宝贝的图片就显得比较复杂&#xff0c;我们计算出他们的轮廓&#xff0c;求出白色数量的多少。 e的函数会计算线条的复杂程度。当得出的线条的复杂程度&#xff0c;小于h。我们认为其是宝可梦&#xff0c;反…

adb shell dumpsys SurfaceFlinger

adb shell dumpsys SurfaceFlinger adb shell dumpsys SurfaceFlinger分析Android 系统图层 此命令输出的内容不较多&#xff0c;可以将输出内容重定向到一个文件中 adb shell dumpsys SurfaceFlinger > ./Downloads/surface.txt如下的内容&#xff0c;过滤HWC layers 另外…

02 |「Android Studio 新建项目」

前言 新手入门安卓开发 文章目录 前言一、步骤一、步骤 New Project选择 Empty Activity1)Name:项目的名字; 2)Package name:项目的包名(项目的唯一标识); 3)Save location:项目的保存路径; 4)Language:

Python+Requests+Excel接口测试实战

1、EXCEL文件接口保存方式&#xff0c;如图。 2、然后就是读取EXCEL文件中的数据方法&#xff0c;如下&#xff1a; 1 import xlrd2 3 4 class readExcel(object):5 def __init__(self, path):6 self.path path7 8 property9 def getSheet(self): 10 …

Java的jdk配置成功,但是输入java -version等,命令行没有任何反应

问题&#xff1a;现在有很多学生出现这种情况&#xff0c; Java的jdk配置成功&#xff0c;但是输入java -version等&#xff0c;命令行没有任何反应 Java下载后&#xff0c;手动配置环境变量&#xff0c;并且配置好&#xff0c;但是在命令行中无论输入java的什么都没有反应 问…

Unity游戏C# dll注入

案例游戏下载 首先在网上下载个游戏案例&#xff0c;我就以Captain Molly游戏为例。 这个游戏玩家默认生命值有5点&#xff0c;咱们通过dll注入修改为10点。 dnSpy 我使用dnSpy来查看Unity游戏生成的dll代码&#xff0c;当然你们也可以使用其他工具。 Unity游戏脚本代码最终…

JS代码混淆,如何配置最合适?

JS混淆加密工具&#xff0c;通常有众多的加密选项。比如&#xff0c;著名的JShaman&#xff0c;中文版有十余种配置选项、英文则有二十余种配置。 ​ 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 当我们在对JS代码进行加密时&#xff0c;该启用哪些选…

SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现

系列文章&#xff1a; SpringBoot Vue前后端分离项目实战 || 一&#xff1a;Vue前端设计 SpringBoot Vue前后端分离项目实战 || 二&#xff1a;Spring Boot后端与数据库连接 SpringBoot Vue前后端分离项目实战 || 三&#xff1a;Spring Boot后端与Vue前端连接 SpringBoot V…

【调峰】储能辅助电力系统调峰的容量需求研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【数据挖掘】时间序列教程【十】

5.4 通用卡尔曼滤波 上一节中描述的状态空间模型作为观测方程的更一般的公式 和状态方程 这里是一个p1 向量是一个k1 向量, 是一个pk 矩阵, 是kk 矩阵。我们可以想到的和 给定初始状态 和 &#xff0c;预测方程为&#xff08;类似于上面&#xff09; 并且更新方程是&#x…

038、TiDB特性_聚簇索引和非聚簇索引

聚簇表 表中的行数据才能出顺序与主键存储的顺序一致表的主键即为KV映射中Key的一部分通过主键访问行记录时&#xff0c;可以直接获取行记录 create table t( a biging primary key clustered ,b varchar(255)); # a列为主键列&#xff0c;聚簇列聚簇表&#xff08;且ID为主键…