C语言——内存函数介绍和模拟实现(memcpy、memmove、memset、memcmp)

之前我们讲过一些字符串函数(http://t.csdnimg.cn/ZcvCo),今天我们来讲一讲几个内存函数,那么可能有人要问了,都有字符串函数了,怎么又来个内存函数,这不是一样的么?

我们要知道之前的字符串函数只能对字符串进行一系列操作很是局限,这次的内存函数就不一样了,内存函数的范围就很广了,它可以对数组啊,或者是结构体进行操作了。

memcpy函数

它是一个内存拷贝函数,类似于字符串函数strcpy。

memcpy的头文件是<string.h>

int main() {int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };memcpy(arr1, arr2, 20 );return 0;
}

1、上面的例子就是两个数组,传的也是整形,所以就不能用strcpy,所以就体现了memcpy的重要性和通用性。

2、这个num一定要注意是字节的大小,所以上面的例子传了5个整数int,所以字节大小就是20。

 那么我们该如何对他进行模拟实现呢?🤔🤔🤔

void* my_memcpy(void* dest,void* src,size_t sz) {assert(dest && src);void* ret = destwhile (sz--) {*(char*)dest = *(char*)src;dest = (char*)dest+1;src = (char*)src + 1;}return ret;
}int main() {int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };my_memcpy(arr1, arr2, 20 );return 0;
}

这里我们进行了一个模拟实现:

1、首先我们因为要考虑传的参数都可能不同,所以为了通用性,我们这里用void*来接受各种类型的指针。

2、其次当进行拷贝的时候,由于是一个字节一个字节进行的,所以我们只能转换成(char*)来进行交换。

3、交换完之后,我们还需要将dest和src进行后移,移动到下一个字节待交换,因为强制类型转换是临时性的,所以这里在进行移动的时候还需要进行一次强制类型转换。

4、sz是总字节大小,所以用做循环的变量,来控制循环。

memmove函数

 刚刚的memcpy函数是用来进行,两个之间的拷贝,那么这个memove函数是用来进行同一个内存块的拷贝。

int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr+2, arr, 12 );return 0;
}

 思考memmove的模拟实现

但是这个思路到底能否实现呢?🤔🤔🤔 

那么只是用从后向前拷贝就可以解决所有问题么? 

所以这个我们就要进行分类讨论了 

可以看到上面这个图,我们可以看到,最后通过我们的分析可以知道,我们当dest<src时要进行从前向后拷贝,dest>src时要进行从后向前拷贝。

那么我们来实现一下代码:

void* my_memmove(void* dest, void* src, size_t sz) {assert(dest && src);void* ret = dest;while (sz--) {if (dest < src) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}else {*((char*)dest + sz) = *((char*)src + sz);}}return ret;
}
int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr+2, arr, 12 );return 0;
}

我们用while循环sz为循环变量,当dest<src的时候我们就将其正常拷贝就可以了 ,否则的话我们用dest和src分别加sz就到了数组的后面,然后随着sz的递减,我们就实现了从后向前拷贝。

 memset函数

这个函数可以将内存块进行指定更改,例如:

我们可以看到arr代表首元素地址,所以从数组第一个1开始,向后的12个字节,也就是3个int整形,所以我们看到内存里面的前三个被替换成了0。

另外也可以替换字符串

int main() {char arr[] = { "Hello world" };memset(arr+6 ,'x', 3);printf("%s", arr);return 0;
}

 我们可以替换字符串就像这样

但是当用这个函数的时候有一个点:

int main() {int arr[] = { 1,2,3,4,5,6 };memset(arr+1 ,1, 8);return 0;
}

 这个函数我们想要把2,3也都变成1,但是我们运行结果却不是

我们发现并不是更改成了1,当我们用16进制看的时候会发现:

它是将每一个字节都更改成了1,所以导致最后的值很大。 

 memcmp函数

