【C语言】memcpy , memset等内存操作函数使用方法与注意事项
这个章节,我们探讨C语言内存操作函数。
重点介绍处理内存操作函数使用和注意事项
和内存函数如何模拟实现。
内存函数所需头文件
#include<string.h>
文章目录
- memcpy
- memcpy 函数模拟实现
- memmove
- memmove 函数模拟实现
- memcmp
- memcmp 函数模拟实现
- memset
- memset 函数模拟实现
memcpy
从source的位置开始向后复制num个字节的数据到destination的内存位置
void * memcpy ( void * destination, const void * source, size_t num );
参数说明:destination: 指向用于存储复制内容的目标数组 。
source: 指向将要复制的数据。
num: 复制的字节个数
返回值:
返回一个指向 destination 首元素地址的指针
注意事项:
- 这个函数在遇到 ‘\0’ 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
- 只要处理 不重叠的内存拷贝就可以
函数使用方法:
#include<stdio.h>
#include<string.h>
typedef struct Stu
{char nane[20];int age;
}T;
int main()
{T t[3] = { {"张三",20},{"李四",30},{"小刘",40} };T s[4] = { 0 };memcpy(s, t, sizeof(t));//把t[3]的内容 拷贝到s里面int i = 0;for (i = 0; i < 3; i++){printf("%s %d\n", s[i].nane, s[i].age);}return 0;
}
最终的输出结果:
张三 20
李四 30
小刘 40
memcpy 函数模拟实现
比较num个字节,把他转换成(char*)每次+1转换一个字节,直到转换num个字节。
#include<stdio.h>
#include<string.h>
void* my_memcpy(void* arr1, void* arr2, int num)
{assert(arr1 && arr2);void* ret = arr1;while (num--){*((char*)arr1) = *((char*)arr2);(char*)arr1 = (char*)arr1 + 1;(char*)arr2 = (char*)arr2 + 1;}return ret;
}
memmove
memmove 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同
void * memmove ( void * destination, const void * source, size_t num );
参数说明:
- 指向用于存储复制内容的目标数组 。
- source: 指向将要复制的数据
- num: 复制的字节个数
返回值:
返回一个指向 destination 首元素地址的指针
注意事项:
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
函数的使用方法:
#include<stdio.h>
#include<string.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int i = 0;memmove(arr + 2, arr, 20);for (i = 0; i < 9; i++){printf("%d ", arr[i]);}return 0;
}
最终的输出结果:
1 2 1 2 3 4 5 8 9
memmove 函数模拟实现
memmove函数的实现分两个部分,因为存在内存覆盖的情况,如果arr2首元素地址大于arr1首元素地址,那肯定需要从前往后拷贝,反之后往前即可。
void* my_memmove(void* arr1, void* arr2, int num)
{assert(arr1 && arr2);char* ret = arr1;if (arr1 < arr2){while (num--){//从前往后*((char*)arr1) = *((char*)arr2);(char*)arr1 = (char*)arr1 + 1;(char*)arr2 = (char*)arr2 + 1;}}else{//从后往前while (num--){*((char*)arr1 + num) = *((char*)arr2 + num);}}return ret;
}
memcmp
内存存储的字节 str1 和 内存存储的字节 str2 的前 num 个字节进行比较
int memcmp(const void *str1, const void *str2, size_t num)
参数说明:str1: 指向str1内存块的指针
str2: 指向str2内存块的指针
num: 要比较字节的个数
返回值:
- str1 大于 str2,则返回大于0的数字
- str1 等于str2 ,则返回0
- str1 小于 str2,则返回小于0的数字
函数的使用方法:
#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4};int arr2[] = { 1,2,3,5};int ret = memcmp(arr1, arr2, 20);printf("%d\n", ret);return 0;
}
memcmp 函数模拟实现
int my_memcmp(void* arr1, void* arr2, int num)
{assert(arr1 && arr2);while (*((char*)arr1) == *((char*)arr2) && num--){(char*)arr1 = (char*)arr1 + 1;(char*)arr2 = (char*)arr2 + 1;}if (*((char*)arr1) > *((char*)arr2)){return 1;}else if (*((char*)arr1) < *((char*)arr2)){return -1;}else{return 0;}
}
memset
复制字符 c(一个无符号字符)到参数 str 所指向地址。复制num个字节
void *memset(void *str, int c, size_t num)
参数说明:str: 指向要复制的的内存块地址
c: 是要被设置的值
num: 要复制多少个字节的个数
返回值:
返回指向srr首元素地址的指针
注意事项:
- 不能任意赋值,memset函数是按照字节对内存块进行初始化,如果是int类型的数组,只能初始化0或者-1.
- 注意memset,是按字节来复制的,而不是按元素个数,经常有人在这里出错。
函数的使用方法:
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "abcdef";memset(arr, '#', 4);printf("%s\n", arr);return 0;
}
memset 函数模拟实现
void* my_memset(void* arr, int set, int num)
{
assert(arr);
void* ret = arr;
while (num--)
{
*((char*)arr) = (char)set;
(char*)arr = (char*)arr + 1;
}
return ret;
}
相关文章:
【C语言】memcpy , memset等内存操作函数使用方法与注意事项
这个章节,我们探讨C语言内存操作函数。 重点介绍处理内存操作函数使用和注意事项 和内存函数如何模拟实现。 内存函数所需头文件 #include<string.h> 文章目录memcpymemcpy 函数模拟实现memmovememmove 函数模拟实现memcmpmemcmp 函数模拟实现memsetmemset 函…...
尚融宝04-mybatis-plus插件和条件构造器
目录 一、分页插件 1、添加配置类 2、添加分页插件 3、测试分页 二、XML自定义分页 1、UserMapper中定义接口方法 2、定义XML 3、测试 三、乐观锁 1、场景 2、乐观锁方案 3、乐观锁实现流程 4、优化流程 四、wapper介绍 1、Wrapper家族 2、创建测试类 五、Qu…...
面试重难点问题(C++)
持续更新!!!!! 网络部分 1.问,四次挥手的过程,和双方状态变化? 挥手这前,两边都是established状态,客户端发起断开请求,向服务器发送fin请求&…...
androidx.appcompat 升级到1.5.1 趟过的坑
APP 要上google play,Android SDK 版本要升级到32;接了一个第三方SDK,不巧的是这个SDK引用appcompat是1.5.1,顺手把appcompat 包升级到1.5.1,这草率的一升,带来的不止一地鸡毛,还有精神上被残忍…...
[C++]反向迭代器
目录 前言: 1 对反向迭代器的构造思想 2 实现反向迭代器 3 完整代码 前言: 本篇文章主要介绍了STL容器当中的反向迭代器,可能有朋友会说:“反向迭代器有什么好学的?不一样还是迭代器吗,我正向能写出来&…...
解析Python编程中的包结构
假设你想设计一个模块集(也就是一个“包”)来统一处理声音文件和声音数据。通常由它们的扩展有不同的声音格式,例如:WAV,AIFF,AU),所以你可能需要创建和维护一个不断增长的各种文件格…...
【前端】深入浅出缓存原理
缓存的基本原理 对于前端来说,缓存主要分为浏览器缓存(比如 localStorage、sessionStorage、cookie等等)以及http缓存,也是本文主要讲述的。 当然叫法也不一样,比如客户端缓存大概包括浏览器缓存和http缓存 所谓htt…...
单调栈图文详解(附Java模板)
🍏🍐🍊🍑🍒🍓🫐🥑🍋🍉🥝 啥是"单调栈",它能解决什么样的问题? 文章目录🦩单调栈的概念&a…...
彻底理解Session、Cookie、Token,入门及实战
文章目录Session Cookie的使用Token的使用Session Cookie的使用 1. Session存储数据 HttpSession session request.getSession(); //Servlet底层通过的SESSIONID,获取Session对象。 session.setAttribute("loginTime",new Date()); out.println(&q…...
为什么运营商大数据可以精准获客?
“获客难”,“获客成本高”,一直是困扰企业的大问题,身边的许多朋友在吐槽客户的意向度不高,总是无法成交,员工非常积极主动去跟踪客户了,但始终事倍功半,这就像是老人们常说的一句老话“热脸贴…...
【数据结构】栈的实现
💯💯💯 本篇主要利用数组来实现栈,对于栈的各种操作都作详细介绍,压栈,出栈以及获取栈中元素的操作都是学习栈的必备知识,快来学起来吧!!!©Ⅰ.栈的概念及…...
【链表OJ题(六)】链表分割
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(六)1. 链表…...
C++类中的三大函数(构造,析构,拷贝)
下面一段话与大家共勉:每个人的一生都会遇到很多边界,有些边界可以突破,有些则不能。那些无法突破的边界就是你的极限,而划分边界的标准就是“阈值”。每次突破阈值之后,人生轨迹就会发生剧烈变化,其间需要…...
【2024考研】计算机考研,4轮复习时间安排
文章目录🎨第1轮复习(暑假前&系统课)英语1/2数学1/2专业课408🎨第2轮复习(开学前&真题)英语1/2试卷数学1/2试卷专业课408试卷🎨第3轮复习(报名前&政治)政治试…...
(十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
系列文章: python网络爬虫专栏 目录 序言 本节学习目标 特别申明 4.7 使用BeautfulSoup解析h...
【经验】项目管理:瀑布式、Scrum
1、瀑布式开发 流程关键词关键人员输出立项简述、周期、预算领导立项申请表、立项评审表策划计划项目经理、QA、CM各种计划书(项目、配置、测试等),评审需求功能项目经理功能列表、需求规格书、需求开发计划等,评审设计UML开发设…...
Learning C++ No.17【STL No.7】双端队列
引言: 北京时间:2023/3/17/7:18,刚刚快乐的早锻炼回来(不对 ,应该说回来有一会了),因为此时我已经吃完早饭,洗过澡了;现在回想起上学期,就算是第二天需要晨跑…...
Snackbar
1.简介 位于底部的提示View 支持侧滑消失 同一时间只有一个 不支持跨Activity展示 国内使用率很低 2.基础使用 2.1 基本展示 Snackbar.make(view, "Content", Snackbar.LENGTH_LONG).show()2.2 设置点击事件 注意不设置点击事件回调,点击按钮的文字不…...
HummerRisk 使用教程:主机检测
1. 概述 HummerRisk 是开源的云原生安全平台,以非侵入的方式解决云原生环境的安全和治理问题。核心能力包括混合云的安全治理和容器云安全检测。 本文将介绍HummerRisk中的主机检测部分功能,包括如何管理主机、管理凭证,以及使用主机检测规…...
【Arduino无线气象站项目】
【Arduino无线气象站项目】 1. 概述2. Arduino无线气象站电路图3. 定制设计电路板4. Arduino无线气象站代码5. 总结1. 概述 使用DHT22传感器测量室外温度和湿度,并使用NRF24L01收发器模块将这些数据无线发送到室内机。在室内机,还有另一个用于测量室内温度和湿度的DHT22传感…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
