C语言快速入门之内存函数的使用和模拟实现

1.memcpy

它可以理解为memory + copy的组合,memory有记忆的意思,这里指的是内存,copy是拷贝,这个函数是针对内存块进行拷贝的

函数原型

void* memcpy(void* destination,const void* source, size_t num);

从source位置开始,向后num个数据拷贝到destination中,它与字符串的strcopy类似,但是遇到'\0'不会停下来,同时,两者的内存不能重叠

我们先来写代码使用一下爱这个函数吧

int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 20);	//字节的长度int i = 0;for (i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;
}

在这个代码中,我们将arr1的内容拷贝到了arr2中,拷贝了20个字节,也就是5个int类型的数字,一定要注意是字节的拷贝,这是运行结果

现在,我们来模拟实现这个函数吧

void* my_memcpy(void* dest, void* src, size_t num)
{int i = 0;void* ret = dest;assert(dest && src);/*for (i = 0; i < num; i++){*((char*)dest + i) = *((char*)src + i);}*/while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}

那如果我们想实现在一个数组内进行操作,比如我想操作arr1数组,把第二个数字开始更改,进行拷贝,如果我们写出如下的代码,可能运行结果与我们考虑的就不同了

int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy((arr1+2), arr1, 20);	//字节的长度int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

我们想要得到的是 1,2,1,2,3,4,5,8,9,10,但实际结果是:

实际上,这是因为memcpy是不能有内存重叠的,这样我们先更改了,然后再访问,因此出现了很多个1,2

当然,VS有保护机制,我们现在也可以使用memcpy来实现了,但理论上 是不行的

2.memmove

memmove和memcopy的差别是memmove函数处理源内存块和目标内存块是可以重叠的,最后返回目标空间的起始地址

函数原型

void* memmeove(void* dest, const void* src, size_t num)

现在,我们可以运用这个函数来实现了

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove((arr + 2), arr, 5*sizeof(int));int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

现在,我们来看看结果是否和我们想要的一样?

那么,我们是否可以尝试进行模拟这个函数呢?

第一种方法,我们在函数中再创建一个数组,将内容拷贝过去,然后再进行

那我们是否可以不创建新数组,来实现这个函数呢?

事实上,我们可以根据dest和scr的位置来判断

当dest在src之前时,我们从前向后进行拷贝,当dest在src后面时,我们从后向前进行拷贝,因此,我们可以写出以下的代码

void* my_memmeove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}

3.memset

是用来完成内存设置的

函数原型:

void * memset(void* ptr,int vulue,size_t num);

ptr代表要填充的内存块的位置,vulue是设置的值,num是填充几个字节的位置

现在我们来使用这个函数吧!

int main()
{char arr[] = "hello world";memset(arr, 'x', 5);printf("%s ", arr);return 0;
}

这里,我们将前五个字符变成了x,结果如下:

当然,也不仅限于字符串函数,整形函数也可以,但是我们需要注意,这里是把所有的字节转换,而int类型占据4个字节,应该注意如何来运用

4.memcmp

完成内存块的比较

函数原型

int memcmp(const void* ptr1, const void* ptr2, size_t num);

从ptr1与ptr2开始num个字节进行比较,返回值是数字,前者大返回大于0的,后者大返回小于0的,相等返回0

我们来使用这个函数吧

int main()
{int arr1[] = { 1,2,3,4,5,6,7 };int arr2[] = { 1,2,3,4,8,8,8 };int ret = memcmp(arr1, arr2, 16);printf("%d ", ret);return 0;
}

结果是这样

感谢您的观看

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

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

相关文章

【开源鸿蒙】模拟运行OpenHarmony轻量系统QEMU RISC-V版

文章目录 一、准备工作1.1 编译输出目录简介 二、QEMU安装2.1 安装依赖2.2 获取源码2.3 编译安装2.4 问题解决 三、用QEMU运行OpenHarmony轻量系统3.1 qemu-run脚本简介3.2 qemu-run脚本参数3.3 qemu-run运行效果3.4 退出QEMU交互模式 四、问题解决五、参考链接 开源鸿蒙坚果派…

合并两个有序链表

