【C语言】12.C语言内存函数
文章目录
- 1.memcpy使用和模拟实现
- 2.memmove使用和模拟实现
- 3.memset函数的使用
- 4.memcmp函数的使用
memcpy
:内存拷贝
memmove
:内存移动
memset
:内存设置
memcmp
:内存比较
1.memcpy使用和模拟实现
memcpy
:内存拷贝
void * memcpy ( void * destination, const void * source, size_t num );目标空间的地址 源空间的地址 被拷贝的字节个数
返回的是目标空间的起始地址
void*指针接收任意参数的地址
函数
memcpy
从source
的位置开始向后复制num
个字节的数据到destination
指向的内存位置。这个函数在遇到 ‘
\0
’ 的时候并不会
停下来。如果
source
和destination
有任何的重叠,复制的结果都是未定义的。
#include <stdio.h>
#include <assert.h>void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;void* ret = dest;assert(src && dest);while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };//将arr1中的34567拷贝到arr2中my_memcpy(arr2, arr1 + 2, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}
打印:
3 4 5 6 7 0 0 0 0 0
注意:对于重叠的内存,交给
memmove
来处理。重叠的意思就是:
my_memcpy(arr1 + 2, arr1, 20);
比如你想把
arr
数组里的某些数用arr
数组的某些数替换,这样会出问题。
例如:
void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;void* ret = dest;assert(src && dest);while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//我们的想法是:将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖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 1 2 1 8 9 10
打印这个玩意儿?怎么和猜的不一样呢?
1 2 3 4 5 6 7 8 9 10
程序里先把1替换了3
1 2 1 4 5 6 7 8 9 10
然后2替换了4
1 2 1 2 5 6 7 8 9 10
然后原来3位置的1替换了5
1 2 1 2 1 6 7 8 9 10
然后原来4位置的2替换了6
1 2 1 2 1 2 7 8 9 10
然后原来5位置的1替换了7
1 2 1 2 1 2 1 8 9 10
memcpy
函数不负责重叠内存的拷贝,只负责不重叠的内存,非要使用,结果就是未定义的。
不过说是这么说,有些时候memcpy
也能实现重叠内存的拷贝。我们可以认为memcpy
实现的拷贝不一定都对。所以重叠就用memmove
函数。
memmove
函数来处理重叠内存的拷贝。
2.memmove使用和模拟实现
memmove
:内存移动
void * memmove ( void * destination, const void * source, size_t num );
和
memcpy
的差别就是memmove
函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。
#include <string.h>int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖memmove(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
这个函数实际上就是实现src拷贝到dest。
如果是上面一种情况的话,我们可以先把3给1,然后把4给2,然后把5给3…这样就可以实现重叠内存的处理。(从前向后)
如果是中间一种情况的话,我们可以先把7给9,然后把6给8,然后把5给7…这样就可以实现重叠内存的处理。(从后向前)
如果是下面一种情况的话,我们可以按顺序把3给8,把4给9,把5给10…这样就可以实现重叠内存的处理。(从后向前)
两个紫色竖线表示的位置分别为
src
的起始位置和结束位置。这两根紫色竖线把情况分成了三种。
第一种情况是(从前向后)
第二种情况是(从后向前)
模拟实现:
void* my_memmove(void* dest, const void* src, size_t num) {void* ret = dest;assert(src && 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;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖my_memmove(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
3.memset函数的使用
memset
:内存设置
void * memset ( void * ptr, int value, size_t num );
memset
是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "hello world";memset (str,'x',6);printf(str);return 0;
}
打印:
xxxxxxworld
4.memcmp函数的使用
memcmp
:内存比较
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
返回值如下:
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}
打印:
0
因为前12个字节一样
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 13);printf("%d\n", ret);return 0;
}
打印:
-1
因为第13个字节不一样
相关文章:

【C语言】12.C语言内存函数
文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy:内存拷贝 memmove:内存移动 memset:内存设置 memcmp:内存比较 1.memcpy使用和模拟实现 memcpy:内存拷贝 void…...
Django:如何将多个数据表内容合在一起返回响应
一.概要 Django写后端返回响应时,通常需要返回的可能不是一个数据表的内容,还包括了这个数据表的外键所关联的其他表的一些字段,那该如何做才能把他们放在一起返回响应呢? 二.处理方法 在这里我有三个数据表 第一个是航空订单&…...

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!
6月18日,国家信息安全漏洞库(CNNVD)2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现,被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…...

uni-app中使用富文本rich-text个人经验
rich-text是在uni-app一个内置组件,用于高性能地渲染富文本内容。先贴一下官方的属性列表: 先说一下“selectable” 长按选择区域复制,这个我在APP项目中 不起作用,可能像文档说的,只支持“百度小程序”吧。在APP端起作…...

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化
1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词:选址定容 电动汽车 充电站位置 仿真平台:MATLAB 主要内容:代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题,提出了能够计及地理因素和服…...

