当前位置: 首页 > news >正文

C语言王国——内存函数

目录

1 memcpy函数

1.1 函数表达式

1.2 函数模拟

2 memmove函数 

2.1 函数的表达式

2.2 函数模拟 

3 memset函数

3.1 函数的表达式

3.2 函数的运用

4 memcmp函数

4.1函数的表达式:

4.2 函数的运用

5 结论

接上回我们讲了C语言的字符和字符串函数,今天也由姜糖来给大家分享一下C语言的内存函数吧!

1 memcpy函数

1.1 函数表达式

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

此函数是将source变量中num个字节赋值给destination

注意

  • 需包含头文件string
  • 遇到'\0'不会停下
  • 如果source和destination有任何重叠,复制的结果都是未定义的。

1.2 函数模拟

原理函数memcpy从cource的位置开始向后复制num个字节的数据到destination指向的内存位置

void* memcpy(void* destination, const void* source, size_t num)
{assert(destination && source);//断言是否为空指针char* ret = destination;//记录改变前的地址,以防丢失while (num--){*(char*)destination = *(char*)source;//因为是字节的改变所以强转为char*destination = (char*)destination + 1;source = (char*)source + 1;}return ret;
}int main()
{int arr[] = { 1,2,3,4,5,6 };int arr1[10] = { 0 };memcpy(arr, arr1, 12);int i;for (i = 0; i < 6; i++){printf("%d ", arr[i]);}return 0;
}

注意:

  1. 使用void*指针进行间接引用时,必须先将其转换为实际类型的指针。这里是改变字节,所以使用时改为char*。
  2. 重叠的就交给memmove处理。


2 memmove函数 

2.1 函数的表达式

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

*包含头文件string

用来处理memcpy处理不了的堆叠问题。

那什么是堆叠问题呢?

如果destination为source+1,num为12则,当source中的1赋值到destination上的2时,就导致了source中的2也变成了1,导致拷贝结果不对,这就是堆叠。

那堆叠该怎么解决呢?

在memcpy中我们使用的是从前往后拷贝,但是这里不行,所以我们使用从前往后拷贝,在数字被改变之前就完成拷贝的步骤。那是否从后往前拷贝就能解决所有问题呢?答案是不行的,比如:

如图,在arr数组上面将蓝色拷贝给黄色就会出错,所有我们在编写memmove中应该分类讨论。

那具体该怎么分类呢?

同样如图所示,设蓝色为source,若黄色首地址在蓝色前面则,从后往前拷贝;反之则从前往后。

2.2 函数模拟 

#include<stdio.h>
#include<assert.h>void* memmove(void* destination, const void* source, size_t num)
{assert(destination && source);char* ret = destination;if (destination < source)//从前往后{while (num--){*(char*)destination = *(char*)source;//因为是字节的改变所以强转为char*destination = (char*)destination + 1;source = (char*)source + 1;}}else//从后往前{*((char*)destination + num) = *((char*)source + num);}
}int main()
{int arr[] = { 1,2,3,4,5,6 };int arr1[10] = { 0 };memmove(arr, arr1, 12);int i;for (i = 0; i < 6; i++){printf("%d ", arr[i]);}return 0;
}

有些人可能会有疑惑,好像memcpy能干的,memmove能干,memcpy不能干的事,memcove也能干,那为什么存在memcpy呢?

memcpy()函数的实现相对于memmove()函数来说更简单、更高效。因为memcpy()不考虑内存重叠的情况,所以它在处理非重叠内存区域的数据复制时更快。而memmove()函数需要先判断内存区域是否重叠,再决定如何进行数据复制,所以相对来说会慢一些。

所以,当你确定要进行的数据复制操作不会涉及到内存重叠的情况时,可以选择使用memcpy()函数。而当你不能确定内存是否重叠,或者确实需要处理内存重叠的情况时,可以使用memmove()函数来确保正确的复制结果。

总而言之,memcpy()和memmove()都有各自的应用场景,你可以根据实际需求选择合适的函数。

姜糖也只能说存在即合理,其实如果想偷懒都用memmove就行啦。


3 memset函数

3.1 函数的表达式

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

此函数是将内存中的值以字节为单位设置成想要的内容。

包含头文件string。

3.2 函数的运用

#include<stdio.h>
#include<string.h>int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memset(arr, 0, 40);//将数组全部归0int i;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}char str[] = "Hello world";memset(str, 'x', 5);//将Hellw全部置为xputs(str);return 0;
}

输出结果为:


4 memcmp函数

