内存操作函数
前言
🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏: 🍔🍟🌯 c语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:介绍c语言中有关指针更深层的知识.
金句分享:
✨未来如星辰大海般璀璨✨
✨不必踌躇于过去的半亩方塘.✨
目录
- 前言
- 一、memcpy函数
- 函数模型:
- 函数参数:
- 函数的应用:
- 函数的模拟实现:
- 二、memmove函数
- 函数模型:
- 函数参数:
- 函数模拟实现
- 三、memcmp函数
- 函数模型:
- 函数参数:
- 函数应用:
- 模拟实现
- 四、memset函数
- 函数模型:
- 函数参数
一、memcpy函数
函数模型:
函数参数:
参数 | 意义 |
---|---|
destination | 指向目的地地址的指针,类型转换为 void* 类型的指针。 |
source | 指向要复制的数据源的指针,类型转换为 const void* 类型的指针。 |
num | 要复制的字节数 |
函数头文件:
#include <string.h>
函数功能:
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
注意:
要保证目的地址存的下源地址的内容,要守规矩哦!
1.为什么有了strcpy函数还要有memcpy函数呢?
因为strcpy函数是字符串拷贝,包括strncpy函数也是一样,只能拷贝字符串,对于其它类型,比如整形的拷贝就无能为力.
2.为什么要设置为void*类型?
如果看过前面qsort函数的模拟,这里应该也不难理解,因为要拷贝的类型是未知的,为了能够接收所有类型,所以设置为void*,使用时强制转换为char*类型,然后按字节个数拷贝即可.
函数的应用:
1.将arr2数组的前三个元素拷贝到arr1数组的前三个位置.
2.将字符串str2全部除了’\0’以外,拷贝到str1字符串.
#include <stdio.h>
#include <string.h>
int main()
{int arr1[10] = { 6,6,6,6,6,6,6,6,6,6 };int arr2[] = { 1,2,3,4,5,6,7,8 };int arr2sz= sizeof(arr2) / sizeof(arr2[0]);char str1[] = "XXXXXXXXXXXXXXXX";char str2[] = "Hello CSDN!";int str2sz= sizeof(str2) / sizeof(str2[0]);memcpy(arr1, arr2, sizeof(int) * 3);for (int i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("\n");memcpy(str1, str2, sizeof(char) * str2sz - 1);//-1是因为这里使用的是sizeof()函数计算的长度,会包括\0printf("%s", str1);printf("\n");return 0;
}
运行结果:
1 2 3 6 6 6 6 6 6 6
Hello CSDN!XXXXX
函数的模拟实现:
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{assert(destination);assert(source);while (num--){//void*类型不可直接使用,要强制转化*(char*)destination = *(char*)source;//*是为了找到该地址所对应的字符串((char*)destination)++;//指针分别往后走,所以不需要解引用((char*)source)++;}
}
思考:
memcpy函数可以拷贝内存重叠的地址吗?
即source和destination有重叠的时候.(可以试试).
二、memmove函数
函数模型:
函数参数:
参数 | 意义 |
---|---|
destination | 指向目的地地址的指针,类型转换为 void* 类型的指针。 |
source | 指向要复制的数据源的指针,类型转换为 const void* 类型的指针。 |
num | 要复制的字节数 |
函数作用:
该函数与memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠
的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理,其实在有的编译器中,对于memcpy函数也进行了优化,也是允许内存重叠的.
但牛牛认为,还是有必要掌握这种更"稳妥"的函数的.
情况1
这种情况我们可以正常的从前向后(前->后) 拷贝.
即:先将6拷贝至2位置,再讲7拷贝至3位置……
这种情况我们使用从从前向后(前->后)拷贝则达不到我们的要求.
如果我们先将6拷贝至8处,7拷贝至9处,则原来的8 9都被修改了.
这时我们需要从后往前(后->前)拷贝.
即先将11拷贝至13处,再将9拷贝至12处……
其实这种情况并不是内存地址重叠,目的地址出现在前面也是一样的,都是可以从前向后(前->后)拷贝和从后往前(后->前)拷贝皆可.
函数模拟实现
#include <stdio.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, size_t num)
{void* ret = destination;//保留目的地原来的首地址assert(destination && source);//防止传错地址if (destination < source)//情况1时,目的地址的首地址小于源地址首地址{//前-->后while (num--){*(char*)destination = *(char*)source;((char*)destination)++;((char*)source)++;}}else{//后->前while (num--){*((char*)destination + num) = *((char*)source + num);//注意,这里如果以destination为1的偏移量,+num则是目的地地址的最后一个元素的地址.}}return ret;
}
代码测试:
情况1;
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr + 1, arr + 5, sizeof(int) * 5);int sz= sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
运行结果:
1 6 7 8 9 11 7 8 9 11 12 13
情况2:
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr +7, arr + 5, sizeof(int) * 5);int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
运行结果:
1 2 3 4 5 6 7 6 7 8 9 11
三、memcmp函数
函数模型:
函数参数:
参数 | 意义 |
---|---|
ptr1 | 指向要比较的内容1,指针 |
ptr2 | 指向要比较的内容2,指针 |
num | 要比较的字节个数 |
函数头文件:
#include <string.h>
函数功能
比较从ptr1和ptr2指针开始的num个字节.
注意与strcmp函数区分:
strcmp函数:用于比较字符串是否相等,只用于比较字符
memcmp:按字节比较,两个指针所指向的内容是否相等.可用于比较不同类型的元素,但是是按字节比较.
返回值 | 意义 |
---|---|
<0 | 第一个不想等的字节中的值的str1的值小于str2中的值(arr1<arr2) |
0 | 两个指针的内容相等 |
>0 | 第一个不相等的字节的str1的值大于于str2中的值(arr1>arr2 |
函数应用:
试着猜一下这段代码的值?(vs2022环境(小端))
//memcmp函数模拟
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,4,7,255 };int arr2[] = { 1,4,7,511 };int ret=memcmp(arr1, arr2, 13);printf("%d", ret);return 0;
}
答案:
0
解析:
首先这里是小端存储模式.则这两个数组在内存中存储的是:
arr1 :01 00 00 00 04 00 00 00 07 00 00 00 FF 00 00 00 (16进制,两位代表一个字节)
arr2 :01 00 00 00 04 00 00 00 07 00 00 00 FF 10 00 00
很明显,这里前四个元素(1,4,7)是相等的,而元素255和元素511则是第一个字节的内容相等,所以当比较的元素是[0,13]时,memcmp函数会认为这两个指针所指向的内容是相同的,故返回值是0.
可以试着改成14字节,返回值会是-1,因为第14个字节,arr1是00.arr2是1,则arr1<arr2;
模拟实现
#include<assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{assert(ptr1 && ptr2);while (num--)//比较num个字节{if (*(char*)ptr1 == *(char*)ptr2)//相等继续往后比较{((char*)ptr1)++;((char*)ptr2)++;}else if (*(char*)ptr1 > *(char*)ptr2)//str1大则返回大于0的数{return 1;}else//str2大返回小于0的数{return -1;}}return 0;//比完了num个字节都相等则返回0
}
四、memset函数
函数模型:
头文件:
#include <string.h>
函数参数
参数 | 意义 |
---|---|
ptr | 指向要设置内容的空间 |
value | 要设置的值,虽然是整形类型,但是也可以是字符,字符会转化为对应的ASCII码值 |
num | 要设置空间内容的字节个数 |
函数功能:
将ptr所指向的空间,的num个字节设置为value值,注意这里也是按字节设置.
示例:
#include <stdio.h>
#include <string.h>
int main()
{int arr[5] = { 0 };memset(arr, 1, 20);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}
结果会是下面这个吗?
1 1 1 1 1
正确答案:
16843009 16843009 16843009 16843009 16843009
为什么呢?
我们可以试着通过调试找到答案.
执行语句memset(arr, 1, 40);后