可以看到,由于memcmp是按照字节比较的所以,当我们取前三个元素的字节时,arr1和arr2都是一样的,所以输出结果就是0。

但是当我改成:

07比04大所以,arr2大于arr1返回的是小于0的值。 

 感谢大家的观看!!!我们下次再见🌹🌹🌹

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

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

相关文章

第十二站(20天):C++泛型编程

模板 C提供了模板(template)编程的概念。所谓模板&#xff0c;实际上是建立一个通用函数或类&#xff0c; 其 类内部的类型和函数的形参类型不具体指定 &#xff0c;用一个虚拟的类型来代表。这种通用的方式称 为模板。 模板是泛型编程的基础, 泛型编程即以一种独立于任何特定…

C++面试:跳表

目录 跳表介绍 跳表的特点&#xff1a; 跳表的应用场景&#xff1a; C 代码示例&#xff1a; 跳表的特性 跳表示例 总结 跳表&#xff08;Skip List&#xff09;是一种支持快速搜索、插入和删除的数据结构&#xff0c;具有相对简单的实现和较高的查询性能。下面是跳表…

职业规划,软件开发工程师的岗位任职资格

软件工程师是指从事软件开发的人&#xff0c;主要的工作涉及到项目培训和项目设计两个方面。在实际工作中&#xff0c;软件工程师是一个广义的概念&#xff0c;包括了很多与软件相关的人员。除开最基础的编程语言&#xff0c;还有数据库语言等等。从事这份工作&#xff0c;需要…

记录一下uniapp 集成腾讯im特别卡(已解决)

uniapp的项目运行在微信小程序 , 安卓 , ios手机三端 , 之前这个项目集成过im,不过版本太老了,0.x的版本, 现在需要添加客服功能,所以就升级了 由于是二开 , 也为了方便 , 沿用之前的webview嵌套腾讯IM的方案 , 选用uniapp集成ui ,升级之后所有安卓用户反馈点击进去特别卡,几…

HR人才测评,如何做技术研发人员基本素质测评?

技术研发人员的基本素质测评&#xff0c;可以从以下几个方面考虑&#xff1a; 1. 技术能力&#xff1a;首要的因素是技术能力&#xff0c;包括编程能力、算法能力、架构设计能力、代码调试和优化能力等。在测评中可以通过技术测试、编程练习、项目经验等方式来考察。 2. 学习…

Java - 深入理解加密解密和签名算法

文章目录 应用的接口安全性问题可能来源加密解密Why保护数据隐私防止未经授权的访问防止数据泄露 对称加密 VS 单向加密 VS 非对称加密一、对称加密二、单向加密&#xff08;哈希加密&#xff09;三、非对称加密 常用的对称加密算法1. AES&#xff08;高级加密标准&#xff09;…

Django从入门到精通(二)

目录 三、视图 3.1、文件or文件夹 3.2、相对和绝对导入urls 3.3、视图参数requests 3.4、返回值 3.5、响应头 3.6、FBV和CBV FBV 四、静态资源 4.1、静态文件 4.2、媒体文件 五、模板 5.1、寻找html模板 5.2、模板处理的本质 5.3、常见模板语法 5.4、内置模板函…

对称密码算法有什么优点

对称密码算法是一种加密和解密数据的方法&#xff0c;其中加密和解密使用相同的密钥。这种方法的一个关键特点是加密和解密的速度非常快&#xff0c;因此它在许多需要高速加密的应用中非常有用。 对称密码算法的优点主要在于其效率和安全性。由于加密和解密使用相同的密钥&…

自定义注解与拦截器实现不规范sql拦截(拦截器实现篇)

最近考虑myBatis中sql语句使用规范的问题&#xff0c;如果漏下条件或者写一些不规范语句会对程序性能造成很大影响。最好的方法就是利用代码进行限制&#xff0c;通过拦截器进行sql格式的判断在自测环节就能找到问题。写了个简单情景下的demo&#xff0c;并通过idea插件来将myB…