4.1函数的表达式:

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

比较ptr1和ptr2指针指向的位置开始,向后num个字节

包含头文件string。

此函数和strncmp原理大致相同。

4.2 函数的运用

#include<stdio.h>
#include<string.h>int mian()
{char str1[] = "hello world";char str[] = "helloworld";int ret = memcmp(str1, str, 6);if (ret){printf("前6个一样");}elseprintf("前6个不一样");return 0;
}

输出结果:


5 结论

最后两个函数的模拟姜糖改为了函数的运用,意在让大家自己开动脑筋结合本文和前文的字符串函数的模拟自己去完成,因为他们都有异曲同工之妙。

接下来有什么问题可以私信姜糖哦。也希望大家能一键三连,谢谢大家了。最后就让我们一起进步吧!

相关文章:

C语言王国——内存函数

目录 1 memcpy函数 1.1 函数表达式 1.2 函数模拟 2 memmove函数 2.1 函数的表达式 2.2 函数模拟 3 memset函数 3.1 函数的表达式 3.2 函数的运用 4 memcmp函数 4.1函数的表达式&#xff1a; 4.2 函数的运用 5 结论 接上回我们讲了C语言的字符和字符串函数&#…...

【计算机组成原理】1.1计算机的软硬件组成(记录学习计算机组成原理)

文章目录 1.早期的冯诺依曼机2.早期冯诺依曼机的基本运行框图3.早期冯诺依曼机的特点4.现代计算机的结构5. 小结 本次及以后有关于计算机组成原理的文章&#xff0c;旨在做学习时的记录和知识的分享。不论是应对期末考试&#xff0c;还是考研都是很有帮助的。希望大家多多支持更…...

Qt xml学习之calculator-qml

1.功能说明&#xff1a;制作简易计算器 2.使用技术&#xff1a;qml,scxml 3.项目效果&#xff1a; 4.qml部分&#xff1a; import Calculator 1.0 //需要引用对应类的队友版本 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 1.4 import QtScxml…...

低代码开发系统是什么?它有那些部分组成?

低代码开发系统是什么&#xff1f;它有那些部分组成&#xff1f; 一、引言 在当今快速变化的商业环境中&#xff0c;企业对于快速响应市场需求、降低开发成本和提高开发效率的需求日益增强。低代码开发系统&#xff08;Low-Code Development Platform&#xff09;应运而生&am…...

2024年西安交通大学程序设计竞赛校赛

2024年西安交通大学程序设计竞赛校赛 文章目录 2024年西安交通大学程序设计竞赛校赛D瑟莉姆的宴会E: 雪中楼I: 命令行(待补)J&#xff1a;最后一块石头的重量(待补)K: 崩坏&#xff1a;星穹铁道(待补)M&#xff1a;生命游戏N: 圣诞树 D瑟莉姆的宴会 解题思路&#xff1a; ​ …...

【学习Day5】操作系统

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 学习编辑文章的时间不太够用&#xff0c;先放思维导图&#xff0c;后续复习完善细节。...

学习小记录——python函数的定义和调用

今日小好运&#xff0c;未来有好运。&#x1f381;&#x1f496;&#x1fad4; 分享个人学习的小小心意&#xff0c;一起来看看吧 函数的定义 函数通常来说就是带名字的代码块&#xff0c;用于完成具体的工作&#xff0c;需要使用的时候调用即可&#xff0c;这不仅提高代码的…...

RHEL7.9修改分区

系统RHEL7.9 他因为安装软件&#xff0c;需要修改分区 进入超级用户root&#xff0c;输入lsblk 查看分区&#xff0c;可见465.8G系统盘sda下有三个物理卷&#xff0c;其中sda3下/home有410.6G&#xff0c;需要这部分拆分出200G软件和100G的数据库分区 备份/home 目录下文件 c…...

【Linux】命名管道

一、命名管道的原理 在前面的博客中&#xff0c;我们学习了匿名管道&#xff0c;了解到了两个具有血缘关系的进程之间是如何进行通信的&#xff1f;那么在没有血缘关系&#xff08;毫不相关&#xff09;的进程之间是如何进行通信的&#xff1f; 大致思路是一样的&#xff0c;我…...

IMX6Q基于linux4.1.15调试音频芯片tas2505

IMX6Q基于linux4.1.15调试音频芯片tas2505 1、开发环境2、初步想法3、开发过程4、tas2505重要的寄存器5、遇到的问题1、开发环境 芯片:IMX6Q (NXP系列) 内核版本:linux4.1.15 Ubuntu版本:16.04 目标模块:tas2505 2、初步想法 由于该电路是由外部晶振提供的时钟频率24.5…...

