c语言回顾-内存操作函数

目录

前言

1.memcpy 函数

1.1函数介绍

1.2与strcpy的区别

1.3memcpy的模拟

2.memmove 函数

2.1函数介绍和使用

2.2函数的模拟

3.memset函数

3.1函数介绍

3.2函数的模拟

4.memcmp函数

4.1函数的使用

4.2函数的模拟

结束语


前言

在动态内存的章节中小编详细讲解了动态内存分配函数,在这里小编将补充内存操作函数的讲解!

1.memcpy 函数

1.1函数介绍

原型:void *memcpy(void *dest, const void *src, size_t n);

功能:将 n 字节的数据从源内存区域 src 复制到目标内存区域 dest

  • 参数:
    • dest:指向目标内存区域的指针。
    • src:指向源内存区域的指针。
    • n:要复制的字节数。
  • 返回值:返回指向目标内存区域的指针。
char src[10] = "Hello";
char dest[10];
memcpy(dest, src, 5); // 将前5个字节从 src 复制到 dest

又比如将数组中的指定的数据放到另一个数组中

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

输出结果:1 2 3 4 5 0 0 0 0 0

1.2与strcpy的区别

  1. 数据类型

    • memcpy:适用于任意类型的数据,复制的是指定的字节数。
    • strcpy:仅适用于字符串,复制的是字符,直到遇到空字符为止。
  2. 复制内容

    • memcpy:不会检查内容,只复制指定字节数,即使其中包含空字符。
    • strcpy:遇到空字符时停止复制,并将空字符包含在内。
  3. 使用场景

    • memcpy:适用于需要复制特定大小内存块的场景,例如结构体、数组等。
    • strcpy:适用于字符串复制的场景,确保字符串以空字符结尾。
  4. 安全性

    • memcpy:需要手动管理字符串结尾,容易出现内存越界问题。
    • strcpy:自动处理字符串结尾,但在源字符串未包含空字符时容易造成缓冲区溢出。

注意:如果source和destination有任何的重叠,复制的结果都是未定义的。但是vs,vscode 等运行出来的结果却是对的,或许提升了性能。

1.3memcpy的模拟

因为我们不知道所要复制的数据类型是什么,所以参数类型我们设置为void*,接受各种类型,

用因为void*不能解应用,所以强制转化类型操作,强制转化为char*

#include <stdio.h>
void*my_memcpy(void*dest,const void*src,size_t count)
{void*ret=dest;while(count--){*(char*)dest=*(char*)src;//强制转化类型dest=(char*)dest+1;src=(char*)src+1;}return ret;
}
int main()
{
int arr1[10]={0};
int arr2[10]={1,2,3,4,5,6,7,8,9,10};
my_memcpy(arr1, arr2,20); //5个整型复制占20个字节
for(int i=0;i<10;i++)
{printf("%d ",arr1[i]);
}
return 0;
}

运行结果:

在 my_memcpy 函数中使用

*(char*)dest = *(char*)src ;dest = (char*)dest + 1;src = (char*)src + 1

是因为我们希望逐字节复制数据。使用 char 类型指针可以确保每次操作都是一个字节,这对于实现 memcpy 函数的逐字节复制行为是必要的。 

为什么使用 `char`

逐字节复制:char 类型指针每次移动一个字节,这是我们想要的行为,因为 memcpy 需要逐字节复制数据。

通用性:char类型适用于任何类型的数据,无论是整数、浮点数还是结构体,因为它操作的是最小单位的字节。

如果使用 int或double其他类型指针,则会面临对齐问题和类型限制,无法实现 memcpy函数的通用性。

2.memmove 函数

2.1函数介绍和使用

void * memmove ( void * destination, const void * source, size_t num );
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
使用:
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[10]={1,2,3,4,5,6,7,8,9,10};
memmove(arr1+3, arr1,20); 
for(int i=0;i<10;i++)
{printf("%d ",arr1[i]);
}
return 0;
}

运行结果:

2.2函数的模拟

#include <stdio.h>
#include <string.h>
void *my_memmove(void *dest, const void *src, size_t n)
{char *csrc = (char *)src;char *cdest = (char *)dest;if(csrc<cdest){for(int i=n-1;i>=0;i--){cdest[i]=csrc[i];}}else{for(int i=0;i<n;i++){cdest[i]=csrc[i];}}return dest;
}
int main()
{
int arr1[10]={1,2,3,4,5,6,7,8,9,10};
my_memmove(arr1, arr1+4,20); 
for(int i=0;i<10;i++)
{printf("%d ",arr1[i]);
}
return 0;
}

my_memove(arr1+4,arr1,20)时

画图解释:

3.memset函数

3.1函数介绍

