当前位置: 首页 > 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.…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...