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

【C语言】12.C语言内存函数

文章目录

  • 1.memcpy使用和模拟实现
  • 2.memmove使用和模拟实现
  • 3.memset函数的使用
  • 4.memcmp函数的使用


memcpy:内存拷贝

memmove:内存移动

memset:内存设置

memcmp:内存比较

1.memcpy使用和模拟实现

memcpy:内存拷贝

void * memcpy ( void * destination, const void * source, size_t num );目标空间的地址          源空间的地址        被拷贝的字节个数
返回的是目标空间的起始地址
void*指针接收任意参数的地址

函数memcpysource的位置开始向后复制num个字节的数据到destination指向的内存位置。

这个函数在遇到 ‘\0’ 的时候并不会停下来。

如果sourcedestination有任何的重叠,复制的结果都是未定义的。

#include <stdio.h>
#include <assert.h>void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;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 };int arr2[20] = { 0 };//将arr1中的34567拷贝到arr2中my_memcpy(arr2, arr1 + 2, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}

打印:

3 4 5 6 7 0 0 0 0 0

注意:对于重叠的内存,交给memmove来处理。

重叠的意思就是:

my_memcpy(arr1 + 2, arr1, 20);

比如你想把arr数组里的某些数用arr数组的某些数替换,这样会出问题。

例如:

void* my_memcpy(void* dest, const void* src, size_t num) {int i = 0;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 };//我们的想法是:将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖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 1 2 1 8 9 10

打印这个玩意儿?怎么和猜的不一样呢?

1 2 3 4 5 6 7 8 9 10

程序里先把1替换了3

1 2 1 4 5 6 7 8 9 10

然后2替换了4

1 2 1 2 5 6 7 8 9 10

然后原来3位置的1替换了5

1 2 1 2 1 6 7 8 9 10

然后原来4位置的2替换了6

1 2 1 2 1 2 7 8 9 10

然后原来5位置的1替换了7

1 2 1 2 1 2 1 8 9 10

memcpy函数不负责重叠内存的拷贝,只负责不重叠的内存,非要使用,结果就是未定义的。

不过说是这么说,有些时候memcpy也能实现重叠内存的拷贝。我们可以认为memcpy实现的拷贝不一定都对。所以重叠就用memmove函数。

memmove函数来处理重叠内存的拷贝。


2.memmove使用和模拟实现

memmove:内存移动

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

memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。

#include <string.h>int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖memmove(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

在这里插入图片描述

这个函数实际上就是实现src拷贝到dest。

如果是上面一种情况的话,我们可以先把3给1,然后把4给2,然后把5给3…这样就可以实现重叠内存的处理。(从前向后)

如果是中间一种情况的话,我们可以先把7给9,然后把6给8,然后把5给7…这样就可以实现重叠内存的处理。(从后向前)

如果是下面一种情况的话,我们可以按顺序把3给8,把4给9,把5给10…这样就可以实现重叠内存的处理。(从后向前)

在这里插入图片描述

两个紫色竖线表示的位置分别为src的起始位置和结束位置。

这两根紫色竖线把情况分成了三种。

第一种情况是(从前向后)

第二种情况是(从后向前)

模拟实现:

