【C语言】memcpy,memmove,memcmp,memset函数详解

memcpy,memmove,memcmp,memset函数详解

  • memcpy函数
    • 一、 memcpy函数的定义:
    • 二、memcpy函数的功能:
    • 三、memcpy函数模拟
    • memcpy注意事项
  • memmove函数
    • 一、memmove函数简介
    • 二、memmove函数的模拟
      • 1.两种情况
      • 2模拟实现
  • memcmp函数
    • memecmp函数介绍
  • memset函数
    • memset函数介绍
    • memset功能
    • memset使用

memcpy函数

#include<string.h>

一、 memcpy函数的定义:

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

与strncmp区别是:参数方面:1.memcpy可以拷贝任意类型数据;2.num是字节数

二、memcpy函数的功能:

== 复制内存块==
将字节数的值从源指向的位置直接复制到目标指向的内存块。

源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本

该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数

为避免溢出,目标和源参数指向的数组大小应至少为字节数,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)

三、memcpy函数模拟

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{void* ret = dest;assert(dest);while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;}
int main()
{int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 40);int i = 0;for (i = 0; i < 20; i++){printf("%d\n", arr2[i]);}return 0;
}

在这里插入图片描述

memcpy注意事项

1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2.这个函数在遇到 '\0' 的时候并不会停下来
3.如果source和destination有任何的重叠,复制的结果都是未定义的。
原因也很简单:如下代码

int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };my_memcpy(arr1+2, arr1, 40);

给自己复制时,肯定时一位一位复制,把arr1[0]复制到arr+2(arr[2])位置时,arr1【2】的数值被覆盖为0,那么当我们继续复制时再取出arr[2]的值就是你之前已经复制过的了0,而不是原本的数值2,就不再是你想要复制的数据了。
4.

my_memcpy(arr2, arr1, 9);

这里我只复制前9个字节,可以发现打印出来了0,1,2.这是为什那么呢?
原因是:我们的vs编译器是小端存储(即,数据低位存到内存的高地址),
1,2,3在内存中的二进制存储为:
01 00 00 00|02 00 00 00|03 00 00 00 【一个00也就是一字节】
存储就9字节,正好把3 的关键位给复制进去了。
在这里插入图片描述

memmove函数

#include<string.h>

一、memmove函数简介

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

参数与memcpy一样
与memcpy函数区别是,它通常被用在源空间和目标空间出现重叠时

二、memmove函数的模拟

1.两种情况

memomove复制时,有两种情况
1.dest地址<src地址: 从前到后(左到右)
2.dest地址>src地址: 从后到前(右到左)
在这里插入图片描述