卷积常用网络

目录 1.AlexNet2.VGG3.GoogleNet4.ResNet5.MobileNet 1.AlexNet AlexNet是2012年ISLVRC 2012&#xff08;ImageNet Large Scale Visual Recognition Challenge&#xff09;竞赛的冠军网络。 首次利用 GPU 进行网络加速训练。使用了 ReLU 激活函数&#xff0c;而不是传统的 Si…...

Firebase Local Emulator Suite详解

文章目录 Firebase Local Emulator Suite 组件安装和使用步骤1. 安装 Firebase CLI2. 初始化 Firebase 项目3. 配置模拟器4. 启动模拟器5. 配置应用程序使用本地模拟器 常见用途 Firebase Local Emulator Suite 是一组本地服务&#xff0c;可以模拟 Firebase 平台的在线服务&am…...

计算机组成原理·存储系统疑点归纳

组原这门课有点学得不是很懂&#xff0c;现在快考试了&#xff0c;挑几个做错了的题分析、记录一下。 N o . 1 \mathit{No}.1 No.1  x x x、 y y y 为定点整数&#xff0c;其格式为 1 1 1 位符号位、 n n n 位数值位&#xff0c;若采用补码一位乘法实现乘法运算&#xff0c;则…...

在 GPU 上实现全规模文件系统加速

摘要 现代高性能计算和人工智能计算解决方案经常使用 GPU 作为其主要计算能力来源。这就为 GPU 应用程序的存储操作造成了严重的不平衡&#xff0c;因为每一个此类存储操作都必须向 CPU 发出信号并由 CPU 处理。在 GPU4FS 中&#xff0c;我们针对这种不平衡提出了一个彻底的解决…...

代码随想录算法训练营Day7|454.四数相加II、 383. 赎金信、15. 三数之和、 18. 四数之和

454.四数相加II 四个数组分成两组进行for循环&#xff0c;先用HashMap存储所有第一组for循环出现的和的次数。再进行第二组for循环&#xff0c;每一次得出的和判断其负数是否在map的key中&#xff0c;如果存在&#xff0c;就加上这个value。 class Solution {public int four…...

编译器屏障概述

文章目录 1. 前言2. 编译器内存屏障2.1 编译器内存访问重排序规则2.2 编译器屏障的几种形式2.2.1 显式编译器屏障2.2.2 隐式编译器屏障2.2.3 硬件内存屏障充当编译屏障2.2.4 编程语言内存模型提供的编译屏障 2.3 编译器内存屏障实例2.3.1 Linux spinlock 3. 结语4. 参考资料 1.…...

RUST宏编程入门

宏指示符 在Rust的宏编程中&#xff0c;宏可以接受多种类型的参数&#xff0c;称为“指示符”。这些指示符帮助宏识别不同类型的代码片段&#xff0c;并相应地处理它们。 这里列出全部指示符&#xff1a; blockexpr 用于表达式ident 用于变量名或函数名itemliteral 用于字面常…...

linux安装srs

获取srs cd /opt git clone -b 4.0release https://gitee.com/ossrs/srs.git cd srs/trunk 启动srs ./objs/srs -c conf/srs.conf ./etc/init.d/srs status 访问http://192.168.220.146:8080/出现下方图片说明安装成功 点击进入SRS控制台看到下方图片...

IO流(2)

缓冲流 字节缓冲流 利用字节缓冲区拷贝文件&#xff0c;一次读取一个字节&#xff1a; public class test {public static void main(String [] args) throws IOException {//利用字节缓冲区来拷贝文件BufferedInputStream bisnew BufferedInputStream(new FileInputStream(&…...

【docker】docker启动bitnami/mysql

说明&#xff1a;-v 宿主机目录:docker容器目录&#xff0c;-p 同理 注意&#xff1a;/opt/bitnami/mysql/conf/bitnami 目录自定义conf的目录&#xff0c;不能使用原有的/opt/bitnami/mysql/conf 目录。 容器启动后可在宿主机的/宿主/mysql8.0/conf&#xff0c;添加my_custom.…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法

使用 ROS1-Noetic 和 mavros v1.20.1&#xff0c; 携带经纬度海拔的话题主要有三个&#xff1a; /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码&#xff0c;来分析他们的发布过程。发现前两个话题都对应了同一…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...

十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】

一、JSON简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;具有以下核心特性&#xff1a; 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...