一篇文章让你搞懂内存函数

news2024/11/25 12:27:56

在这里插入图片描述

内存操作函数

memcpy

库函数memcmp介绍
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 ‘\0’ 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。
库函数memcmp的代码形式

void * memcpy ( void * destination, const void * source, size_t num );

看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	//将arr1中的内容,拷贝到arr2中
	memcpy(arr2, arr1, 40);
         //int*  int*
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

memcmp将arr1中的内容拷贝到arr2中,总共10个元素,每个元素为整型—40个字节
通过循环遍历拷贝过后的arr2数组,前十位为拷贝的数数字,后10个元素补0即可
对于float类型的memcmp同理

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
	float arr1[] = { 1.0,2.0,3.0 };
	float arr2[5] = { 0 };
	//将arr1中的内容,拷贝到arr2中
	memcpy(arr2, arr1, 8);
	//    float* float*
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%f ", arr2[i]);
	}
	return 0;
}

因为memcmp对于浮点数,整型都可以进行拷贝,所以我们将memcmp的函数参数的类型设计成void星
当我们明白的这个库函数的基本原理,现在我们模拟实现一下库函数memcmp
先直接看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
//函数拷贝结束后,返回目标空间的起始地址
void* my_memcpy(void* dest, const void* src, size_t num)
{
	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 };
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1, 40);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