2模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{void* ret = dest;//保存初始位置地址assert(dest);//确保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);//先强制转换成char型,再加上num个字节。//就是指向src,dest的末尾元素}}return ret;}
int main()
{int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };my_memcpy(arr1+5, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d\n", arr1[i]);}return 0;
}

在这里插入图片描述

memcmp函数

#include<string.h>

memecmp函数介绍

定义

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

参数:ptr1和ptr2都指向内存块的指针。
num:要比较的字节数
返回值:
返回一个整数值,该值指示内存块内容之间的关系:

返回值表明
小于0ptr2大(指向的第一个不相等字符块)
0两个内存块的内容相等
大于0ptr1大

功能
将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的第一个字节数进行比较,
如果它们都匹配,则返回零,
如果不匹配,则返回一个不同于零的值,表示哪个值更大。 请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。

memset函数

#include<string.h>

memset函数介绍

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

参数: ptr;指向要填充的内存块的指针。
value:要设置的值。该值作为 int 传递,但该函数使用此值的无符号 char 转换填充内存块。
num:字节数
返回值:修改后的ptr

memset功能

memset使用

案例一:

#include<string.h>
int main()
{int arr[10] = { 0 };memset(arr, 1, 20);return 0;}

在这里插入图片描述
它是将每一个字节都赋值成1;
案例二:

#include<string.h>
int main()
{char arr[10] = { "hellloni"};memset(arr, 'x', 5);printf("%s", arr);return 0;}

在这里插入图片描述

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

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

相关文章

企业UPS不稳定?不用怕,这个技巧简单且容易!

随着技术的不断发展&#xff0c;食品行业中的UPS监控系统变得更加智能化和便捷&#xff0c;使食品生产过程更加安全可靠。 UPS监控在食品行业中扮演着关键的角色&#xff0c;确保电力供应的稳定性对于食品生产和储存过程至关重要。 客户案例 安徽某食品制造公司是一家大型食品…

BI-SQL丨XML

XML SQL Server中&#xff0c;存在一种特殊类型的数据&#xff0c;就是XML数据类型。 可能看到这里&#xff0c;小伙伴都会产生疑惑&#xff0c;XML不是Web语言么&#xff1f;为什么在SQL Server里面也会有XML数据类型&#xff1f; 这个就要从SQL Server的应用开始说起了&am…

如何在Windows 10中启用或禁用缩略图预览

文件资源管理器可以在 Windows 10 中显示文件和文件夹的缩略图或图标。 本教程将向你展示如何在文件资源管理器中为你的帐户、所有用户或Windows 10 中的特定用户启用或禁用缩略图预览。 缩略图预览仅在打开并且选择了中等图标、大图标或超大图标文件夹视图布局时显示。 如果缩…

PADS VX2.5学习

1、关于库的定义 PADS中的元件库分为四个文件 &#xff1a;*.ld9 *.ln9 *.pd9 *.pt9 即CAE、 LINES、PCB DECAL、PART TYPE。只有这四个文件都存在才是一个完整的库&#xff0c;才可以加载。 我们设计的电路所用到的元件必须在PADS logic和PADS layout中都存在&#xff0c;…

Python:基于matplotlib与mayavi的3D可视化

文章目录 一、3D可视化常用方法二、三维图像在numpy、cv2、以及tifffile.imread中通道的区别三、项目实战&#xff08;1&#xff09;基于matplotlib的3D可视化&#xff08;2&#xff09;基于mayavi的3D可视化&#xff08;2.1&#xff09;立方体&#xff08;2.2&#xff09;3D灰…

UI界面中的图标设计趋势与最佳实践

作为UI设计师&#xff0c;在日常的工作中&#xff0c;避免不了做图标规范。今天跟大家聊一聊&#xff0c;UI设计中的图标设计。 规范的重要性不用多说了&#xff0c;没有规范多个设计师绘制的图标会有很多差异&#xff0c;描边粗细、角度、圆角度等等。今天的文章和大家聊一下…

pythonocc进阶学习:faces的inner wire与outer wire

总目录 >> PythonOCC入门进阶到实战(目前已更新入门篇、基础篇和进阶篇) 我们在这篇文章中绘制了带有holes的面&#xff0c; 本篇是在读取到外部文件如brep&#xff0c;igs&#xff0c;stp后获取面的性质&#xff0c;寻找面中的wires的正向与逆向 只显示外wire from O…

STM32数字小键盘

基于STM32的数字小键盘 自己的键盘小键盘数字键坏了几个&#xff0c;准备自己用STM32做一个数字键盘。 硬件 找了一些资料&#xff0c;感谢知乎老哥。 原理图 采用的是主控是STM32F103RBT6&#xff0c;上拉1.5K接高速USB。按键采用的是矩阵按键。轴位可以自己选择。还接了一…

C++学习——类和对象(一)

C语言和C语言最大的区别在于在C当中引入了面向对象的编程思想&#xff0c;想要完全了解c当中的类和对象&#xff0c;就要从头开始一点一点的积累并学习。 一&#xff1a;什么是面向对象编程 我们之前学习的C语言属于面向过程的编程方法。举一个简单的例子来说&#xff1a;面向过…

Elasticsearch--客户端

Es客户端 语言无关 ​ java最常用的客户端是Java Client、Java Rest Client、Java Transport Client Java Client 从es7.17开始&#xff0c;官方推出Java Client&#xff0c;并且将Java Rest Client标为Deprecated&#xff08;过期&#xff09; 要求jdk至少要jdk8 具体用法…

LangChain大型语言模型(LLM)应用开发(六):Agents

LangChain是一个基于大语言模型&#xff08;如ChatGPT&#xff09;用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口&#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

Ajax详解

文章目录 1. 概述1.1 Ajax工作原理1.2 Ajax的作用1.3 同步异步 2. 原生Ajax3. Axios3.1 Axios的基本使用3.2 Axios快速入门3.3 请求方法的别名 1. 概述 Ajax 是 “Asynchronous JavaScript and XML”&#xff08;异步 JavaScript 和 XML&#xff09;的缩写。它是一种在无需重新…