很显然,这里是将20个字节设置为了1,而一个整形占4个字节;
那么怎样才可以将每个元素都设置为1呢?
#include <stdio.h>
#include <string.h>
int main()
{int arr[5] = { 0 };for (int i = 0; i < 5; i++){memset(arr+i, 1, 1);}for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}
其实这样才能达到我们想要的结果,这里是将一个字节设置为1,然后跳过四个字节(下一个元素),再将这个元素的首字节设置为1.
但是这样是不是有点太麻烦了,所以一般memset函数一般不会这么用,一般memset函数用来将一段空间的元素按字节都初始化为0,在后面我们用到malloc函数向内存申请空间时,得到的空间里面存放的值都是随机值,这时我们可以使用它来帮助我们完成初始化操作.
好了,今天的内存操作函数就讲到这里了,我们下周再见!
最后,如果文章对大家有帮助的话,求一波三连吧!
💗💗💗886
相关文章:

内存操作函数
前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨未来…...

免费搭建个人博客
免费搭建个人博客,并发布到公网 利用hexo搭建个人博客,通过gitee的pages发布到公网 1 前置准备 安装git、安装node.js(尽量选择长期支持的版本) node.js官网:https://nodejs.org/en/ git官网:https://git-scm.com/book/zh/v2 安装…...

