C语言快速入门之内存函数的使用和模拟实现

1.memcpy

它可以理解为memory + copy的组合,memory有记忆的意思,这里指的是内存,copy是拷贝,这个函数是针对内存块进行拷贝的

函数原型

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

从source位置开始,向后num个数据拷贝到destination中,它与字符串的strcopy类似,但是遇到'\0'不会停下来,同时,两者的内存不能重叠

我们先来写代码使用一下爱这个函数吧

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };

	my_memcpy(arr2, arr1, 20);	//字节的长度
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}

	return 0;
}

在这个代码中,我们将arr1的内容拷贝到了arr2中,拷贝了20个字节,也就是5个int类型的数字,一定要注意是字节的拷贝,这是运行结果

现在,我们来模拟实现这个函数吧

void* my_memcpy(void* dest, void* src, size_t num)
{
	int i = 0;
	void* ret = dest;
	assert(dest && src);
	/*for (i = 0; i < num; i++)
	{
		*((char*)dest + i) = *((char*)src + i);
	}*/

	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

那如果我们想实现在一个数组内进行操作,比如我想操作arr1数组,把第二个数字开始更改,进行拷贝,如果我们写出如下的代码,可能运行结果与我们考虑的就不同了

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

	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,3,4,5,8,9,10,但实际结果是:

实际上,这是因为memcpy是不能有内存重叠的,这样我们先更改了,然后再访问,因此出现了很多个1,2

当然,VS有保护机制,我们现在也可以使用memcpy来实现了,但理论上 是不行的

2.memmove

memmove和memcopy的差别是memmove函数处理源内存块和目标内存块是可以重叠的,最后返回目标空间的起始地址

函数原型

void* memmeove(void* dest, const void* src, size_t num)

现在,我们可以运用这个函数来实现了

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove((arr + 2), arr, 5*sizeof(int));
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

现在,我们来看看结果是否和我们想要的一样?

那么,我们是否可以尝试进行模拟这个函数呢?

第一种方法,我们在函数中再创建一个数组,将内容拷贝过去,然后再进行

那我们是否可以不创建新数组,来实现这个函数呢?

事实上,我们可以根据dest和scr的位置来判断

当dest在src之前时,我们从前向后进行拷贝,当dest在src后面时,我们从后向前进行拷贝,因此,我们可以写出以下的代码

void* my_memmeove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = 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;
}

3.memset

是用来完成内存设置的

函数原型:

void * memset(void* ptr,int vulue,size_t num);

ptr代表要填充的内存块的位置,vulue是设置的值,num是填充几个字节的位置

现在我们来使用这个函数吧!

int main()
{
	char arr[] = "hello world";
	memset(arr, 'x', 5);
	printf("%s ", arr);

	return 0;
}

这里,我们将前五个字符变成了x,结果如下:

当然,也不仅限于字符串函数,整形函数也可以,但是我们需要注意,这里是把所有的字节转换,而int类型占据4个字节,应该注意如何来运用

4.memcmp

完成内存块的比较

函数原型

int memcmp(const void* ptr1, const void* ptr2, size_t num);

从ptr1与ptr2开始num个字节进行比较,返回值是数字,前者大返回大于0的,后者大返回小于0的,相等返回0

我们来使用这个函数吧

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };
	int arr2[] = { 1,2,3,4,8,8,8 };
	int ret = memcmp(arr1, arr2, 16);
	printf("%d ", ret);

	return 0;
}

结果是这样

感谢您的观看

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue的疗养院管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Python深度学习之路:TensorFlow与PyTorch对比【第140篇—Python实现】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python深度学习之路&#xff1a;TensorFlow与PyTorch对比 在深度学习领域&#xff0c;Tens…

MATLAB环境下基于决策树和随机森林的心力衰竭患者生存情况预测

近年来&#xff0c;随着医学数据的不断积累和计算机技术的快速发展&#xff0c;许多机器学习技术已经被用在医学领域&#xff0c;并取得了不错的效果。与传统的基于医学知识经验的心衰预后评估模型相比&#xff0c;机器学习方法可以快速、高效地从繁杂的、海量的心衰病人数据中…

软件杯 深度学习 python opencv 实现人脸年龄性别识别

文章目录 0 前言1 项目课题介绍2 关键技术2.1 卷积神经网络2.2 卷积层2.3 池化层2.4 激活函数&#xff1a;2.5 全连接层 3 使用tensorflow中keras模块实现卷积神经网络4 Keras介绍4.1 Keras深度学习模型4.2 Keras中重要的预定义对象4.3 Keras的网络层构造 5 数据集处理训练5.1 …

HTML详细教程

文章目录 前言一、快速开发网站最简模板二、HTML标签1.编码2.title3.标题4.div和span5.超链接6.图片7.列表8.表格9.input系列10.下拉框11.多行文本 三、GET方式和POST方式1.GET请求2.POST请求 前言 HTML的全称为超文本标记语言&#xff0c;是一种标记语言&#xff0c;是网站开发…

HCIP —— 交换 (VLAN)

VLAN --- 虚拟局域网 在 HCIA 中 &#xff0c;已经学过交换机的一些基础配置&#xff0c;下面进行回顾一些简单的内容。 1.创建VLAN VLAN ID --- 区别和标识不同的VLAN 使用范围&#xff1a;0-4095 &#xff0c; 由12位二进制构成。 0 和 4095 作为 保留的VLAN。 …

