【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)。这不仅是一次编程挑战,更是一次深入理解欧几里得算法判断互质的绝佳机会!🎉 问题简介 题目要求我们给定一…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...