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

内存操作函数

在这里插入图片描述

前言

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏: 🍔🍟🌯 c语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:介绍c语言中有关指针更深层的知识.
金句分享:

✨未来如星辰大海般璀璨✨
✨不必踌躇于过去的半亩方塘.✨

目录

  • 前言
  • 一、memcpy函数
    • 函数模型:
    • 函数参数:
    • 函数的应用:
    • 函数的模拟实现:
  • 二、memmove函数
    • 函数模型:
    • 函数参数:
    • 函数模拟实现
  • 三、memcmp函数
    • 函数模型:
    • 函数参数:
    • 函数应用:
    • 模拟实现
  • 四、memset函数
    • 函数模型:
    • 函数参数

一、memcpy函数

函数模型:

在这里插入图片描述

函数参数:

参数意义
destination指向目的地地址的指针,类型转换为 void* 类型的指针。
source指向要复制的数据源的指针,类型转换为 const void* 类型的指针。
num要复制的字节数

函数头文件:

#include <string.h>

函数功能:
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

注意:
要保证目的地址存的下源地址的内容,要守规矩哦!

1.为什么有了strcpy函数还要有memcpy函数呢?

因为strcpy函数是字符串拷贝,包括strncpy函数也是一样,只能拷贝字符串,对于其它类型,比如整形的拷贝就无能为力.

2.为什么要设置为void*类型?

如果看过前面qsort函数的模拟,这里应该也不难理解,因为要拷贝的类型是未知的,为了能够接收所有类型,所以设置为void*,使用时强制转换为char*类型,然后按字节个数拷贝即可.

函数的应用:

1.将arr2数组的前三个元素拷贝到arr1数组的前三个位置.
2.将字符串str2全部除了’\0’以外,拷贝到str1字符串.

#include <stdio.h>
#include <string.h>
int main()
{int arr1[10] = { 6,6,6,6,6,6,6,6,6,6 };int arr2[] = { 1,2,3,4,5,6,7,8 };int arr2sz= sizeof(arr2) / sizeof(arr2[0]);char str1[] = "XXXXXXXXXXXXXXXX";char str2[] = "Hello CSDN!";int str2sz= sizeof(str2) / sizeof(str2[0]);memcpy(arr1, arr2, sizeof(int) * 3);for (int i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("\n");memcpy(str1, str2, sizeof(char) * str2sz - 1);//-1是因为这里使用的是sizeof()函数计算的长度,会包括\0printf("%s", str1);printf("\n");return 0;
}

运行结果:

1 2 3 6 6 6 6 6 6 6
Hello CSDN!XXXXX

函数的模拟实现:

#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{assert(destination);assert(source);while (num--){//void*类型不可直接使用,要强制转化*(char*)destination = *(char*)source;//*是为了找到该地址所对应的字符串((char*)destination)++;//指针分别往后走,所以不需要解引用((char*)source)++;}
}

思考:
memcpy函数可以拷贝内存重叠的地址吗?
即source和destination有重叠的时候.(可以试试).

二、memmove函数

函数模型:

在这里插入图片描述

函数参数:

参数意义
destination指向目的地地址的指针,类型转换为 void* 类型的指针。
source指向要复制的数据源的指针,类型转换为 const void* 类型的指针。
num要复制的字节数

函数作用:
该函数与memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠
的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理,其实在有的编译器中,对于memcpy函数也进行了优化,也是允许内存重叠的.

但牛牛认为,还是有必要掌握这种更"稳妥"的函数的.

情况1

在这里插入图片描述
这种情况我们可以正常的从前向后(前->后) 拷贝.
即:先将6拷贝至2位置,再讲7拷贝至3位置……

在这里插入图片描述
这种情况我们使用从从前向后(前->后)拷贝则达不到我们的要求.
如果我们先将6拷贝至8处,7拷贝至9处,则原来的8 9都被修改了.
这时我们需要从后往前(后->前)拷贝.

即先将11拷贝至13处,再将9拷贝至12处……

在这里插入图片描述
其实这种情况并不是内存地址重叠,目的地址出现在前面也是一样的,都是可以从前向后(前->后)拷贝和从后往前(后->前)拷贝皆可.

函数模拟实现

#include <stdio.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, size_t num)
{void* ret = destination;//保留目的地原来的首地址assert(destination && source);//防止传错地址if (destination < source)//情况1时,目的地址的首地址小于源地址首地址{//前-->后while (num--){*(char*)destination = *(char*)source;((char*)destination)++;((char*)source)++;}}else{//后->前while (num--){*((char*)destination + num) = *((char*)source + num);//注意,这里如果以destination为1的偏移量,+num则是目的地地址的最后一个元素的地址.}}return ret;
}