UE5 Windows打包时报错“SDK Not Found”解决方案

在Unreal Engine 5.0.3 Windows平台下打包时报错&#xff1a;“Windows的SDK未正常安装&#xff0c;而其是生成数据的必需项。请检查主工具栏中“启动“菜单SDK部分来更新SDK。” 解决方案&#xff1a; 1、打开 Visual Studio Installer&#xff0c;点击“修改”按钮&#xf…

EtherNet/IP开发:C++搭建基础模块,EtherNet/IP源代码

这里是CIP资料的协议层级图&#xff0c;讲解协议构造。 ODVA&#xff08;www.ODVA.org&#xff09;成立于1995年&#xff0c;是一个全球性协会&#xff0c;其成员包括世界领先的自动化公司。结合其成员的支持&#xff0c;ODVA的使命是在工业自动化中推进开放、可互操作的信息和…

到店商详架构变迁

一、项目背景 到店商详是平台为京东到店业务提供的专属商详页面&#xff0c;将传统电商购物路径打造成以LBS门店属性的本地生活服务交易链路。 二、架构变迁 1、 主站商详扩展点 **优点&#xff1a;**到店侧仅关注业务&#xff0c;无需过度关注服务部署、性能优化等。 **缺…

数据结构与算法(一)线性表

逻辑结构 逻辑结构有以下几种关系 没关系 一对一关系 一对多关系 多对多关系 a是b的前驱&#xff0c;c是b的后继 该四种关系有以下别名 集合 线性表 树 图 …

[IPv6]常用的几种IPv4和IPv6地址格式

记录一下常用的IPv4和IPv6地址格式 IPv4 IPv4地址是32位的&#xff0c;通常表示为“192.168.1.12”这样点分成4段的形式。 一个IP地址可以分为两部分&#xff0c;网络ID和主机ID。如何区分哪些位是网络ID&#xff0c;哪些位是主机ID&#xff0c;就需要子网掩码。 子网掩码 …

pip install flagai时出现Collecting PyYAML==5.4.1 (from flagai)等错误信息的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

HCIA——22DNS:DNS层次域名空间、域名服务器、域名解析的原理

学习目标&#xff1a; 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本方法进行…

CVE重要通用漏洞复现java phpCVE-2021-44228

在进行漏洞复现之前我们需要在linux虚拟机上进行docker的安装 我不喜欢win上安因为不知道为什么总是和我的vmware冲突 然后我的kali内核版本太低 我需要重新安装一个新的linux 并且配置网络 我相信这会话费我不少时间 查看版本 uname -a 需要5.5或以上的版本 看错了浪…

Rocky Linux 9. 3安装图解

风险告知 本人及本篇博文不为任何人及任何行为的任何风险承担责任&#xff0c;图解仅供参考&#xff0c;请悉知&#xff01;本次安装图解是在一个全新的演示环境下进行的&#xff0c;演示环境中没有任何有价值的数据&#xff0c;但这并不代表摆在你面前的环境也是如此。生产环境…

计算机网络-分层结构,协议,接口,服务

文章目录 总览为什么要分层怎样分层正式认识分层概念小结 总览 为什么要分层 发送文件前要做的准备工作很多 把这个准备工作分层小问题解决&#xff0c;也就分层解决 怎样分层 每层相互独立&#xff0c;每层做的工作不同 界面自然清晰&#xff0c;层与层之间的接口能够体现…

三、Flask学习之BootSrap

三、Flask学习之BootSrap Bootstrap 是一款由Twitter团队开发的开源前端框架&#xff0c;它以响应式设计、移动端友好和丰富的组件为特色&#xff0c;为开发者提供了快速构建现代化网站和Web应用的工具。借助其灵活的栅格系统、丰富的UI组件和可定制的样式&#xff0c;Bootstr…