Cyuyanzhong的内存函数

news2024/10/6 6:44:37

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

文章目录

  • 前言
  • 一、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.coloradmin.cn/o/1875343.html

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

相关文章

Qt creator实现一个简单计算器

目录 1 界面设计 2 思路简介 3 代码 目录 1 界面设计 ​2 思路简介 3 代码 3.1 widget.h 3.2 widget.c 4 完整代码 在这里主要记载了如何使用Qt creator完成一个计算器的功能。该计算器可以实现正常的加减乘除以及括号操作&#xff0c;能实现简单的计算器功能。 1 界…

.NET使用CsvHelper快速读取和写入CSV文件

前言 在日常开发中使用CSV文件进行数据导入和导出、数据交换是非常常见的需求&#xff0c;今天我们来讲讲在.NET中如何使用CsvHelper这个开源库快速实现CSV文件读取和写入。 CsvHelper类库介绍 CsvHelper是一个.NET开源、快速、灵活、高度可配置、易于使用的用于读取和写入C…

Spring Boot集成vavr快速入门demo

1.什么是vavr&#xff1f; 初闻vavr&#xff0c;感觉很奇怪&#xff0c;咋这个名字&#xff0c;后面看到它的官网我沉默了&#xff0c;怀疑初创团队付费资讯了UC震惊部如何取名字&#xff0c;好家伙&#xff0c;vavr就是java这四个字倒过来&#xff0c;真的是’颠覆’了java……

如何成为-10x工程师:反向教学大数据开发实际工作中应如何做

10x 工程师可能是神话&#xff0c;但 -10x 工程师确实存在。要成为 -10x 工程师&#xff0c;只需每周浪费 400 小时的工程时间。结合以下策略&#xff1a; 目录 如何使 10 名工程师的输出无效化改变需求大数据开发示例 创建 400 小时的繁忙工作任务示例大数据开发示例 创建 400…

心理辅导平台系统

摘 要 中文本论文基于Java Web技术设计与实现了一个心理辅导平台。通过对国内外心理辅导平台发展现状的调研&#xff0c;本文分析了心理辅导平台的背景与意义&#xff0c;并提出了论文研究内容与创新点。在相关技术介绍部分&#xff0c;对Java Web、SpringBoot、B/S架构、MVC模…

Unable to get expected results using BM25 or any search functions in Weaviate

题意&#xff1a;使用 Weaviate 中的 BM25 或任何搜索函数都无法获得预期结果 问题背景&#xff1a; I have created a collection in Weaviate, and ingested some documents into the Weaviate database using LlamaIndex. When I used the default search, I found that it…

高精度除法的实现

高精度除法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的这篇博客&#xff1a;高精度加法计算的实现 在这里就不再详细讲解&#xff0c;只讲解主体过程qwq 主体过程 高精度除法的原理和小学学习的竖式除法是一样的。 …

Chrome导出cookie的实战教程

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

备份SQL Server数据库并还原到另一台服务器

我可以将SQL Server数据库备份到另一台服务器吗&#xff1f; 有时您可能希望将 SQL数据库从一台服务器复制到另一台服务器&#xff0c;或者将计算机复制到计算机。可能的场景包括测试、检查一致性、从崩溃的机器恢复数据库、在不同的机器上处理同一个项目等。 是的&#xff0c…

Vue+Proj4Leaflet实现地图瓦片(Nginx代理本地地图瓦片为网络url)加载并实现CRS投影转换(附资源下载)

场景 Leaflet中加载离线OSM瓦片地图(使用OfflineMapMaker切割下载离线png地图文件)&#xff1a; Leaflet中加载离线OSM瓦片地图(使用OfflineMapMaker切割下载离线png地图文件)_offline map maker-CSDN博客 Leaflet快速入门与加载OSM显示地图&#xff1a; Leaflet快速入门与…

等保测评练习卷14

等级保护初级测评师试题14 姓名&#xff1a; 成绩&#xff1a; 判断题&#xff08;10110分&#xff09; 1. 方案编制活动中测评对象确定、测评指…

sql想查询一个数据放在第一个位置

sql想查询一个数据放在第一个位置 背景:比如在查询后台账号的时候想将管理员账号始终放在第一个,其他账号按照创建时间倒序排序, 可以这样写sql: SELECTid,create_time FROMuser ORDER BY CASEWHEN id 1 THEN1 ELSE 2 END ASC, create_time DESC 运行截图: 可以看到id…

企业源代码加密软件丨透明加密技术是什么

在一个繁忙的软件开发公司中&#xff0c;两位员工小李和小张正在讨论源代码安全的问题。 “小张&#xff0c;你有没有想过我们的源代码如果被泄露了怎么办&#xff1f;”小李担忧地问。 “是啊&#xff0c;这是个大问题。源代码是我们的核心竞争力&#xff0c;一旦泄露&#…

CentOS 8 Stream 上安装 Docker 遇到的一些问题

curl 命令无法连接到 URL&#xff0c;可能是由于网络问题或 IPv6 配置问题。我们可以使用以下方法来解决这个问题&#xff1a; 强制使用 IPv4&#xff1a; 尝试使用 curl 强制使用 IPv4 进行连接&#xff1a; curl -4 -fsSL https://get.docker.com -o get-docker.sh 检查网络…

Python28-2 机器学习算法之SVM(支持向量机)

SVM&#xff08;支持向量机&#xff09; 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种用于分类和回归分析的监督学习模型&#xff0c;在机器学习领域中被广泛应用。SVM的目标是找到一个最佳的分割超平面&#xff0c;将不同类别的数据分开&…

【详细】CNN中的卷积计算是什么-实例讲解

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、 CNN的基础卷积计算1.1.一个例子了解CNN的卷积计算是什么1.2.卷积层的生物意义 二、卷积的拓展&#xff1a;多输入通道与多输出通道2.1.多输入通道卷积2.2.多输出通道卷积 三、卷积的实现3.1.pytorch实现卷积…

夏令营1期-对话分角色要素提取挑战赛-第①次打卡

零基础入门大模型技术竞赛 简介&#xff1a; 本次学习是 Datawhale 2024 年 AI 夏令营第一期&#xff0c;学习活动基于讯飞开放平台“基于星火大模型的群聊对话分角色要素提取挑战赛”开展实践学习。 适合想 入门并实践大模型 API 开发、了解如何微调大模型的学习者参与 快来…

Windows系统开启自带虚拟机功能Hyper-V

前言 最近有小伙伴咨询&#xff1a;Windows系统上有自带的虚拟机软件吗&#xff1f; 答案肯定是有的。它就是Hyper-V&#xff0c;但很多小伙伴都不知道怎么打开这个功能。 今天小白就带大家来看看如何正确打开这个Windows自带的虚拟机功能Hyper-V。 开始之前&#xff0c;你…

基于STM32的智能花园灌溉系统

目录 引言环境准备智能花园灌溉系统基础代码实现&#xff1a;实现智能花园灌溉系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;花园灌溉管理与优化问题解决方案与优化收尾与总结 1. 引言 智能花园灌溉系统通过使用ST…

PacBio or Nanopore:测序技术简单对比

前言 在基因组学和生命科学领域&#xff0c;追求知识的旅程不断演变&#xff0c;由揭示DNA和RNA奥秘的技术创新推动。我们熟知的两大测序技术——PacBio和Nanopore&#xff0c;正位于这一领域的前沿。这些由 Pacific Biosciences 和 Oxford Nanopore Technologies 分别开发的先…