问题描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 […

AJAX概念和axios使用、URL、请求方法和数据提交、HTTP协议、接口、form-serialize插件

AJAX概念和axios使用 AJAX概念 AJAX就是使用XMLHttpRequest对象与服务器通信&#xff0c;它可以使用JSON、XML、HTML和text文本等格式发送和接收数据&#xff0c;AJAX最吸引人的就是它的异步特性&#xff0c;也就是说它可以在不重新刷新页面的情况下与服务器通信&#xff0c;…

vulhub中GitLab 任意文件读取漏洞复现(CVE-2016-9086)

GitLab是一款Ruby开发的Git项目管理平台。在8.9版本后添加的“导出、导入项目”功能&#xff0c;因为没有处理好压缩包中的软连接&#xff0c;已登录用户可以利用这个功能读取服务器上的任意文件。 环境运行后&#xff0c;访问http://your-ip:8080即可查看GitLab主页&#xff0…

【鸿蒙HarmonyOS开发笔记】状态管理入门

状态管理 为了方便开发者管理组件状态&#xff0c;ArkTS 提供了一系列状态相关的装饰器&#xff0c;例如State&#xff0c;Prop&#xff0c;Link&#xff0c;Provide和Consume等等。 State State用于装饰当前组件的状态变量&#xff0c;State装饰的变量发生变化时会驱动当前组…

uniapp移动端 IOS系统下无法与webview通信

不知道有没有人遇到过这个问题 我的页面嵌套了一个webview&#xff08;文件位于项目的hybrif/html&#xff09;目录下 使用evalJS与webview进行通信 代码如下 在安卓里运行是没问题的&#xff0c;但在苹果手机上一直无法通信 连接真机&#xff0c;打印evalJS是个方法&#xf…

Blocks —— 《Objective-C高级编程 iOS与OS X多线程和内存管理》

目录 Blocks概要什么是BlocksOC转C方法关于几种变量的特点 Blocks模式Block语法Block类型 变量截获局部变量值__block说明符截获的局部变量 Blocks的实现Block的实质 Blocks概要 什么是Blocks Blocks是C语言的扩充功能&#xff0c;即带有局部变量的匿名函数。 顾名思义&#x…

email + celery+django 异步发送邮件功能的实现

主要流程&#xff1a; django通过发件服务器到收件服务器&#xff0c;最后到收件人 邮件配置设置需要打开SMTP/IMAP并获的授权码&#xff0c;完成授权功能实现发送给收件人 邮件配置请参考另一博客https://blog.csdn.net/qq_44238024/article/details/136277821 项目结构树…

【Linux杂货铺】进程的基本概念

目录 &#x1f308;前言&#x1f308; &#x1f4c1;进程的概念 &#x1f4c2;描述进程-PCB &#x1f4c2; 查看进程 &#x1f4c2; 查看正在运行的程序 &#x1f4c2;杀死进程 &#x1f4c2;通过系统调用获取进程标识符 &#x1f4c2;通过系统调用创建进程 &#x1f…

纯 CSS 实现文字换行环绕效果

实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><…

蓝桥杯并查集|路径压缩|合并优化|按秩合并|合根植物(C++)

并查集 并查集是大量的树&#xff08;单个节点也算是树&#xff09;经过合并生成一系列家族森林的过程。 可以合并可以查询的集合的一种算法 可以查询哪个元素属于哪个集合 每个集合也就是每棵树都是由根节点确定&#xff0c;也可以理解为每个家族的族长就是根节点。 元素集合…

Transformer的前世今生 day02(神经网络语言模型

神经网络语言模型 使用神经网络的方法&#xff0c;去完成语言模型的两个问题&#xff0c;下图为两层感知机的神经网络语言模型&#xff1a; 以下为预备概念 感知机 线性模型可以用下图来表示&#xff1a;输入经过线性层得到输出 线性层 / 全连接层 / 稠密层&#xff1a;假…

Etcd 介绍与使用(入门篇)

etcd 介绍 etcd 简介 etc &#xff08;基于 Go 语言实现&#xff09;在 Linux 系统中是配置文件目录名&#xff1b;etcd 就是配置服务&#xff1b; etcd 诞生于 CoreOS 公司&#xff0c;最初用于解决集群管理系统中 os 升级时的分布式并发控制、配置文件的存储与分发等问题。基…

phpstudy搭建简单渗透测试环境upload-labs、DVWA、sqli-labs靶场

好久没有做渗透相关的试验了&#xff0c;今天打开phpstudy发现很多问题&#xff0c;好多环境都用不了&#xff0c;那就卸载重装吧&#xff0c;顺便记录一下。 小皮下载地址&#xff1a; https://www.xp.cn/download.html 下载安装完成 一、下载搭建upload-labs环境 github…

mysql与redis数据测试

题目要求 1.新建一张user表&#xff0c;在表内插入10000条数据。 2.①通过jdbc查询这10000条数据&#xff0c;记录查询时间。 ②通过redis查询这10000条数据&#xff0c;记录查询时间。 3.再次查询这一万条数据&#xff0c;要求根据年龄进行排序&#xff0c;mysql和redis各实现…

【GPT-SOVITS-03】SOVITS 模块-生成模型解析

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

vb.net+zxing.net随机彩色二维码、条形码

需要zxing库支持ZXing.NET Generate QR Code & Barcode in C# Alternatives | IronBarcode 效果图&#xff1a; 思路&#xff1a;先生成1个单位的二维码&#xff0c;然后再通过像素填充颜色&#xff0c;颜色数组要通过洗牌算法 洗牌算法 Dim shuffledCards As New List(…

Java八股文(MyBatis Plus)

Java八股文のMyBatis Plus MyBatis Plus MyBatis Plus MyBatis Plus 是什么&#xff1f;它与 MyBatis 有什么区别&#xff1f; MyBatis Plus 是基于 MyBatis 进行扩展的一款持久层框架&#xff0c;它提供了一系列增强功能&#xff0c;简化了 MyBatis 的使用。 与 MyBatis 相比…

K8S POD 启动探针 startupProbe 的使用

当我们启动一个POD 时&#xff0c; 当k8s detect 里面的容器启动成功时&#xff0c; 就会认为这个POD 启动完成了&#xff0c; 通常就会在状态里表示 ready 1/1 … 例如 rootk8s-master:~# kubectl get pods NAME READY STATUS RESTARTS AGE bq-api-demo 1…

有来团队后台项目-解析7

sass 安装 因为在使用vite 创建项目的时候&#xff0c;已经安装了sass&#xff0c;所以不需要安装。 如果要安装&#xff0c;那么就执行 npm i -D sass 创建文件 src 目录下创建文件 目录结构如图所示&#xff1a; reset.scss *, ::before, ::after {box-sizing: border-…