根据库函数的参数类型基本形式我们将my_memcmp的函数的参数的返回类型设计成void星,size_t sum是字节所占的大小,函数my_memcmp的返回类型也为void星
num–直到为0—为假的时候循环停下来,这里我们将void*转化为char星目的是为了访问到每一个字节,如果强制类型转化为int星,每一次访问4个字节,就不能挨个挨个访问到40个字节,其他类型也不行,所以char星为最优解
下面有一个特例
看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	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 };
	//             1 2 1 2 3 4 5 8 9 10
	my_memcpy(arr1+2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

打印的结果是什么呢?
在这里插入图片描述
为什么打印这个结果呢?
当你去拷贝3的时候3已经被置换成1了,当你去拷贝4的时候,4已经被置换成为2了,所以就打印了上图的结果
总结:memcmp库函数是用来处理不重叠的内存拷贝的
那么为了解决这个问题,我们引入了库函数memmove

memmove

库函数memmove介绍
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
如果源空间和目标空间出现重叠,就得使用memmove函数处理
库函数memmove的代码形式

void * memmove ( void * destination, const void * source, size_t num );

看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);

	if (dest < src)
	{
		//前->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (num--)//20
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//             1 2 1 2 3 4 5 8 9 10
	my_memmove(arr1, arr1+2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

对于my_memmove需要特别注意一个点,就是我的源数据和被拷贝到的目标数据
以图片的形式展现出来
在这里插入图片描述

memcmp

库函数memcmp介绍
比较从ptr1和ptr2指针开始的num个字节
返回值如下:
在这里插入图片描述

int main()
{
	int arr1[] = { 1,2,1,4,5,6 };
	int arr2[] = { 1,2,257 };
	int ret = memcmp(arr1, arr2, 10);
	printf("%d\n", ret);
	return 0;
}

案例

/* memcmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";
  int n;
  n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
  if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
  else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
  else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
  return 0;
}

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

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

相关文章

Ubuntu使用Samba设置共享文件夹提示“拒绝访问”的解决办法一

问题&#xff1a;看图片 IP正确&#xff0c;用户名也对。 解决&#xff1a;重新设置密码 sudo smbpasswd -a topeet 添加成功

详解CAS算法

CAS的全称是 Compare And Swap&#xff08;比较并交换&#xff09;&#xff0c;它是并发编程中的一个重要概念。本文结合Java的多线程操作来讲解CAS算法。 CAS算法的优势是可以在不加锁的情况下保证线程安全&#xff0c;从而减少线程之间的竞争和开销。 目录 一、CAS算法的内…

979. 在二叉树中分配硬币(力扣)

在二叉树中分配硬币 题目一题一解&#xff1a;DFS(java)思路步骤解析测试代码复杂度分析运行结果 优化代码思路测试代码运行结果复杂度分析 题目 给你一个有 n 个结点的二叉树的根结点 root &#xff0c;其中树中每个结点 node 都对应有 node.val 枚硬币。整棵树上一共有 n 枚…

韦东山-BeagleV-Ahead TH1520 RISC-V 高性能开发板开箱硬件评测

BeagleV-Ahead开箱硬件讲解 BeagleV-Ahead开箱介绍 非常感谢 中国杭州平头哥半导体优先公司 和 Beagle社区给予我们 全球首款高性能 TH1520 RISC-V SBC开发板 BeagleV-Ahead评测工作&#xff0c;我们将围绕 开发板 外观 &#xff0c;板载功能接口&#xff0c;系统启动系统初体…

AcWing 107. 超快速排序—逆序对

问题链接: AcWing 107. 超快速排序 问题描述 分析 这道题考查的算法不难&#xff0c;就只是利用归并排序来求逆序对的数量&#xff0c;但是主要是如何分析问题&#xff0c;如何能从问题中看出来和逆序对数量有关&#xff0c;现在的题目基本上很少是那种模板算法题了&#xff…

力扣21. 合并两个有序链表

题目 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 链接&#xff1a;21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 题解 设置两个指针head和tail&#xff0c;head用来指向新链表的头结点&#xff0c;tail…

HCIA初级考试题目(复制粘贴命令修改满分试卷)

要求&#xff1a; &#xff08;设备名称按照拓扑标识修改&#xff0c;注意区分大小写&#xff09; 1、ISP路由器仅配置IP地址 2、test-1和test-2仅作为代替终端设备进行测试使用&#xff0c;路由采用静态路由 3、R1/R2之间使用OSPF做到内网全通&#xff0c;单区域&#xff0c;O…

3.6.cuda运行时API-共享内存的学习

目录 前言1. 共享内存2. shared memory案例3. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习精简 CUDA 教程-共享…

前端vue入门(纯代码)32_编程式路由导航

星光不问赶路人&#xff0c;时光不负有心人 【30.Vue Router--编程式导航】 除了使用 <router-link> 创建 a 标签来定义导航链接&#xff0c;我们还可以借助 $router 的实例方法&#xff0c;通过编写代码来实现。 编程式路由导航的5种方法 我们先看一下组件实例中的t…

掌握这几招,让你的CTA按钮更吸引人点击

CTA全称Call-To-Action&#xff0c;是行为召唤按钮&#xff0c;是App和网页设计中的关键元素。 在落地页设计制作中&#xff0c;CTA按钮是用户在访问页面后引导用户去点击并且跳转至下一个流程&#xff08;如购买、联系、提交等行为&#xff09;的按钮控件。其核心目标是引导用…

函数图形化显示练习(进阶)

运行代码: //函数图形化显示练习&#xff08;进阶&#xff09; #include"std_lib_facilities.h" #include"GUI/Simple_window.h" #include"GUI/GUI.h" #include"GUI/Graph.h" #include"GUI/Point.h" //定义函数 double one…

【Spring Cloud系列】Hystrix应用详解

【Spring Cloud系列】Hystrix应用详解 文章目录 【Spring Cloud系列】Hystrix应用详解一、概述二、什么是Hystix三、Hystrix作用四、Hystrix设计原则五、Hystrix实现原理5.1 隔离5.2 熔断5.3 降级服务降级主要用于什么场景呢实现服务降级需要考虑几个问题降级分类 5.4 缓存请求…

使用Hugging Face预训练Bert处理下游任务显存占用过多

在使用HuggingFace的transformer下的BertForMaskedLM进行预训练语言模型的load时&#xff0c;bert会占用很大的显存。 这里可以考虑使用TinyBERT&#xff0c;速度和显存上都能得到很大的优化。 具体的方法进入https://huggingface.co/huawei-noah/TinyBERT_General_4L_312D/tr…

day01——项目导入+环境搭建

目录 软件开发整体介绍 软件开发流程 需求分析 设计阶段 编码阶段 测试阶段 上线运维 角色分工 软件环境 苍穹外卖项目介绍 项目介绍 功能架构 产品原型 ​编辑 技术选型 开发环境搭建——前端环境搭建 开发环境搭建——后端环境搭建 熟悉项目结构 ​编辑 使…

入门开发教程之网站品质教程

目录 网站品质 教程 网站品质教程 背景 要素 可访问性 可用性 可靠性 可维护性 提升网站品质 针对性调整 优化网页速度 提供多种访问方法 结论 网站品质教程 背景 在今天这个数字化时代&#xff0c;网站已经成为了各个行业展示产品和服务的重要媒介。而网站品质是…

百分点科技苏萌受邀出席首届全国统计与数据科学联合会议

7月11-13日&#xff0c;首届全国统计与数据科学联合会议在北京举行&#xff0c;会议由中国现场统计研究会、中国数学会概率统计分 会、全国工业统计学教学研究会和中国商业统计学会联合主办&#xff0c;北京大学统计科学中心承办&#xff0c;旨在促进统计与数据科学领域发展&a…

H3C-Cloud Lab实验-IPv6实验

实验拓扑图&#xff1a; 实验需求&#xff1a; 1、在R1和PC3上开启IPv6链路本地地址自动生成&#xff0c;测试是否能够使用链路本地地址互通 2、为R1配置全球单播地址2001::1/64&#xff0c;使PC3能够自动生成与R1同一网段的IPv6地址3、测试R1和PC3是否能够使用全球单播地址互…

【UE4 塔防游戏系列】05-制作可跟踪旋转的炮塔

目录 效果 步骤 一、设置游戏观察视角 二、设置PlayerController 三、制作可跟踪旋转的炮塔 效果 步骤 一、设置游戏观察视角 在视口中调整好位置&#xff0c;能够看到敌人行走的全部路线即可。然后在此处创建CameraActor 打开关卡蓝图&#xff0c;设置使用这个相机的…

【Kaggle】初学者几个冷门的操作总结

文章目录 一、如何看当前的目录&#xff1f;二、Kaggle如何切换路径&#xff1f;三、与包安装或设置有关的错误四、如何把 Kaggle 上的 input 数据转到 output 中&#xff1f; 一、如何看当前的目录&#xff1f; 在 Linux 中&#xff0c;你可以使用 pwd 命令来查看当前所在的目…

UML与SYSML的关系

UML与SysML的联系 UML&#xff08;统一建模语言&#xff09;和SysML&#xff08;系统建模语言&#xff09;是两种与建模相关的语言&#xff0c;它们之间存在联系和区别。 SysML的图分类如下图所示。 联系 SysML是基于UML的&#xff0c;它重用了UML 2的子集&#xff0c;并提…