void* my_memmove(void* dest, const void* src, size_t num) {void* ret = dest;assert(src && 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;
}int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖my_memmove(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

3.memset函数的使用

memset:内存设置

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

memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。

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

打印:

xxxxxxworld

4.memcmp函数的使用

memcmp:内存比较

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

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

返回值如下:

在这里插入图片描述


#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

打印:

0

因为前12个字节一样


#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,6,5 };//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00int ret = memcmp(arr1, arr2, 13);printf("%d\n", ret);return 0;
}

打印:

-1

因为第13个字节不一样

相关文章:

【C语言】12.C语言内存函数

文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy&#xff1a;内存拷贝 memmove&#xff1a;内存移动 memset&#xff1a;内存设置 memcmp&#xff1a;内存比较 1.memcpy使用和模拟实现 memcpy&#xff1a;内存拷贝 void…...

Django:如何将多个数据表内容合在一起返回响应

一.概要 Django写后端返回响应时&#xff0c;通常需要返回的可能不是一个数据表的内容&#xff0c;还包括了这个数据表的外键所关联的其他表的一些字段&#xff0c;那该如何做才能把他们放在一起返回响应呢&#xff1f; 二.处理方法 在这里我有三个数据表 第一个是航空订单&…...

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!

6月18日&#xff0c;国家信息安全漏洞库&#xff08;CNNVD&#xff09;2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现&#xff0c;被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…...

uni-app中使用富文本rich-text个人经验

rich-text是在uni-app一个内置组件&#xff0c;用于高性能地渲染富文本内容。先贴一下官方的属性列表&#xff1a; 先说一下“selectable” 长按选择区域复制&#xff0c;这个我在APP项目中 不起作用&#xff0c;可能像文档说的&#xff0c;只支持“百度小程序”吧。在APP端起作…...

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化

1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词&#xff1a;选址定容 电动汽车 充电站位置 仿真平台&#xff1a;MATLAB 主要内容&#xff1a;代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题&#xff0c;提出了能够计及地理因素和服…...

从零开始! Jupyter Notebook的安装教程

&#x1f680; 从零开始! Jupyter Notebook的安装教程 摘要 &#x1f4c4; Jupyter Notebook 是一个广受欢迎的开源工具&#xff0c;特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤&#xff0c;包括各种操作系统的安装方法&am…...

web前端信息卡:深入探索与实用指南

web前端信息卡&#xff1a;深入探索与实用指南 在数字化时代&#xff0c;web前端信息卡已成为我们日常生活和工作中的重要组成部分。这些小巧而强大的工具&#xff0c;能够在有限的空间内展示丰富的信息&#xff0c;提升用户体验。然而&#xff0c;设计一个出色的web前端信息卡…...

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!

天津工业大学&#xff08;Tiangong University&#xff09;&#xff0c;简称“天工大”&#xff0c;位于天津市&#xff0c;是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…...

WPF三方UI库全局应用MessageBox样式(.NET6版本)

一、问题场景 使用HandyControl简写HC 作为基础UI组件库时&#xff0c;希望系统中所有的MessageBox 样式都使用HC的MessageBox&#xff0c;常规操作如下&#xff1a; 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…...

ABAP-03基础数据类型

基本数据类型 数据类型默认大小&#xff08;byte&#xff09;有效大小初始值说明示例C11-65535SPACE文本字符&#xff08;串&#xff09;‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…...

Zabbix监控神通数据库教程

作者&#xff1a;乐维社区&#xff08;forum.lwops.cn&#xff09; 乐乐 神通数据库&#xff0c;即神舟通用数据库&#xff08;ShenTong Database&#xff09;&#xff0c;是我国自主研发的一款关系型数据库管理系统。它在国内市场有一定的应用&#xff0c;尤其是在一些对数据安…...

5.音视频基础 FLV

目录 简说FLV FLV Header FLV Body Tag Header ​编辑Tag Data Audio Data Video Data Script Data 简说FLV FLV格式可以包含音频、视频和文本数据&#xff0c;并且可以在网络上进行流媒体传输。优点是文件大小较小&#xff0c;压缩效率高&#xff0c;并且可以在较低…...

Ubuntu server 24 (Linux) 安装客户端(windows/linux) Zabbix 7.0 LTS Zabbix agent2

一 Ubuntu(linux)安装客户端 1 Ubuntu 24 安装Zabbix agent2 #安装agent库 sudo wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-1ubuntu24.04_all.deb sudo dpkg -i zabbix-release_7.0-1ubuntu24.04_all.deb sudo apt u…...

在 Ubuntu 上取消登录密码和锁屏功能的简易指南

你可以使用终端命令来直接设置取消登录密码和锁屏功能。以下是具体步骤&#xff1a; 取消登录密码 打开终端。编辑 /etc/gdm3/custom.conf 文件&#xff1a;sudo nano /etc/gdm3/custom.conf在 [daemon] 部分下&#xff0c;添加或修改以下行&#xff1a;AutomaticLoginEnable…...

PAT B1046. 划拳

题目描述 划拳是中国酒文化中一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字&#xff0c;同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和&#xff0c;谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。…...

奥特曼谈AI的机遇、挑战与人类自我反思:中国将拥有独特的大语言模型

奥特曼在对话中特别提到&#xff0c;中国将在这个领域扮演重要角色&#xff0c;孕育出具有本土特色的大语言模型。这一预见不仅彰显了中国在全球人工智能领域中日益增长的影响力&#xff0c;也预示着未来技术发展的多元化趋势。 ①奥特曼认为AI在提升生产力方面已显现积极作用&…...

Java版-剑指offer数据结构与算法 视频教程 下载

Java版-剑指offer数据结构与算法 视频教程 下载 01-数据结构与算法入门基础 clip.mp4 02-clip1.mp4 03-clip2.mp4 04-基础数据结构&#xff1a;数组&链表&#xff08;一&#xff09;.mp4 05基础数据结构&#xff1a;数组&链表&#xff08;二&#xff09;.mp4 06-基…...

mac禁用电池睡眠-mac盒盖连接显示器

mac禁用电池睡眠-mac盒盖连接显示器-mac断点盒盖连接显示器 讲解&#xff1a;mac盒盖的时候连接显示器会睡眠并断开和显示器的连接&#xff0c;只有在电池->选项->选择使用电源适配器的时候防止睡眠&#xff0c;才可以连接电源线外界显示器 但是苹果的电池相当于手机电…...

最好用的智能猫砂盆存在吗?自用分享智能猫砂盆测评!

在现代都市的忙碌生活中&#xff0c;作为一名上班族&#xff0c;经常因为需要加班或频繁出差而忙碌得不可开交。急匆匆地出门&#xff0c;却忘了给猫咪及时铲屎。但是大家要知道&#xff0c;不及时清理猫砂盆会让猫咪感到不适&#xff0c;还会引发各种健康问题&#xff0c;如泌…...

LeetCode 每日一题 2748. 美丽下标对的数目

Hey编程小伙伴们&#x1f44b;&#xff0c;今天我要带大家一起解锁力扣上的一道有趣题目—— 美丽下标对的数目 - 力扣 (LeetCode)。这不仅是一次编程挑战&#xff0c;更是一次深入理解欧几里得算法判断互质的绝佳机会&#xff01;&#x1f389; 问题简介 题目要求我们给定一…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...