代码测试:
情况1;

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr + 1, arr + 5, sizeof(int) * 5);int sz= sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

运行结果:

1 6 7 8 9 11 7 8 9 11 12 13

情况2:


int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr +7, arr + 5, sizeof(int) * 5);int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

运行结果:

1 2 3 4 5 6 7 6 7 8 9 11

三、memcmp函数

函数模型:

在这里插入图片描述

函数参数:

参数意义
ptr1指向要比较的内容1,指针
ptr2指向要比较的内容2,指针
num要比较的字节个数

函数头文件:

#include <string.h>

函数功能
比较从ptr1和ptr2指针开始的num个字节.

注意与strcmp函数区分:

strcmp函数:用于比较字符串是否相等,只用于比较字符

memcmp:按字节比较,两个指针所指向的内容是否相等.可用于比较不同类型的元素,但是是按字节比较.

返回值意义
<0第一个不想等的字节中的值的str1的值小于str2中的值(arr1<arr2)
0两个指针的内容相等
>0第一个不相等的字节的str1的值大于于str2中的值(arr1>arr2

函数应用:

试着猜一下这段代码的值?(vs2022环境(小端))

//memcmp函数模拟
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,4,7,255 };int arr2[] = { 1,4,7,511 };int ret=memcmp(arr1, arr2, 13);printf("%d", ret);return 0;
}

在这里插入图片描述
答案:

0

解析:
首先这里是小端存储模式.则这两个数组在内存中存储的是:

arr1 :01 00 00 00 04 00 00 00 07 00 00 00 FF 00 00 00 (16进制,两位代表一个字节)
arr2 :01 00 00 00 04 00 00 00 07 00 00 00 FF 10 00 00

很明显,这里前四个元素(1,4,7)是相等的,而元素255和元素511则是第一个字节的内容相等,所以当比较的元素是[0,13]时,memcmp函数会认为这两个指针所指向的内容是相同的,故返回值是0.

可以试着改成14字节,返回值会是-1,因为第14个字节,arr1是00.arr2是1,则arr1<arr2;

模拟实现

#include<assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{assert(ptr1 && ptr2);while (num--)//比较num个字节{if (*(char*)ptr1 == *(char*)ptr2)//相等继续往后比较{((char*)ptr1)++;((char*)ptr2)++;}else if (*(char*)ptr1 > *(char*)ptr2)//str1大则返回大于0的数{return 1;}else//str2大返回小于0的数{return -1;}}return 0;//比完了num个字节都相等则返回0
}

四、memset函数

函数模型:

在这里插入图片描述
头文件:

#include <string.h>

函数参数

参数意义
ptr指向要设置内容的空间
value要设置的值,虽然是整形类型,但是也可以是字符,字符会转化为对应的ASCII码值
num要设置空间内容的字节个数

函数功能:
将ptr所指向的空间,的num个字节设置为value值,注意这里也是按字节设置.

示例:

#include <stdio.h>
#include <string.h>
int main()
{int arr[5] = { 0 };memset(arr, 1, 20);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}

结果会是下面这个吗?

1 1 1 1 1

正确答案:

16843009 16843009 16843009 16843009 16843009

为什么呢?
我们可以试着通过调试找到答案.

执行语句memset(arr, 1, 40);后

很显然,这里是将20个字节设置为了1,而一个整形占4个字节;

那么怎样才可以将每个元素都设置为1呢?

#include <stdio.h>
#include <string.h>
int main()
{int arr[5] = { 0 };for (int i = 0; i < 5; i++){memset(arr+i, 1, 1);}for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}

其实这样才能达到我们想要的结果,这里是将一个字节设置为1,然后跳过四个字节(下一个元素),再将这个元素的首字节设置为1.
但是这样是不是有点太麻烦了,所以一般memset函数一般不会这么用,一般memset函数用来将一段空间的元素按字节都初始化为0,在后面我们用到malloc函数向内存申请空间时,得到的空间里面存放的值都是随机值,这时我们可以使用它来帮助我们完成初始化操作.

好了,今天的内存操作函数就讲到这里了,我们下周再见!
最后,如果文章对大家有帮助的话,求一波三连吧!
💗💗💗886
在这里插入图片描述

相关文章:

内存操作函数

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨未来…...

免费搭建个人博客

免费搭建个人博客,并发布到公网 利用hexo搭建个人博客&#xff0c;通过gitee的pages发布到公网 1 前置准备 安装git、安装node.js&#xff08;尽量选择长期支持的版本) node.js官网&#xff1a;https://nodejs.org/en/ git官网&#xff1a;https://git-scm.com/book/zh/v2 安装…...

