Cyuyanzhong的内存函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、memcpy函数的使用与模拟实现
  • 二、memmove函数的使用和模拟实现
  • 三、memset函数与memcmp函数的使用
    • (一)、memset函数(内存块设置)
    • (二)、memcmp函数(内存块比较)
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:


提示:以下是本篇文章正文内容,下面案例可供参考
前面已经介绍了关于字符串和单个字符的操作,本文主要介绍(任意类型)内存层面的操作函数,主要介绍
memcpy:内存拷贝
memmove:内存移动
memset:内存设置
memcmp:内存比较
这四类关于内存函数的 相关知识.它们的头文件都是<string.h>

一、memcpy函数的使用与模拟实现

  • 函数库函数原型:
void*memcpy(void*destination,const void*source,size_t num);

这个函数作用就是从source位置开始向后复制num个字节的数据到destination指向的内存位置。

  • 关于这个函数注意以下几点:
    num的单位是字节!!!一定要注意;
    这个函数在遇到’\0’的时候不会停下来
    如果source和destination有任何重叠,复制的结果是未定义,换句话说memcpy不负责重叠空间的拷贝!!,它只负责非重叠空间的拷贝,即destination和source所指向的空间没有重叠。
  • memcpy函数的使用
#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memcpy(arr2, arr1 + 2, 20);//计算的是字节数int sz = sizeof(arr2) / sizeof(int);for (int i = 0; i < sz; i++){printf("%d,", arr2[i]);}
}

运行结果:
在这里插入图片描述
这里很显然将arr1的数组中从3开始以后的20个字节内容(即4个整形)拷贝到arr2的前4个元素中。

  • memcpy函数的模拟实现
void* my_memcpy(void*dest,const void*src,size_t num)
{//转换成char*,一个字节一个节搞,这样我们可以照顾所有数据类型void* ret = dest;for (int i = 0; i < num; i++){*(char*)dest = *(char*)src;//这里不能用自加加,因为强转是临时型的。要展开来写//(char*)dest++;这种写法不可以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 };my_memcpy(arr2, arr1 + 2, 20);//计算的是字节数int sz = sizeof(arr2) / sizeof(int);for (int i = 0; i < sz; i++){printf("%d,", arr2[i]);}
}

运行结果如下:
在这里插入图片描述

  • 如果用memcpy处理重叠区域会出现bug的现象
void* my_memcpy(void*dest,const void*src,size_t num)
{//转换成char*,一个字节一个节搞void* ret = dest;for (int i = 0; i < num; i++){*(char*)dest = *(char*)src;//这里不能用自加加,因为强转是临时型的。要展开来写//(char*)dest++;这种写法不可以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 };my_memcpy(arr1+2, arr1, 20);//计算的是字节数int sz = sizeof(arr2) / sizeof(int);for (int i = 0; i < sz; i++){printf("%d,", arr2[i]);}
}

我们期待的结果是:
在这里插入图片描述
可实际结果如下:

在这里插入图片描述
这里就出现了用memcpy函数处理重叠空间arr1的时候,出现BUG的现象。我们的memcpy对处理重叠空间的结果不负责

二、memmove函数的使用和模拟实现

  • memmove 函数的原型:
void*memmove(void*destination,const void*source,size_t num);

关于memmove 函数注意:memmove比memcpy的功能更加强大,它除了可以处理非重叠空间的拷贝,更重要的是它可以处理重叠空间的拷贝,换句话说,如果源空间和目标空间出现重叠,就得使用memmove函数处理。

  • 函数的使用:
#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memmove(arr1, arr1+2, 20);int sz = sizeof(arr1) / sizeof(int);for (int i = 0; i < sz; i++){printf("%d,", arr1[i]);}
}

这里是在重叠空间arr1中进行的拷贝,故而用到memmove 函数
运行结果:
在这里插入图片描述

  • memmove 函数的模拟实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* dest,const void* src, size_t num)
{assert(dest && src);void* ret = dest;//从前向后拷贝if (dest < src){for (int i = 0; i < num; i++){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}//从后向前拷贝else{while (num--){//首先要找到第num个字节的地址*((char*)dest + num) = *((char*)src + num);}}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memmove(arr1, arr1+2, 20);int sz = sizeof(arr1) / sizeof(int);for (int i = 0; i < sz; i++){printf("%d,", arr1[i]);}}

我们通过分析可得,如果目标空间指针所指向的地址小于源空间指针所指向的地址,那么我们从前向后拷贝,可以避免数据覆盖的现象,如果目标空间指针所指向的地址大于源空间指针,那我们从后向前拷贝,可以有效避免数据覆盖的现象。
运行结果如下:
在这里插入图片描述

三、memset函数与memcmp函数的使用

(一)、memset函数(内存块设置)

  • memset函数的原型:
void*memset(void*ptr, int value, size_t num);

memset 是用来设置内存的,将内存中的值以字节为单位设置成想要的内容;
这里ptr指向要被填充内存块的指针;value 是要设置的内存值;num是要设置的字节个数为多少,这里都用void*指针是为了进行泛型编程,容纳所有数据类型。

  • memset函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "hello word";
memset(arr + 6, 'x', 4);
printf("%s\n", arr);
return 0;
}