【Vue全家桶】详解Vue Router(一)
【Vue全家桶】Vue Router详解(一) Vue系列文章目录: 内容参考链接Vue(一)【Vue全家桶】邂逅Vue、Vue的多种引入方式Vue(二)【Vue全家桶】声明式编程、MVVMVue(三)【Vue…...

9大 HIVE SQL 最频繁被问到的面试题
SQL是用于数据分析和数据处理的最重要的编程语言之一,因此与数据科学相关的工作(例如数据分析师、数据科学家和数据工程师)在面试时总会问到关于 SQL 的问题。 SQL面试问题旨在评估应聘者的技术和解决问题的能力。因此对于应聘者来说&#x…...

学大数据算跟风吗?
随着互联网、物联网和人工智能等技术的不断发展,大数据技术逐渐进入人们的视野,成为一个备受关注的热点话题。那么,大数据专业好学吗?前景如何?下面我们来一起探讨一下。 一、大数据专业的学习难度 大数据技术是一种综…...

[C#]关于ListBox的坑
在用C#写个Demo程序的时候,使用ListBox保存读取到的每行内容。然后在重复读取的时候需要清除ListBox中的内容,我看到ListBox有清除的函数:lsbFiles.Items.Clear();以为这个函数就可以解决所有的问题,但是....于是想了个方法准备一…...

Apache POI 入门·第一话
文章目录1 摘要2 Apache POI2.1 介绍2.2 应用场景2.3 入门案例2.3.1 将数据写入Excel文件2.3.1.1 导入POI maven坐标2.3.1.2 代码开发2.3.1.3 实现效果2.3.2 读取Excel文件中的数据2.3.3 实现效果2.4 开发案例——导出运营数据Excel报表2.4.1 产品原型2.4.2 接口设计2.4.3 代码…...

8个python自动化脚本提高打工人幸福感~比心~
人生苦短,我用Python 最近有许多打工人都找我说打工好难 每天都是执行许多重复的任务, 例如阅读新闻、发邮件、查看天气、打开书签、清理文件夹等等, 使用自动化脚本,就无需手动一次又一次地完成这些任务, 非常方便…...

【嵌入式烧录/刷写文件】-1-详解Motorola S-record(S19/SREC/mot/SX)格式文件
目录 1 什么是Motorola S-record 2 Motorola S-record的格式 2.1 Motorola S-record的结构 2.1.1 “Record type记录类型”的说明 2.1.2 “Record length记录长度”的说明 2.1.3 如何计算“Checksum校验和” 2.2 Record order记录顺序 2.3 Text line terminator文本行终…...

图形视图界面 图形效果
Qt的标准图形效果类: QGraphicsBlurEffect提供模糊效果QGraphicsColorizeEffect提供染色效果QGraphicsDropShadowEffect提供阴影效果QGraphicsOpacityEffect提供透明效果 QGraphicsBlurEffect(模糊效果) 模糊效果会模糊源。此效果对于减少细…...
ElementUI学习笔记
目录 一、简单介绍 二、安装 1、下载 2、引入 三、布局 1、简介 2、使用 3、好处 四、布局容器 1、常见排布 2、调整样式 五、按钮 1、简单引用 2、改变样式 3、加载中效果 六、表格 1、简单使用 2、样式修改 七、对话框 1、简单使用 2、添加自定义内容 3、…...

安装KVM并创建虚拟机及基本使用
#环境说明:Centos7 环境准备: CPU开启虚拟化,给宿主机的CPU和内存分配足够多的配置 安装KVM 1.安装相关软件包 yum -y install qemu-kvm libvirt virt-manager virt-install virt-viewer 软件包简介: qemu-kvm: 为kvm提供…...

一种LCD屏闪问题的调试
背景 项目使用ESP32-S3 RGB接口驱动的LCD, 框架 idf-v5.0, LVGL-v7.11 显示画面正常, 但肉眼可见的像是背光在闪烁, 背光电路是应用很久的经典电路, 且排查背光驱动无错, 但开机一段时间后, 闪烁会明显减轻 记录 这块屏的显示驱动芯片为ST7701S, 查看芯片手册有说明特定的上…...

Java程序运行在Docker等容器环境有哪些新问题?
第30讲 | Java程序运行在Docker等容器环境有哪些新问题? 如今,Docker 等容器早已不是新生事物,正在逐步成为日常开发、部署环境的一部分。Java 能否无缝地运行在容器环境,是否符合微服务、Serverless 等新的软件架构和场景&#x…...
C语言面试最常问的三个关键字
文章目录前言一,static关键字的作用二,const 关键字的作用2.1, 修饰局部变量2.2,修饰指针2.3, 修饰函数形参2.4,修饰函数的返回值三,volatile关键字的作用前言 面试的时候,C语言最常…...

【Linux】-初识Linux
作者:学Java的冬瓜 博客主页:☀冬瓜的主页🌙 专栏:【Linux】 分享:逆着光行走,任风吹雨打。 ——《起风了》 主要内容:Linux的一些最基本指令,Linux的小程序,Linux关于连…...

精选7个 Python 学习资源库,助你成为优秀的开发者
当你在学习编程时,很容易被大量的资源所吓到,不知道该从何开始。 GitHub 仓库是一个很好的起点,因为它们提供了一种非常实用的方式来了解实际的编程应用。你可以查看其他人的代码,并将其与自己的代码进行比较和学习。 当涉及到 …...

【大数据处理与可视化】三 、Pandas库的运用
【大数据处理与可视化】三 、Pandas库的运用实验目的实验内容实验步骤一、使用pandas库分别创建Series对象和DataFrame对象,并对创建的对象使用索引、排序等相关操作;练习DataFrame对象的统计计算和统计描述的功能。1&2、创建一个DataFrame(d…...

FPGA解码SDI视频任意尺寸缩放拼接输出 提供工程源码和技术支持
目录1、前言2、SDI理论练习3、设计思路和架构SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像缩放FDMA图像缓存实现拼接HDMI驱动4、vivado工程详解5、上板调试验证并演示6、福利:工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案&#…...
线索二叉树结构
线索二叉树结构1.线索二插树的作用2.线索二叉树的定义3.线索二叉树的结构4. 线索二叉树的操作4.1. 建立一棵中序线索二叉树4.2. 在中序线索二叉树上查找任意结点的中序前驱结点4.3. 在中序线索二叉树上查找任意结点的中序后继结点4.4. 在中序线索二叉树上查找任意结点在先序下的…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...