【Vue全家桶】详解Vue Router(一)

【Vue全家桶】Vue Router详解&#xff08;一&#xff09; Vue系列文章目录&#xff1a; 内容参考链接Vue&#xff08;一&#xff09;【Vue全家桶】邂逅Vue、Vue的多种引入方式Vue&#xff08;二&#xff09;【Vue全家桶】声明式编程、MVVMVue&#xff08;三&#xff09;【Vue…...

9大 HIVE SQL 最频繁被问到的面试题

SQL是用于数据分析和数据处理的最重要的编程语言之一&#xff0c;因此与数据科学相关的工作&#xff08;例如数据分析师、数据科学家和数据工程师&#xff09;在面试时总会问到关于 SQL 的问题。 SQL面试问题旨在评估应聘者的技术和解决问题的能力。因此对于应聘者来说&#x…...

学大数据算跟风吗?

随着互联网、物联网和人工智能等技术的不断发展&#xff0c;大数据技术逐渐进入人们的视野&#xff0c;成为一个备受关注的热点话题。那么&#xff0c;大数据专业好学吗&#xff1f;前景如何&#xff1f;下面我们来一起探讨一下。 一、大数据专业的学习难度 大数据技术是一种综…...

[C#]关于ListBox的坑

在用C#写个Demo程序的时候&#xff0c;使用ListBox保存读取到的每行内容。然后在重复读取的时候需要清除ListBox中的内容&#xff0c;我看到ListBox有清除的函数&#xff1a;lsbFiles.Items.Clear();以为这个函数就可以解决所有的问题&#xff0c;但是....于是想了个方法准备一…...

Apache POI 入门·第一话

文章目录1 摘要2 Apache POI2.1 介绍2.2 应用场景2.3 入门案例2.3.1 将数据写入Excel文件2.3.1.1 导入POI maven坐标2.3.1.2 代码开发2.3.1.3 实现效果2.3.2 读取Excel文件中的数据2.3.3 实现效果2.4 开发案例——导出运营数据Excel报表2.4.1 产品原型2.4.2 接口设计2.4.3 代码…...

8个python自动化脚本提高打工人幸福感~比心~

人生苦短&#xff0c;我用Python 最近有许多打工人都找我说打工好难 每天都是执行许多重复的任务&#xff0c; 例如阅读新闻、发邮件、查看天气、打开书签、清理文件夹等等&#xff0c; 使用自动化脚本&#xff0c;就无需手动一次又一次地完成这些任务&#xff0c; 非常方便…...

【嵌入式烧录/刷写文件】-1-详解Motorola S-record(S19/SREC/mot/SX)格式文件

目录 1 什么是Motorola S-record 2 Motorola S-record的格式 2.1 Motorola S-record的结构 2.1.1 “Record type记录类型”的说明 2.1.2 “Record length记录长度”的说明 2.1.3 如何计算“Checksum校验和” 2.2 Record order记录顺序 2.3 Text line terminator文本行终…...

图形视图界面 图形效果

Qt的标准图形效果类&#xff1a; QGraphicsBlurEffect提供模糊效果QGraphicsColorizeEffect提供染色效果QGraphicsDropShadowEffect提供阴影效果QGraphicsOpacityEffect提供透明效果 QGraphicsBlurEffect&#xff08;模糊效果&#xff09; 模糊效果会模糊源。此效果对于减少细…...

ElementUI学习笔记

目录 一、简单介绍 二、安装 1、下载 2、引入 三、布局 1、简介 2、使用 3、好处 四、布局容器 1、常见排布 2、调整样式 五、按钮 1、简单引用 2、改变样式 3、加载中效果 六、表格 1、简单使用 2、样式修改 七、对话框 1、简单使用 2、添加自定义内容 3、…...

安装KVM并创建虚拟机及基本使用

#环境说明&#xff1a;Centos7 环境准备&#xff1a; CPU开启虚拟化&#xff0c;给宿主机的CPU和内存分配足够多的配置 安装KVM 1.安装相关软件包 yum -y install qemu-kvm libvirt virt-manager virt-install virt-viewer 软件包简介&#xff1a; qemu-kvm: 为kvm提供…...

一种LCD屏闪问题的调试

背景 项目使用ESP32-S3 RGB接口驱动的LCD, 框架 idf-v5.0, LVGL-v7.11 显示画面正常, 但肉眼可见的像是背光在闪烁, 背光电路是应用很久的经典电路, 且排查背光驱动无错, 但开机一段时间后, 闪烁会明显减轻 记录 这块屏的显示驱动芯片为ST7701S, 查看芯片手册有说明特定的上…...

Java程序运行在Docker等容器环境有哪些新问题?

第30讲 | Java程序运行在Docker等容器环境有哪些新问题&#xff1f; 如今&#xff0c;Docker 等容器早已不是新生事物&#xff0c;正在逐步成为日常开发、部署环境的一部分。Java 能否无缝地运行在容器环境&#xff0c;是否符合微服务、Serverless 等新的软件架构和场景&#x…...

C语言面试最常问的三个关键字

文章目录前言一&#xff0c;static关键字的作用二&#xff0c;const 关键字的作用2.1&#xff0c; 修饰局部变量2.2&#xff0c;修饰指针2.3&#xff0c; 修饰函数形参2.4&#xff0c;修饰函数的返回值三&#xff0c;volatile关键字的作用前言 面试的时候&#xff0c;C语言最常…...

【Linux】-初识Linux

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Linux】 分享&#xff1a;逆着光行走&#xff0c;任风吹雨打。 ——《起风了》 主要内容&#xff1a;Linux的一些最基本指令&#xff0c;Linux的小程序&#xff0c;Linux关于连…...

精选7个 Python 学习资源库,助你成为优秀的开发者

当你在学习编程时&#xff0c;很容易被大量的资源所吓到&#xff0c;不知道该从何开始。 GitHub 仓库是一个很好的起点&#xff0c;因为它们提供了一种非常实用的方式来了解实际的编程应用。你可以查看其他人的代码&#xff0c;并将其与自己的代码进行比较和学习。 当涉及到 …...

【大数据处理与可视化】三 、Pandas库的运用

【大数据处理与可视化】三 、Pandas库的运用实验目的实验内容实验步骤一、使用pandas库分别创建Series对象和DataFrame对象&#xff0c;并对创建的对象使用索引、排序等相关操作&#xff1b;练习DataFrame对象的统计计算和统计描述的功能。1&#xff06;2、创建一个DataFrame(d…...

FPGA解码SDI视频任意尺寸缩放拼接输出 提供工程源码和技术支持

目录1、前言2、SDI理论练习3、设计思路和架构SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像缩放FDMA图像缓存实现拼接HDMI驱动4、vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案&#…...

线索二叉树结构

线索二叉树结构1.线索二插树的作用2.线索二叉树的定义3.线索二叉树的结构4. 线索二叉树的操作4.1. 建立一棵中序线索二叉树4.2. 在中序线索二叉树上查找任意结点的中序前驱结点4.3. 在中序线索二叉树上查找任意结点的中序后继结点4.4. 在中序线索二叉树上查找任意结点在先序下的…...

6.网络爬虫——BeautifulSoup详讲与实战

网络爬虫——BeautifulSoup详讲与实战BeautifulSoup简介&#xff1a;BS4下载安装BS4解析对象Tag节点遍历节点find_all()与find()find_all()find()豆瓣电影实战前言&#xff1a; &#x1f4dd;​&#x1f4dd;​此专栏文章是专门针对网络爬虫基础&#xff0c;欢迎免费订阅&#…...

Vue:路由管理模式

三种模式 Vue.js 的路由管理有三种模式&#xff1a; Hash 模式&#xff08;默认&#xff09;&#xff1a;在 URL 中使用 # 符号来管理路由。例如&#xff0c;http://example.com/#/about。这个模式的好处是可以避免浏览器向服务器发送不必要的请求&#xff0c;并且不需要特殊…...

7个最好的PDF编辑器,帮你像编辑Word一样编辑PDF

PDF 是具有数字思维的组织的重要交流工具。提供高效的工作流程和更好的安全性&#xff0c;可以创建重要文档并与客户、同事和员工共享。文档的布局已锁定&#xff0c;因此无论在什么设备上查看&#xff0c;格式都保持不变。这是让每个人保持一致的好方法——尤其是那些使用Micr…...

【数据结构】树的介绍

文章目录前言树的概念及结构树的概念树的表示树在实际中的运用二叉树的概念及结构二叉树的概念现实中的二叉树特殊的二叉树二叉树的性质二叉树的储存结构顺序存储链式存储写在最后前言 &#x1f6a9;本章给大家介绍一下树。树的难度相对于前面的数据结构来说&#xff0c;又高了…...

CoreDNS 性能优化

CoreDNS 作为 Kubernetes 集群的域名解析组件&#xff0c;如果性能不够可能会影响业务&#xff0c;本文介绍几种 CoreDNS 的性能优化手段。合理控制 CoreDNS 副本数考虑以下几种方式:根据集群规模预估 coredns 需要的副本数&#xff0c;直接调整 coredns deployment 的副本数:k…...

前端三剑客常见面试题及其答案

目录 1、什么是 HTML&#xff1f; 2、什么是 CSS&#xff1f; 3、什么是 JavaScript&#xff1f; 4、什么是盒模型&#xff1f; 5、什么是浮动&#xff1f; 6、什么是定位&#xff1f; 7、什么是选择器&#xff1f; 8、什么是事件&#xff1f; 前端的三剑客指的是 HTML…...

【DFS专题】深度优先搜索 “暴搜”优质题单推荐 10道题(C++ | 洛谷 | acwing)

文章目录题单一、模板 [极为重要]全排列DFS组合型DFS指数DFS二、专题烤鸡 (指数BFS&#xff09;P1088 火星人 【全排列】P1149 火彩棒 [预处理 ]P2036 PERKETP1135 奇怪的电梯 暴力P1036 [NOIP2002 普及组] 选数 &#xff08;组合&#xff09;P1596 [USACO10OCT]Lake Counting …...

微信小程序自定义组件生命周期有哪些?

微信小程序自定义组件的生命周期函数分为三类&#xff1a; 创建时执行的生命周期函数、更新时执行的生命周期函数和销毁时执行的生命周期函数。 下面是具体的生命周期函数及其触发时机&#xff1a; 创建时执行的生命周期函数&#xff1a; created&#xff1a;在组件实例刚刚…...

Linux就该这么学(六)

一、从“/”开始 Linux 系统中的文件和目录名称是严格区分大小写的。例如&#xff0c;root、rOOt、rooT 均代表不同的目录&#xff0c;并且文件名称中不得包含斜杠&#xff08;/&#xff09;。Linux 系统中的文件存储结构如下图所示。 在 Linux 系统中&#xff0c;最常见的目录…...

目标检测算法——YOLOv5/v7/v8改进结合涨点Trick之Wise-IoU(超越CIOU/SIOU)

超越CIOU/SIOU | Wise-IoU助力YOLO强势涨点&#xff01;&#xff01;&#xff01; 论文题目&#xff1a;Wise-IoU: Bounding Box Regression Loss with Dynamic Focusing Mechanism 论文链接&#xff1a;https://arxiv.org/abs/2301.10051 ​ 近年来的研究大多假设训练数据中的…...

聊城做网站建设的公司/怎么样推广自己的公司

题目链接&#xff1a;https://cn.vjudge.net/contest/250168#problem/D 题目大意&#xff1a;给你一些点的坐标&#xff0c;这些点属于两个帮派&#xff0c;让你将这些点分进两个不能重叠的矩形中&#xff0c;问你最多两个矩形中不同帮派之和为多少&#xff1f; 具体思路&…...

做网站卖草坪赚钱吗/五合一网站建设

利用到Java多线程的知识&#xff0c;下面是我的实现代码&#xff1a; import java.util.ArrayList; import java.util.Iterator; import java.util.List;/*** 假设有3个车位可以停车&#xff0c;写一个程序模拟多个用户开车离开、停车入库的效果。* * author qiaoao*/ public …...

深圳网站建设 沙漠风/武汉seo首页优化技巧

前言 Hello&#xff0c;开始回归开始每周更新一到两篇博客&#xff0c;本节我们回归下EF Core基础&#xff0c;来讲述EF Core中到底是如何映射的&#xff0c;废话少说&#xff0c;我们开始。 One-Many Relationship&#xff08;一对多关系&#xff09; 首先我们从最简单的一对多…...

网站建设海南/国内重大新闻十条

一、Lua与C的交互机制——Lua堆栈 1)交互机制 Lua和C 的交互机制的基础在于Lua提供了一个虚拟栈&#xff0c;C 和Lua之间的所有类型的数据交换都通过这个栈完成。无论何时C想从Lua中调用一个值&#xff0c;被请求的值将会被压入栈&#xff0c;无论何时C想要传递一个值给Lua&…...

wordpress无法加载主题/技术教程优化搜索引擎整站

其实我一直不太理解递归函数&#xff0c;不太理解递归的思想&#xff0c;最近看见一篇阐述递归函数思想的文章&#xff0c;先mark一下&#xff0c; 等手头工作干完了再来仔细理解。 https://blog.csdn.net/doncoder/article/details/79182542 转载于:https://www.cnblogs.com/r…...

门户是什么意思/网站优化方法

#include<iostream>class CBox { public://公有的函数成员//显式构造函数explicit CBox(double lv 1.0, double wv 1.0, double hv 1.0) :m_length{ lv }, m_width{ wv }, m_height{ hv }{std::cout << "调用构造函数" << std::endl; }//函数成…...