这里我们从"hello word"的‘w’字符往后的4字符设置为’x’字符
运行结果如下:
在这里插入图片描述

(二)、memcmp函数(内存块比较)

  • memcmp函数原型:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

memcmp函数是用来比较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
返回值如下:
在这里插入图片描述

  • memcmp函数的使用
#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,6,5 };int ret1=memcmp(arr1, arr2, 12);int ret2=memcmp(arr1, arr2, 16);printf("%d\n", ret1);printf("%d\n",ret2);return 0;
}

很显然前三个整形数据arr1与arr2是相同的,而比较到第四个整形数据的时候,显然4<6,所以输出结果如下:
在这里插入图片描述

总结

本文主要介绍了C语言中几类内存函数——memcpy(内存拷贝)、memmove(内存移动)、memset(内存设置)、memcmp(内存比较).如有错误,请批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux shell编程学习笔记59: ps 获取系统进程信息,类似于Windows系统中的tasklist 命令

0 前言 系统进程信息是电脑网络信息安全检查中的一块重要内容&#xff0c;对于使用Linux和基于Linux作为操作系统的电脑来说&#xff0c;可以使用ps命令。 1 ps命令 的功能、格式和选项说明 1.1 ps命令 的功能 Linux 中的ps&#xff08;意为&#xff1a;process status&…

Chrome导出cookie的实战教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

leetcode刷题:vector刷题

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;leetcode刷题 1.只出现一次的数字 这道题很简单&#xff0c;我们只需要遍历一次数组即可通过异或运算实现。(一个数与自身异或结果为0&#xff0c;任何数与0异或还是它本身) class Solut…

WPF UI 3D 基本概念 点线三角面 相机对象 材质对象与贴图 3D地球 光源 变形处理 动作交互 辅助交互插件 系列三

WPF UI交互专题 平面图形 Path Drawing 绘图 渐变 Brush 矩阵 Transform 变形 阴影效果 模糊效果 自定义灰度去色效果 系列二-CSDN博客 1软件中的3D基本概念 WPF 中 3D 功能的设计初衷并非提供功能齐全的游戏开发平台。 WPF 中的 3D 图形内容封装在 Viewport3D 元素中&#x…

WPF自定义模板--Button

属性&#xff1a; TemplateBinding&#xff1a;用于在ControlTemplate中绑定到控件的属性&#xff0c;例如Background、BorderBrush等。TargetType&#xff1a;指定该模板应用于哪种控件类型。在这个例子中&#xff0c;是Button。 标准的控件模板代码&#xff1a; <Style…

借助 Aspose.Words,在 C# 中将 Word 转换为 Excel

有时我们会遇到需要将 Word 文档&#xff08;DOC 或 DOCX&#xff09;转换为 Excel 文档的任务。例如&#xff0c;这对于数据分析和报告很有用&#xff0c;或者如果您收到了任何文本数据并想将其转换为表格格式&#xff08;XLS 或 XLSX&#xff09;以便进一步工作。在本文中&am…

IAR工程目录移动报错(改变文件目录结构)

刚开始用IAR&#xff0c;记录一下。 工作中使用华大单片机&#xff0c;例程的文件目录结构太复杂了想精简一点。 1.如果原本的C文件相对工程文件&#xff08;.eww文件&#xff09;路径变化了&#xff0c;需要先打开工程&#xff0c;再将所有的.c文件右键Add添加进工程&#xf…

Day50

Spring AOP 概念 AOP全称为Aspect Oriented Programming&#xff0c;表示面向切面编程。切面指的是将那些与业务无关&#xff0c;但业务模块都需要使用的功能封装起来的技术。 AOP基本术语 **连接点&#xff08;Joinpoint&#xff09;&#xff1a;**连接点就是被拦截到的程序执…

