C语言内存函数memcpy、memmove、 memset、memcmp

 ---------------------------------------------

夜色难免黑凉,前行必有曙光。

-------------今天我将带大家认识C语言中的内存函数

---------的使用和模拟实现

-----这些函数的头文件依然被#include<string.h>所包含

目录

memcpy函数的使用

memcpy函数的模拟实现

memmove函数的使用 

memmove函数的模拟实现 

 memset函数的使用

 memcmp函数的使用


memcpy函数的使用

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

1.函数memcpy是从cource的位置开始向后复制num字节数据到destination指向的内存位置

2.函数memcpy在遇到'\0'并不会停下来依然可以拷贝'\0'后面位置

3. source和destination不能有重叠

4.常被我们用来拷贝非字符串的类型

 以下是memcpy函数的一般用法:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	int str[10] = { 0 };
	memcpy(str,arr , 20);
//内存函数的单位是字节,20字节就是5个整形元素
//也可以这么写memcpy(str,arr,5*sizeof(int))
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

我们来验证一下,memcpy遇到'\0'是否不会停止: 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "Hel\0lo World!";
	char str[10] = { 0 };
	memcpy(str, arr, 6 * sizeof(char));
	for (int i = 0; i < 6; i++)
	{
		printf("%c", str[i]);
	}
	return 0;
}

我们可以看到memcpy函数并不会因为遇到'\0'而停止,它会把'\0' 拷贝到目标函数

memcpy函数的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memcpy(void* arr, const void* str, size_t num)
         //因为这个函数可以运用到多种类型,所以用了void*(无具体类型的指针)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr+1;   
		str = (char*)str + 1;
//强制类型转换为char类型可以一个字节一个字节的访问
	}
	return ret;
//返回目标函数的起始地址
}
int main()
{
	char arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	char str[10] = { 0 };
	my_memcpy(str, arr, 5 * sizeof(int));
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

 memcpy中重叠拷贝问题:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memcpy(void* arr, const void* str, size_t num)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr + 1;
		str = (char*)str + 1;
	}