void * memset ( void * ptr, int value, size_t num );
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。 函数用于将指定的值设置到一段内存区域中。它在初始化数组或结构体时非常有用。
#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "hello world";memset (str+2,'x',6);printf(str);return 0;
}

输出结果:hexxxxxxrld

3.2函数的模拟

#include <stdio.h>
#include <string.h>
void*my_memset(void*dest, int c, size_t count)
{char*str = (char*)dest;while(count--){*str++ = (char)c;}return dest;
}
int main ()
{char str[] = "hello world";my_memset (str+2,'x',6);printf("%s\n", str);int arr[10]={1,2,3,4,5,6,7,8,9,10};my_memset(arr,0,20);
for(int i=0;i<10;i++)
{printf("%d ",arr[i]);
}return 0;
}

4.memcmp函数

4.1函数的使用

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
#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;
}

4.2函数的模拟

#include <stdio.h>
#include <string.h>
int my_memcmp(const void *str1, const void *str2, size_t n)
{const unsigned char *s1 = (const unsigned char *)str1;const unsigned char *s2 = (const unsigned char *)str2;/*size_t i;for (i = 0; i < n; i++){if (s1[i] < s2[i])return -1;if (s1[i] > s2[i])return 1;}return 0;*/while (n--){if (*s1 != *s2)return (*s1 - *s2);s1++;s2++;}return 0;
}int main()
{int a[6]={1,2,3,4,5,6};int b[6]={1,2,3,4,5,7};int n;n = my_memcmp(a,b,20);if (n > 0)printf("Array 'a' is greater than array 'b'.\n");
else if (n < 0)printf("Array 'a' is less than array 'b'.\n");
elseprintf("Array 'a' is the same as array 'b'.\n");return 0;
}

比较前五个数数据:

结束语

OK啦,本节的干货也彻底上完了,相信大家多内存函数有了进一步的认识,

最后友友们动动你们尊贵的手指给小编点点赞,评论一下吧,忠诚感谢大家的支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.基于SpringBoot的SSMP整合案例-表现层开发

目录 1.基于Restfu1进行表现层接口开发 1.1创建功能类 1.2基于Restful制作表现层接口 2.接收参数 2使用Apifox测试表现层接口功能 保存接口&#xff1a; 分页接口&#xff1a; 3.表现层一致性处理 3.1先创建一个工具类&#xff0c;用作后端返回格式统一类&#xff1a;…

【人工智能学习之图像操作(一)】

【人工智能学习之图像操作&#xff08;一&#xff09;】 图像读写创建图片并保存视频读取色彩空间与转换色彩空间的转换通道分离理解HSV基本图形绘制 阀值操作OTSU二值化简单阀值自适应阀值 图像读写 图像的读取、显示与保存 import cv2 img cv2.imread(r"1.jpg")…

Unity休闲手机游戏开发课程

课程介绍 Unity休闲手机游戏开发课程将教您如何利用Unity游戏引擎创建令人愉快的休闲手机游戏。从基础的游戏开发知识到高级的游戏制作技巧&#xff0c;您将学习到创建各种类型的休闲游戏所需的关键技能和工具。无论您是初学者还是有一定经验的开发者&#xff0c;本课程都能帮助…

协程调度模块

什么是协程和协程调度&#xff1f; 基本概念 协程 协程是一种比线程更轻量级的并发编程结构&#xff0c;它允许在函数执行过程中暂停和恢复执行状态&#xff0c;从而实现非阻塞式编程。协程又被称为用户级线程&#xff0c;这是由于协程包括上下文切换在内的全部执行逻辑都是…

[linux]sed命令基础入门详解

sed是一种流编辑器&#xff0c;它一次处理一行内容。处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为“模式空间”&#xff0c;接着用sed命令处理缓冲区中的内容&#xff0c;处理完成后&#xff0c;把缓冲区的内容送往屏幕。接着处理下一行&#xff0c;这…

上位机GUI 第三弹

&#x1f60a; &#x1f60a; &#x1f60a; 从协议层面讲&#xff0c;地质单元相当重要&#xff0c;调试模式,我只能义命令发送的索引码作为,每个设备的区分方式,调试的情况&#xff0c;不在设备上设置任何东西&#xff0c;开机访问地址和端口就能用 因为懒&#xff0c;直接将…

股票分析-20240628

今日关注&#xff1a; 20240626 六日涨幅最大: ------1--------300386--------- 飞天诚信 五日涨幅最大: ------1--------300386--------- 飞天诚信 四日涨幅最大: ------1--------300386--------- 飞天诚信 三日涨幅最大: ------1--------300386--------- 飞天诚信 二日涨幅最…

Spring AI 1.0.0 新变化,从 0.8.1 如何升级