从零开始! Jupyter Notebook的安装教程
🚀 从零开始! Jupyter Notebook的安装教程 摘要 📄 Jupyter Notebook 是一个广受欢迎的开源工具,特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤,包括各种操作系统的安装方法&am…...
web前端信息卡:深入探索与实用指南
web前端信息卡:深入探索与实用指南 在数字化时代,web前端信息卡已成为我们日常生活和工作中的重要组成部分。这些小巧而强大的工具,能够在有限的空间内展示丰富的信息,提升用户体验。然而,设计一个出色的web前端信息卡…...

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!
天津工业大学(Tiangong University),简称“天工大”,位于天津市,是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…...

WPF三方UI库全局应用MessageBox样式(.NET6版本)
一、问题场景 使用HandyControl简写HC 作为基础UI组件库时,希望系统中所有的MessageBox 样式都使用HC的MessageBox,常规操作如下: 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…...

ABAP-03基础数据类型
基本数据类型 数据类型默认大小(byte)有效大小初始值说明示例C11-65535SPACE文本字符(串)‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…...

Zabbix监控神通数据库教程
作者:乐维社区(forum.lwops.cn) 乐乐 神通数据库,即神舟通用数据库(ShenTong Database),是我国自主研发的一款关系型数据库管理系统。它在国内市场有一定的应用,尤其是在一些对数据安…...

5.音视频基础 FLV
目录 简说FLV FLV Header FLV Body Tag Header 编辑Tag Data Audio Data Video Data Script Data 简说FLV FLV格式可以包含音频、视频和文本数据,并且可以在网络上进行流媒体传输。优点是文件大小较小,压缩效率高,并且可以在较低…...

Ubuntu server 24 (Linux) 安装客户端(windows/linux) Zabbix 7.0 LTS Zabbix agent2
一 Ubuntu(linux)安装客户端 1 Ubuntu 24 安装Zabbix agent2 #安装agent库 sudo wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-1ubuntu24.04_all.deb sudo dpkg -i zabbix-release_7.0-1ubuntu24.04_all.deb sudo apt u…...
在 Ubuntu 上取消登录密码和锁屏功能的简易指南
你可以使用终端命令来直接设置取消登录密码和锁屏功能。以下是具体步骤: 取消登录密码 打开终端。编辑 /etc/gdm3/custom.conf 文件:sudo nano /etc/gdm3/custom.conf在 [daemon] 部分下,添加或修改以下行:AutomaticLoginEnable…...
PAT B1046. 划拳
题目描述 划拳是中国酒文化中一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。…...

奥特曼谈AI的机遇、挑战与人类自我反思:中国将拥有独特的大语言模型
奥特曼在对话中特别提到,中国将在这个领域扮演重要角色,孕育出具有本土特色的大语言模型。这一预见不仅彰显了中国在全球人工智能领域中日益增长的影响力,也预示着未来技术发展的多元化趋势。 ①奥特曼认为AI在提升生产力方面已显现积极作用&…...
Java版-剑指offer数据结构与算法 视频教程 下载
Java版-剑指offer数据结构与算法 视频教程 下载 01-数据结构与算法入门基础 clip.mp4 02-clip1.mp4 03-clip2.mp4 04-基础数据结构:数组&链表(一).mp4 05基础数据结构:数组&链表(二).mp4 06-基…...

mac禁用电池睡眠-mac盒盖连接显示器
mac禁用电池睡眠-mac盒盖连接显示器-mac断点盒盖连接显示器 讲解:mac盒盖的时候连接显示器会睡眠并断开和显示器的连接,只有在电池->选项->选择使用电源适配器的时候防止睡眠,才可以连接电源线外界显示器 但是苹果的电池相当于手机电…...

最好用的智能猫砂盆存在吗?自用分享智能猫砂盆测评!
在现代都市的忙碌生活中,作为一名上班族,经常因为需要加班或频繁出差而忙碌得不可开交。急匆匆地出门,却忘了给猫咪及时铲屎。但是大家要知道,不及时清理猫砂盆会让猫咪感到不适,还会引发各种健康问题,如泌…...
LeetCode 每日一题 2748. 美丽下标对的数目
Hey编程小伙伴们👋,今天我要带大家一起解锁力扣上的一道有趣题目—— 美丽下标对的数目 - 力扣 (LeetCode)。这不仅是一次编程挑战,更是一次深入理解欧几里得算法判断互质的绝佳机会!🎉 问题简介 题目要求我们给定一…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...

从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...