Python零基础---爬虫技术相关

python 爬虫技术&#xff0c;关于数据相关的拆解&#xff1a; 1.对页面结构的拆解 2.数据包的分析&#xff08;是否加密了参数&#xff09;&#xff08;Md5 aes&#xff09;难易程度&#xff0c;价格 3.对接客户(433,334) # 数据库 CSV 4.结单&#xff08;发一部分数据&a…

13 - grace数据处理 - 泄露误差改正 -正演建模法(Forward-Modeling)

grace数据处理 - 泄露误差改正 -正演建模法(Forward-Modeling) *0* 引言*1* Matlab代码实现0 引言 正演建模法最早是由Chen等提出的,本质是通过迭代的思想反求真实信号的过程,为什么要反求呢?因为在数据处理过程中做了球谐截断和空间滤波,使部分有用信号被湮灭,也就是有…

Blocks —— 《Objective-C高级编程 iOS与OS X多线程和内存管理》

目录 Blocks概要什么是BlocksOC转C方法关于几种变量的特点 Blocks模式Block语法Block类型 变量截获局部变量值__block说明符截获的局部变量 Blocks的实现Block的实质 Blocks概要 什么是Blocks Blocks是C语言的扩充功能&#xff0c;即带有局部变量的匿名函数。 顾名思义&#x…

如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf?

如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf? 步骤1 编译安装内核获取源码修改配置编译编译成功后配置重启WSL测试 步骤2 安装bcc安装依赖下载bcc&#xff0c;编译测试 环境: wsl2windows 11 步骤1 编译安装内核 去https://kernel.org/找你想要的版本&#xff0c; …

CCDP.01.使用NotePad++辅助部署OpenStack的说明

前言 对于象OpenStack&#xff08;OS&#xff09;这样的复杂分布式系统&#xff08;云计算平台&#xff09;&#xff0c;一次部署通过是需要相当的Linux基础、网络基础、分布式系统基础、云计算基础的。这里类比在开发大型复杂系统常常采用的“防御式编程”方法论&#xff0c;探…

Gin 框架中实现路由的几种方式介绍

本文将为您详细讲解 Gin 框架中实现路由的几种方式&#xff0c;并给出相应的简单例子。Gin 是一个高性能的 Web 框架&#xff0c;用于构建后端服务。在 Web 应用程序中&#xff0c;路由是一种将客户端请求映射到特定处理程序的方法。以下是几种常见的路由实现方式&#xff1a; …

llama笔记:官方示例解析 example_chat_completion.py

1 导入库 from typing import List, Optional从typing模块中导入List和Optional。typing模块用于提供类型注解的支持&#xff0c;以帮助明确函数预期接收和返回的数据类型。List用于指定列表类型Optional用于指定一个变量可能是某个类型&#xff0c;也可能是None。 import fir…

Laravel11.0.3安装完后运行项目报错

Laravel11.0.3安装完后运行项目报错&#xff1a;could not find driver (Connection: sqlite, SQL: PRAGMA foreign_keys ON;) 运行项目报错时提示链接sqlite错误 解决方案&#xff1a; 1.确认机器安装了sqlite&#xff0c;https://blog.csdn.net/centaury32/article/detail…

C#,人工智能,机器学习,聚类算法,训练数据集生成算法、软件与源代码

摘要:本文简述了人工智能的重要分支——机器学习的核心算法之一——聚类算法,并用C#实现了一套完全交互式的、可由用户自由发挥的,适用于聚类算法的训练数据集生成软件——Clustering。用户使用鼠标左键(拖动)即可生成任意形状,任意维度,任意簇数及各种数据范围的训练数…

尚硅谷SQL|数据库的创建,修改与删除

DDL&#xff1a;创建和管理表 DDL所有的操作都要慎重&#xff0c;尤其是删除&#xff0c;清空等。 创建数据库--->确认字段--->创建数据表---->插入数据 创建数据库 1.创建数据库&#xff1a;推荐使用方式3 #创建数据库 #方式1,使用的是默认字符集 create databa…

Matlab|【免费】基于半不变量的概率潮流计算

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序主要内容是基于半不变量法的概率潮流&#xff0c;包含蒙特卡洛模拟法、半不变量法&#xff0b;Gram-Charlier级数展开以及半不变量法Cornish-Fisher级数展开三种方法以及效果对比&#xff0c;模型考虑了…

Android学习使用GitLab(保姆级)

实习生入职第一课 学习使用GitLab&#xff0c;熟悉Git版本控制工具 下面是我的学习笔记&#xff0c;希望能帮助到需要的人&#xff01; 目录 一、注册你的GitLab账号 二、安装Git 三、在Android studio中配置Git 四、GitLab账户配置SSH Keys 五、GitLab账号创建项目 六…

Qt/C++监控推流设备推流/延迟极低/实时性极高/rtsp/rtmp推流/hls/flv/webrtc拉流/调整分辨率降低带宽

一、前言 算下来这个推流的项目作品写了有四年多了&#xff0c;最初第一个版本只有文件点播的功能&#xff0c;用的纯QTcpSocket通信实现&#xff0c;属于比较简单的功能。由于文件点播只支持文件形式的推流&#xff0c;不支持网络流或者本地设备采集&#xff0c;所以迫切需要…

【GPT-SOVITS-05】SOVITS 模块-残差量化解析

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…