Spring AI 1.0.0-M1 版本已经发布&#xff0c;距离 1.0.0 正式版又更近了一步。同时这也意味着&#xff0c;Spring AI 1.0.0 的 API 已经基本确定&#xff0c;不会发生大的改动。这里介绍一下&#xff0c;相对于上一个发布版本 0.8.1&#xff0c;Spring AI 1.0.0 的一些重要的变…

MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入

文章目录 1、批量插入1.1、大批量插入数据1.2、启动Linux中的mysql服务1.3、客户端连接到mysql数据库&#xff0c;加上参数 --local-infile1.4、查询当前会话中 local_infile 系统变量的值。1.5、开启从本地文件加载数据到服务器的功能1.6、创建表 tb_user 结构1.7、上传文件到…

HarmonyOS APP应用开发项目- MCA助手(Day01持续更新中~)

简言&#xff1a; gitee地址&#xff1a;https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5 注&#xff1…

在TkinterGUI界面显示WIFI网络摄像头(ESP32s3)视频画面

本实验结合了之前写过的两篇文章Python调用摄像头&#xff0c;实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点&#xff08;AP&#xff09;工作模式–Arduino程序&#xff0c;当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…

前后端分离:四种开发模式与实践指南

前后端分离&#xff1a;四种开发模式与实践指南 什么是前后端分离 当业务变得越来越复杂或产品线越来越多时&#xff0c;原有的开发模式就无法满足业务需求了。 产品越来越多&#xff0c;展现层的变化越来越快、越来越多&#xff0c;此时应该进行前后端分离的分层抽象&#…

2024攻防演练:亚信安全推出MSS/SaaS短期定制服务

随着2024年攻防演练周期延长的消息不断传出&#xff0c;各参与方将面临前所未有的挑战。面对强大的攻击队伍和日益严格的监管压力&#xff0c;防守单位必须提前进行全面而周密的准备和部署。为应对这一形势&#xff0c;亚信安全特别推出了为期三个月的MSS/SaaS短期订阅方案。该…

【Android面试八股文】Android性能优化面试题:怎样检测函数执行是否卡顿?

文章目录 卡顿一、可重现的卡顿二、不可重现的卡顿第一种方案: 基于 Looper 的监控方法第二种方案:基于 Choreographer 的监控方法第三种方案:字节码插桩方式第四种方案: 使用 JVMTI 监听函数进入与退出总结相关大厂的方案ArgusAPMBlockCanaryQQ空间卡慢组件Matrix微信广研参…

Asp .Net Core 系列:基于 Castle DynamicProxy + Autofac 实践 AOP 以及实现事务、用户填充功能

文章目录 什么是 AOP &#xff1f;.Net Core 中 有哪些 AOP 框架&#xff1f;基于 Castle DynamicProxy 实现 AOPIOC中使用 Castle DynamicProxy实现事务管理实现用户自动填充 什么是 AOP &#xff1f; AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&a…

TCP、UDP详解

目录 1.区别 1.1 概括 1.2 详解 2.TCP 2.1 内容 2.2 可靠传输 2.2.1 确认应答 2.2.2 超时重传 2.2.3 连接管理 三次握手 四次挥手 2.2.4 滑动窗口 2.2.5 流量控制 2.2.6 拥塞控制 2.2.7 延时应答 2.2.8 捎带应答 2.2.9 面向字节流 2.2.10 异常情况的处理 1.…

IDEA 编译单个Java文件

文章目录 一、class文件的生成位置二、编译单个文件编译项目报错Error:java: 无效的源发行版: 8 一、class文件的生成位置 file->project structure->Modules 二、编译单个文件 选中文件&#xff0c;点击recompile 编译项目报错 Error:java: 无效的源发行版: 8 Fi…

ffmpeg使用png编码器把rgb24编码为png图像

version #define LIBAVCODEC_VERSION_MAJOR 60 #define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MICRO 100 note 不使用AVOutputFormat code void CFfmpegOps::EncodeRGB24ToPNG(const char *infile, const char *width_str, const char *height_str…

海外短剧CPS推广分佣系统平台讲解,他和短剧播放平台有啥区别?

首先来讲讲什么是海外短剧系统&#xff1f;什么是海外短剧cps系统&#xff1f;这俩有何区别&#xff1f; 海外短剧系统 顾名思义&#xff1a;就是做一套海外短剧系统&#xff0c;把剧放在自己的系统内&#xff0c;让用户来充值&#xff0c;充值的钱全部都是我自己的&#xff…

【区块链+基础设施】蜀信链 | FISCO BCOS应用案例

蜀信链是在四川省经济和信息化厅指导下&#xff0c;在四川省区块链行业协会组织下&#xff0c;由全省区块链相关从业与应用机构 共同参与建设和运营的区域性区块链基础设施&#xff0c;通过多方协同&#xff0c;共同打造合作共赢的区块链产业生态。 蜀信链区块链服务生态秉承“…