当前位置: 首页 > news >正文

C语言内存操作函数

目录

一. C语言内存操作函数

1. memcpy的使用和模拟实现

2. memmove函数

3. memset函数

4. memcmp函数


一. C语言内存操作函数

随着知识的不断积累,我们所想要实现的目标程序就会更加复杂,今天我们来学习一个新的知识叫做C语言内存操作函数,它是C语言标准库中提供的一系列对内存进行操作的函数。比如对于内存的复制,内存的设置以及内存的比较,这些函数都是针对内存块来处理的,为程序员提供了更加安全,高效和灵活的方式,让程序员能够对内存进行各种常见的操作和处理,下面就让我们来详细了解一下吧。😁🤗🤗

1. memcpy的使用和模拟实现

首先我们来认识memcpy函数,它的原型是void* memcpy(void* destination, const void* soure,size_t num),作用就是内容的复制,从soure的位置开始向后复制num个字节(注意单位是字节)的数据到destination指向的内存位置这个函数遇到'/0'的时候并不会停下来并且destination和soure有任何的重叠,复制的结果都是未定义的。下面给出大家实际的例子:

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };memcpy(arr2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}

 对于运行结果来说我们也可以看出来如果num小于实际输出的数量,那么后面都是用0来补的,大家下去可以自己多尝试进行练习。

🎡🎡如何模拟实现memecpy函数呢?

#include <assert.h>
void* my_memcpy(void* str1, const void* str2, size_t num)
{void* ret = str1;assert(str1);assert(str2);/** copy from lower addresses to higher addresses*/while (num--) {*(char*)str1 = *(char*)str2;str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}return(ret);
}
int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}

在我们模拟实现的过程中,在开始的时候我们要注意两个指针不能是空指针,需要assert进行断言,我们为什么要进行强制类型转换成char*呢?首先我们要明确memcpy函数传入第三个参数size_t num是字节的个数,所以当我们强制类型转换的时候会更加方便去计算,另外就是我们的指针是void*类型的,是不能直接进行加减运算的,最终返回一个void*的指针。

2. memmove函数

接下来认识memmove函数,它的原型是void* memmove(void* destination,const void* scoure,size_t num),原型与memcpy函数是一模一样的,所以说其实memmove函数与memcpy函数的区别就是memmove函数可以处理重叠部分。也就是说如果源空间也目标空间出现重叠的话,我们就使用memmove函数来处理。给大家举一个例子说明:

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

 其实对于我们memmove函数的实现其实是更复杂的,那么我们究竟要如何实现它呢?大家看下面面的四种情况:

sour代表的是源空间,des代表的是目标函数,大家认真看第一个,如果我们将sour里面的内容复制到des中,我们可以直接按顺序将34567依次放入12345中,最终我们的打印结果就是3 4 5 6 7 6 7 8 9 10,但是我们来看第三种,如果我们将34567按顺序放在56789中,我们会发现当我们放完3和4之后,原本的5和6就会变成3和4,那么原来应该把5和6放在7和8位置上的计划就不能实现,所以这样放是不对的,但我们换一种方法,我们先将7放入9,再将6放入8,也就是从后面往前面放置,对于第四种来说,从前往后和从后往前都是一样的。所以我给出大家一张图来更好的说明:我们的数组有高低地址之分,也就是说当我们的des小于sour的时候我们选择从前往后,除此之外我们选择从前往后,所以了解了底层的逻辑下面我们就开始设计我们的代码: 