第三篇——始计篇:诡计,就是引诱对方犯错误

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 这一篇讲解了诡计&#xff0c;对于诡计的解释和定位&#xff1b;我们更应…

win10下安装PLSQL14连接Oracle数据库

问题背景 在使用Oracle开发过程中&#xff0c;经常会使用工具来连接数据库&#xff0c;方便查询、处理数据。其中有很多工具可以使用&#xff0c;比如dbeaver、plsql等。本文主要介绍在win10环境下&#xff0c;plsql14的安装步骤以及安装过程中遇到的一些问题。 安装步骤及问题…

清爽一夏,羊大师伴你健康运动,引领活力生活!

在这个绚烂多彩的夏日&#xff0c;让我们携手踏上一段清爽与健康并行的旅程。阳光炽热&#xff0c;万物生长&#xff0c;正是释放活力、追求健康的最佳时节。“清爽一夏&#xff0c;健康运动引领活力生活&#xff01;”这不仅是一句口号&#xff0c;更是我们向美好生活发出的诚…

BurpSuite抓IOS设备HTTPS流量

一、简述&#xff1a; Burp 这个工具做过 web 安全的人都应该用过&#xff0c;是个非常强大的抓包工具。在 PC 的浏览器上直接配置代理就行了&#xff0c;本篇文章就来介绍一下如何用 Burp 抓 IOS 设备上的流量&#xff0c;很多文章都介绍过怎么抓包&#xff0c;但是很多坑都没…

试用笔记之-汇通计算机等级考试软件一级Windows

首先下载汇通计算机等级考试软件一级Windows http://www.htsoft.com.cn/download/htwork.rar

昇思25天学习打卡营第9天|FCN图像语义分割

FCN是Fully Convolutional Networks的简称&#xff0c;即全卷积网络。区别于全连接网络&#xff0c;全连接网络每层直接cell全部连接&#xff0c;全卷积网络即每层都进行卷积。全卷积网络不包含全连接层。 卷积说有点像缩放&#xff0c;具体的可以参考其他专门的介绍文章。 之…

pandas数据分析(4)

修改DataFrame数据的最简单的方法是通过loc和iloc属性为某些元素赋值。 首先构造一组数据 通过标签或位置设置值 也可以一次修改多个值&#xff1a; 通过布尔索引设置数据 将所有来自China&#xff0c;或者年龄20以下的人名字设置为匿名&#xff1a; 通过替换值设置数据 如果…

vue2项目的打包以及部署

打包 当我们写好vue2的项目后&#xff0c;可以通过npm build来对项目进行打包 npm build 打包完成后我们可以看到在当面目录下生成了dis目录,src下的文件都会被打包进这个目录里&#xff0c;当然打包后的文件我们不能直接在浏览器打开&#xff0c;需要进行部署 部署 1.新建一个…

RFID技术在粉末涂料配料生产线的精准应用

RFID技术在粉末涂料配料生产线的精准应用 应用背景 随着科技的快速发展&#xff0c;智能化、自动化已经成为现代工业生产的重要趋势。RFID&#xff08;无线射频识别&#xff09;技术以其独特的优势&#xff0c;如非接触式识别、高速读取、大容量数据存储等&#xff0c;在多个…

中国民间网络外交组织(CCND)

中国民间网络外交组织Chinese Civil Network Diplomacy简称(CCDN) 是由中国网民建立起来的一个网络外交组织&#xff0c;深度贯彻党的主张和网民意志的统一&#xff0c;为保护中国中华优秀传统文化&#xff0c;民族自信&#xff0c;国家安全&#xff0c;民族利益&#xff0c;社…

DICOM灰度图像、彩色图像的窗宽、窗位与像素的最大最小值的换算关系?

图像可以调整窗宽、窗位 dicom图像中灰度图像可以调整窗宽、窗位&#xff0c;RGB图像调整亮度或对比度&#xff1f;_灰度 图 调节窗宽-CSDN博客 窗宽、窗位与像素的最大最小值的换算关系? 换算公式 max-minWindowWidth; (maxmin)/2WindowCenter; 详细解释 窗宽&#xff0…

Michael.W基于Foundry精读Openzeppelin第61期——ERC1967Upgrade.sol

Michael.W基于Foundry精读Openzeppelin第61期——ERC1967Upgrade.sol 0. 版本0.1 ERC1967Upgrade.sol 1. 目标合约2. 代码精读2.1 _getImplementation() internal && _upgradeTo(address newImplementation) internal2.2 _upgradeToAndCall(address newImplementation,…