return ret;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memcpy(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

VS2022的库函数里面的memcpy可以重叠拷贝,但有些编译器不行

为了表示区分,我们以后重叠拷贝都不用memcpy

可以用memmove函数来实现重叠拷贝

memmove函数的使用 

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

 1.memmove和memcpy的区别就是源内空间可以和目标空间重叠

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	memmove(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

我们可以发现memmove把我们刚刚源内空间和目标空间重叠的问题很好的解决了

接下来让我们看看它是怎么实现的吧

memmove函数的模拟实现 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) {
		while (count--) {
                  //从前向后拷贝
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else {
                  //从后向前拷贝
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--) {
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memmove(arr + 3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

接下来我将会以画图的形式帮助大家理解:

 memset函数的使用

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

1.memsrt常被我们用来设置内存,将内存中的值以字节为单位设置成想要的内容 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "hello world";
	memset(arr, 'x', 6);
	printf(arr);
	return 0;
}

 这样来看我们是不是把hello 的内容设置成"x"了!这就是memset函数的运用场景。

 memcmp函数的使用

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

1.比较ptr1和ptr2指针指向的位置开始,向后的num个字节 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "abcdfe";
	char str[] = "abcdefg";
	int n;
	n = memcmp(arr, str, sizeof(arr));
	if (n > 0)
		printf("'%s' 大于 '%s'.\n",arr ,str );
	else if (n < 0)
		printf("'%s' 小于 '%s'.\n", arr,str );
	else
		printf("'%s' 等于 '%s'.\n",arr ,str );
	return 0;
}

 今天的介绍就到这里啦!

后续我将会把结构体方面的知识点整理出来

希望大家长期关注 !

感谢支持

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

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

相关文章

css中的 Grid 布局

flex布局和grid布局区别 flex布局是 一维布局grid布局是二维布局 flex布局示例 grid布局示例 grid 布局初体验 体验地址 <div class"wrapper"><div class"one item">One</div><div class"two item">Two</div&…

NIO--07--Java lO模型详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 何为 IO?先从计算机结构的角度来解读一下I/o.再从应用程序的角度来解读一下I/O 阻塞/非阻塞/同步/异步IO阻塞IO非阻塞IO异步IO举例 Java中3种常见的IO模型BIO (Blo…

二分查找边界问题——排序数组找元素第一次出现和最后一次出现

二分查找的边界逼近问题&#xff1a; 下面的代码&#xff0c;第一个函数会向左边界逼近&#xff0c;第二个函数会像右边界逼近&#xff01; 考虑left5,right6这种情况&#xff0c;如果5&#xff0c;6的值都是满足的条件的怎么办&#xff1f; 如果mid(leftright1)/2&#xff0c;…

详解Spring中的Aop编程原理JDK动态代理和CGLIB动态代理

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

HuggingFace学习笔记--BitFit高效微调

1--BitFit高效微调 BitFit&#xff0c;全称是 bias-term fine-tuning&#xff0c;其高效微调只去微调带有 bias 的参数&#xff0c;其余参数全部固定&#xff1b; 2--实例代码 from datasets import load_from_disk from transformers import AutoTokenizer, AutoModelForCaus…

【Pytorch】Visualization of Feature Maps(5)——Deep Dream

学习参考来自&#xff1a; PyTorch实现Deep Dreamhttps://github.com/duc0/deep-dream-in-pytorch 文章目录 1 原理2 VGG 模型结构3 完整代码4 输出结果5 消融实验6 torch.norm() 1 原理 其实 Deep Dream大致的原理和【Pytorch】Visualization of Feature Maps&#xff08;1&…

一起学docker系列之十七Docker Compose 与手动操作的比较与优势分析

目录 1 前言2 不使用 Docker Compose2.1 启动 MySQL 容器2.2 启动 Redis 容器2.3 启动微服务容器 3 使用 Docker Compose4 使用 Docker Compose 的优势5 结语参考地址 1 前言 在当今容器化应用的开发与部署中&#xff0c;容器编排工具的选择对于简化流程、提高效率至关重要。本…

蓝桥杯第1037题子串分值和 C++ 字符串 逆向思维 巧解

题目 思路和解题方法 方案一——遍历哈希表 仅能过60%样例,大多数同学都用的该方法&#xff0c;就不过多赘述 #include <iostream> #include <unordered_map> using namespace std; int main() {string s;cin >> s;int n s.size();int res n;for (int i 0…

未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序报错的解决办法

当在本地计算机上使用Microsoft Office相关库时&#xff0c;可能会出现“未在本地计算机上注册microsoft.ACE.oledb.12.0”提供程序的报错。这是由于缺少相关的驱动程序或者未安装相应的软件所导致的。下面是解决该问题的完整攻略。 可能是因为没有安装数据访问组件&#xff0…

反序列化漏洞(二)

目录 pop链前置知识&#xff0c;魔术方法触发规则 pop构造链解释&#xff08;开始烧脑了&#xff09; 字符串逃逸基础 字符减少 字符串逃逸基础 字符增加 实例获取flag 字符串增多逃逸 字符串减少逃逸 延续反序列化漏洞(一)的内容 pop链前置知识&#xff0c;魔术方法触…

树基本概念+前中后序遍历二叉树

&#x1f308;一、树的基本概念 ☀️1.树的定义&#xff1a;树是一种非线性结构&#xff0c;看起来像一棵倒挂的树&#xff0c;根朝上&#xff0c;而叶朝下。 ☀️2.相关术语 1.根节点&#xff1a;图中的A&#xff0c;无前驱结点 2.叶节点&#xff08;终端节点&#xff09;&a…

iptables——建立linux安全体系

目录 一. 安全技术类型 二. linux防火墙 1. 按保护范围划分&#xff1a; 2. 按实现方式划分&#xff1a; 3. 按网络协议划分&#xff1a; 4. 防火墙原理 三. 防火墙工具——iptables 1. netfilter 中五个勾子函数和报文流向 数据包传输过程&#xff1a; ① .五表四链…

设计模式-结构型模式之外观设计模式

文章目录 七、外观模式 七、外观模式 外观模式&#xff08;Facade Pattern&#xff09;隐藏系统的复杂性&#xff0c;并向客户端提供了一个客户端可以访问系统的接口。它向现有的系统添加一个接口&#xff0c;来隐藏系统的复杂性。 这种模式涉及到一个单一的类&#xff0c;该类…

爬虫-xpath篇

1.xpath的基础语法 表达式描述nodename选中该元素/从根节点选取、或者是元素和元素间的过渡//从匹配选择的当前节点选择文档中的节点&#xff0c;而不考虑它们的位置.选取当前节点…选取当前节点的父节点选取属性text()选取文本 举例&#xff1a; 路径表达式结果html选择html元…

使用java批量生成Xshell session(*.xsh)文件

背景 工作中需要管理多套环境, 有时需要同时登陆多个节点, 且每个环境用户名密码都一样, 因此需要一个方案来解决动态的批量登录问题. XShell Xshell有session管理功能: 提供了包括记住登录主机、用户名、密码及登录时执行命令或脚本(js,py,vbs)的功能 session被存储在xsh文…

6-49.自定义的学生类

本题要求定义一个简单的学生类&#xff0c;数据成员仅需要定义学号和姓名&#xff0c;函数成员的原型见给出的代码&#xff0c;请给出函数成员的类外完整实现。 其中m_id和m_name分别表示学生的学号和姓名&#xff0c;类型已经定义好。类内声明了3个成员函数&#xff0c;分别表…

Linux docker批量安装软件

1.前提 具备docker-compose.yml 和 prometheus.yml 文件 常见报错&#xff1a; 1.没有配置network 配置network即可&#xff1a; 2.缺少相关依赖 docker-compose.yml加入相关配置 3.重复项 删除掉重复的 最后 执行 等待完成 下载后相当于有了这些软件包的镜像 启动的每…

大数据Hadoop-HDFS_架构、读写流程

大数据Hadoop-HDFS 基本系统架构 HDFS架构包含三个部分&#xff1a;NameNode&#xff0c;DataNode&#xff0c;Client。 NameNode&#xff1a;NameNode用于存储、生成文件系统的元数据。运行一个实例。 DataNode&#xff1a;DataNode用于存储实际的数据&#xff0c;将自己管理…

OpenHarmony亮相MTSC 2023 | 质量效率共进,赋能应用生态发展

11月25日&#xff0c;MTSC 2023第十二届中国互联网测试开发大会在深圳登喜路国际大酒店圆满举行。大会以“软件质量保障体系和测试研发技术交流”为主要目的&#xff0c;旨在为行业搭建一个深入探讨和交流的桥梁和平台。OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&a…

Langchain-Chatchat的安装过程

参考&#xff1a;LLMs之RAG&#xff1a;LangChain-Chatchat(一款中文友好的全流程本地知识库问答应用)的简介(支持 FastChat 接入的ChatGLM-2/LLaMA-2等多款主流LLMs多款embe_一个处女座的程序猿的博客-CSDN博客 1、安装过程中出现了 GPU驱动版本 是11.8 而 python -c "…