#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* sour, size_t num)
{assert(dest && sour);void* ret = dest;if (dest < sour)//从前往后{while (num--){*(char*)dest = *(char*)sour;dest = (char*)dest + 1;sour = (char*)sour + 1;}}else//从后往前{while (num--){*((char*)dest + num) = *((char*)sour + num);}}return ret;};int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

但是可能细心的同学会发现,我们就算使用memcpy函数也能够实现重叠部分的程序运算,但是我们在C语言中更推荐规范使用,如果有重叠部分的就使用memmove函数,虽然我们在VS的编译器上用memcpy来处理重叠部分可以成功,但是在其他编译器上却不一定,所以我们尽量的规范使用。

3. memset函数

🧣🧣memset函数是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。它的原型是void* memset(void* ptr,int value,size_t num);ptr就指向要被填充的内存块指针,value要设置的内容,num就表示要设置成多少个字节。

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

 

4. memcmp函数

🧀🧀memcmp函数是用来比较两个指针大小的,它的原型是int memcmp(const void* ptr1,const void* ptr2,size_t num),就是对内存块ptr1和ptr2进行比较,比较从ptr1和ptr2指针指向的位置开始,向后的num个字节,注意也是以字节为单位,当ptr1>ptr2的时候,返回大于0的值,当两个相等的时候,返回0,当ptr1<ptr2的时候,返回小于0的值

#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);elseprintf("'%s' is the same as '%s'.\n", buffer1, buffer2);return 0;

相关文章:

C语言内存操作函数

目录 一. C语言内存操作函数 1. memcpy的使用和模拟实现 2. memmove函数 3. memset函数 4. memcmp函数 一. C语言内存操作函数 随着知识的不断积累&#xff0c;我们所想要实现的目标程序就会更加复杂&#xff0c;今天我们来学习一个新的知识叫做C语言内存操作函数&#x…...

深入探索 PyTorch:torch.nn.Parameter 与 torch.Tensor 的奥秘

标题&#xff1a;深入探索 PyTorch&#xff1a;torch.nn.Parameter 与 torch.Tensor 的奥秘 在深度学习的世界里&#xff0c;PyTorch 以其灵活性和易用性成为了众多研究者和开发者的首选框架。然而&#xff0c;即使是经验丰富的 PyTorch 用户&#xff0c;也可能对 torch.nn.Pa…...

成为Python砖家(1): 在本地查询Python HTML文档

目的 Python3 官方文档位于 https://docs.python.org/3/ &#xff0c; 有时候网络无法连接&#xff0c;或者连接速度慢&#xff0c; 这对于学习 Python 时的反馈造成了负面影响。准备一份本地 Python 文档可以让反馈更加及时。 下面给出 macOS 和 Win11 下的 Python 离线文档…...

深度学习基础—RMSprop算法与Adam 优化算法

1.RMSprop算法 1.1.算法流程 除了动量梯度下降法&#xff0c;RMSprop算法也可以加快梯度下降&#xff0c;这个算法的算法流程如下&#xff1a;深度学习基础—动量梯度下降法http://t.csdnimg.cn/zeGRo 1.2.算法原理 和动量梯度下降不同的是&#xff0c;对dW和db的变成了平方项…...

单片机原理及技术(六)—— 中断系统的工作原理

目录 一、AT89S51中断技术概述 二、AT89S51中断系统结构 2.1 中断请求源 2.2 中断请求标志寄存器 2.2.1 TCON 寄存器 2.2.2 SCON 寄存器 三、中断允许与中断优先级的控制 3.1 中断允许寄存器 IE 3.2 中断优先级寄存器 IP 四、响应中断请求的条件 五、外部中断的触发…...

Angular路由使用

Angular路由是Angular框架中一个非常重要的特性&#xff0c;开发者可以根据URL的不同来动态地加载和显示不同的组件&#xff0c;从而构建出单页面应用&#xff08;SPA&#xff09;。 以下是Angular路由使用的基本步骤和要点&#xff1a; 1. 安装和配置路由模块 首先&#xf…...

【JVM】深入理解类加载机制(一)

深入理解类加载机制 Klass模型 Java的每个类&#xff0c;在JVM中都有一个对应的Klass类实例与之对应&#xff0c;存储类的元信息如:常量池、属性信息、方法信息…从继承关系上也能看出来&#xff0c;类的元信息是存储在元空间的。普通的Java类在JVM中对应的是InstanceKlass(C)…...

区块链浏览器需求整理

用户需求 普通用户 便捷查询交易记录&#xff1a;能够轻松找到自己或特定地址的交易详情&#xff0c;包括交易时间、金额、状态等。查看账户余额&#xff1a;实时了解地址的余额情况。追踪资产流向&#xff1a;了解自己的资产在区块链上的转移路径。 开发者 智能合约调试&a…...

Laravel 表单验证功能重定向判断

判断主要针对 API 请求和普通页面请求&#xff0c;即 API 的表单验证失败直接响应 JSON&#xff0c;而页面的表单验证失败正常重定向。 看网上基本上是继承 FormRequest 类来实现&#xff0c;其实直接修改异常处理的 Handler 类即可&#xff0c;非常简单。 打开 app/Exception…...

MATLAB口罩检测系统

一、应用背景 作为数字图像处理和计算机视觉领域的一个重要组成部分&#xff0c;利用摄像机对图像进行采集&#xff0c;从图像中检测人脸并进行口罩穿戴的识别的有着非常重要的研究意义和应用价值。面对突如其来的新型肺炎疫情&#xff0c;人们生活秩序被严重打乱。跟普通流感…...

LeetCode 第三十一天 2024.8.18

1. &#xff1a;买卖股票的最佳时机 题目链接: 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 应用条件&#xff1a; 难点&#xff1a; # 确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp数组由len(prices)个[][]组成&#xff…...

Linux驱动学习之点灯(一)

学习不同的板子我们都是从点灯开始&#xff0c;linux驱动也不例外 驱动开发基础知识 何为驱动&#xff1f; 驱使硬件正常工作的代码就叫做驱动。 在一些mcu里&#xff1a; 无非就是直接操作寄存器&#xff0c;或者用库函数初始化外设&#xff0c;使外设正常工作如初始化iic&…...

从HTTP到HTTPS:SSL加密如何重塑互联网安全格局

从HTTP到HTTPS&#xff1a;SSL加密如何重塑互联网安全格局 随着互联网技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;保护用户数据的安全性和隐私性成为了不可忽视的重要议题。从HTTP&#xff08;超文本传输协议&#xff09;到HTTPS&#xff08;超文本传输安全协…...

QT网络编程: 实现UDP通讯设置

目录 一.widget.ui界面设计 二.创建UDP通信 1.pro文件添加network模块。 2.添加对应头文件 3.定义槽函数&#xff0c;即与 UI 中的按钮点击事件相关联的函数 4.定义类的私有成员 5.关闭按钮 6.信息处理 7.绑定端口 8.发送信息 9.效果图 三.代码演示 1.widget.h 2.…...

机器学习第十一章--特征选择与稀疏学习

一、子集搜索与评价 我们将属性称为 “特征”(feature&#xff09;&#xff0c;对当前学习任务有用的属性称为 “相关特征”(relevant feature&#xff09;、没什么用的属性称为 “无关特征”(irrelevant feature)&#xff0e;从给定的特征集合中选择出相关特征子集的过程&…...

dm 到 dm 的 HS 同步部署

一、数据库部署 完成两节点数据库部署并初始化&#xff0c;配置参数如下&#xff1a; 节点 192.168.2.132 192.168.2.133 数据库版本 DM8 DM8 实例名 DM1 DM2 端口号 5236 5236 数据文件路径 /home/dmdba/dmdata /home/dmdba/dmdata 二、 dmhs 部署 1. 部署…...

ShardingSphere、雪花算法、分布式id生成器CosID概述

ShardingSphere 用处&#xff1a;sharding是分片的意思&#xff0c;sphere是球&#xff08;生态的意思&#xff09;。用来做分库分表的生态的。一个订单表太大&#xff0c;查询会很慢&#xff0c;要分表&#xff0c;分为3个表&#xff0c;这样查询会快一点&#xff0c;所以有了…...

hive学习(四)

一、分区表的数据导入 1.静态分区&#xff08;需要手动指定分区字段的值&#xff09; 直接将文件数据导入到分区表 语法&#xff1a;load data [local] inpath filepath into table tablename partition(分区字段1分区值1, 分区字段2分区值2...); load data [local] inpat…...

UniAD_面向规划的自动驾驶

Planning-oriented Autonomous Driving 面向规划的自动驾驶 https://github.com/OpenDriveLab/UniAD Abstract Modern autonomous driving system is characterized as modular tasks in sequential order, i.e., perception, prediction, and planning. In order to perfor…...

《现代情报》

《现代情报》简介 《现代情报》&#xff08;原名《情报知识》&#xff09;杂志是由吉林省科学技术厅主管&#xff0c;吉林省科学技术信息研究所、中国科学技术情报学会联合主办的信息资源管理领域综合性学术期刊。该刊于1980年创刊&#xff0c;每年12期。重点报道服务于国家战略…...

2024年最新上榜的文件加密管理软件

文件加密市场风起云涌&#xff0c;后辈迭出&#xff0c;2024年安企神软件在文件加密管理软件市场中备受瞩目&#xff0c;凭借其强大的功能和全面的保护策略&#xff0c;成功上榜并受到广泛认可。以下是对它的详细介绍&#xff1a; 一、产品概述 安企神软件不仅是一款电脑监控…...

Matplotlib库学习之scatter(模块)

Matplotlib库学习之scatter(模块) 一、简介 Matplotlib 是 Python 中一个强大的绘图库&#xff0c;其中 matplotlib.pyplot.scatter 用于创建散点图。散点图在数据可视化中广泛用于展示两个变量之间的关系。 二、语法和参数 语法 matplotlib.pyplot.scatter(x, y, sNone, c…...

脑网络相似性:方法与应用

摘要 图论方法已被证明是理解、表征和量化复杂大脑网络的有效工具。然而&#xff0c;定量比较两个图形的方法却较少受到关注。在一些网络神经科学应用中&#xff0c;比较大脑网络确实是必不可少的。在这里&#xff0c;本研究讨论了近年来用于比较大脑网络的技术现状、挑战以及…...

【JavaEE】深入MyBatis:动态SQL操作与实战项目实现指南

目录 MyBatis的进阶操作动态SQL<if>标签<trim>标签<where>标签<set>标签<foreach>标签<include>标签 练习表白墙数据准备引⼊MyBatis 和 MySQL驱动依赖配置MySQL账号密码编写后端代码测试 图书管理系统数据库表设计引⼊MyBatis 和MySQL 驱…...

Linux 实操-权限管理:深入了解rwx的作用

&#x1f600;前言 本篇博文是关于Linux文件权限管理的基本知识和实际操作&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是…...

Linux 系统编程 --- day3

目录 1. fileno 2.fdopen 3. 目录操作 3.1 opendir 3.2 readdir 3.3 closedir 3.4 实现 ls 命令的功能 4. chdir &#xff08;相当于cd命令&#xff09; 5. getcwd &#xff08;相当于pwd命令&#xff09; 6. mkdir 7. rmdir &#xff08;相当于rm命令&a…...

centos从home分区分配空间到根分区

在安装centos系统时如果采用默认自动分区&#xff0c;则会默认只给根分区分配50G空间&#xff0c;其余多余的会被分配到home分区&#xff0c;而作为家用服务器或仅个人使用的话&#xff0c;为了方便往往根分区会不够用而home分区几乎没使用。 先看下现在的磁盘结构和容量(xfs文…...

设计模式实战:即时通讯应用的设计与实现

系统功能需求 用户管理:支持用户注册、登录、注销、个人信息更新等功能。消息传递:支持即时消息发送、接收、存储和显示,支持文本、图片、语音等多种消息类型。在线状态管理:实时跟踪和显示用户的在线状态。消息通知:在消息到达时发送推送通知给用户。聊天记录管理:支持聊…...

白骑士的C#教学实战项目篇 4.3 Web开发

系列目录 上一篇&#xff1a;白骑士的C#教学实战项目篇 4.2 图形用户界面&#xff08;GUI&#xff09;应用 在这一部分&#xff0c;我们将从桌面应用程序扩展到 Web 开发。Web 开发是现代软件开发的重要领域&#xff0c;涵盖了从前端用户界面到后端服务器逻辑的完整堆栈。在这…...

【数据分析】(交互) 延迟互信息(熵、概率密度、高斯核、带宽估计)

文章目录 一、互信息基础二、延迟互信息2.1 交互延迟互信息三、时间序列互信息中的概率计算(高斯核密度估计)四、python 示例补充 1:熵熵的定义熵的性质熵的单位和对数底数熵的最大值高熵、低熵的分辨补充 2:概率密度 和 高斯核概率密度高斯核拓展3 :核密度函数带宽估计在…...