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

每天学习一个字符串类函数之memmove函数

目录

前言:

一、头文件

二、memmove函数的作用

三、理解memmove函数的定义

1、返回类型

2、参数

四、使用memmove函数

案例1:

案例2:

五、解决数据拷贝之前被覆盖的方法

六、模拟实现memmove函数


前言:

上一篇博客,我们已经对memcpy函数进行了学习,也指明了memcpy函数不能支持源位置与目标位置相交的情况的拷贝,而在这种情况下,我们就要使用memmove函数了。所有今天我们来深入学习memmove函数。希望大家可以认真看完。

一、头文件

memmove函数的头文件是和memcpy函数的头文件相同的,都是<cstring>(string.h),同样同样memmove函数也是面向所有数据类型的,故也称其为内存函数

C语言

#include <string.h>

C++

#include <cstring>

二、memmove函数的作用

将 num 字节的数据从 source 指向的位置复制到 destination 指向的内存块。复制就像使用中间缓冲区一样进行,从而允许目标位置源位置重叠

三、理解memmove函数的定义

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

1、返回类型

在C语言标准库函数的定义中,memmove函数的返回类型为一个void*的指针,用于返回目标位置的地址由于void*指针的数据类型不固定性,可用于返回所有类型的数据

2、参数

在C语言标准库函数的定义中,memmove函数的参数有三个,第一个为void*destination(不固定类型的指针)用于接收目标位置的地址;第二个为const void*source(不固定类型的指针,前用const修饰,使程序不可通过该指针更改其指向的数据)用于接收源头位置的地址;第三个为size_t num用于表示要拷贝的数据的大小,单位是字节。

四、使用memmove函数

案例1:

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

函数代码运行前的监视结果: 

函数代码运行后的监视结果: 

案例2:

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

 函数代码执行前的监视结果:

函数代码执行后的监视结果:

* 这里强调一下,在案例2中若使用memcpy函数其执行结果将为:

为什么会出现这种情况?

因为从memcpy函数的实现代码可知,在memcpy函数中数组的元素3、4、5已经在对其进行拷贝之前,便已经被1、2覆盖掉了。 这便是memcpy函数定义的局限性。

五、解决数据拷贝之前被覆盖的方法

对会被覆盖的数据,先进行拷贝;对不会被覆盖的数据,后进行拷贝。而要完成这点,必须区分源头位置与目标位置的第一个元素的大小。

六、模拟实现memmove函数

#include <assert.h>void* my_memmove(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);if (dest < src){//从前往后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;//*((char*)dest)++ = *((char*)src)++;}}else{//从后往前while(num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}

解释:

当源位置地址大于目标位置地址,从前往后拷贝,否则从后往前拷贝。(要是不太理解,可以试着用画图来表示数据的拷贝过程)

每日一学,今天你又超过了百分之九十九的人。

如果本篇文章对你有帮助,请点个关注和赞吧!

如果对本篇文章有疑惑,欢迎在评论区讨论。

注:“每天学习一个字符串类函数”类型文章已整理为专栏,欢迎大家订阅。

http://www.lryc.cn/news/433163.html

相关文章:

  • 【机器人工具箱Robotics Toolbox开发笔记(十三)】三自由度机器人圆弧轨迹规划仿真实例
  • 软件工程-图书管理系统的概要设计
  • springboot 整合swagger
  • Flutter 进阶:绘制加载动画
  • 【深度学习】梯度下降法
  • 基于机器学习的电商优惠券核销预测
  • PHP-FPM 远程代码执行漏洞(CVE-2019-11043)复现
  • Rust : 从事量化的生态现状与前景
  • Java项目——苍穹外卖(一)
  • 20240908 每日AI必读资讯
  • HNU-2023电路与电子学-实验3
  • html基础语法 看这一篇就够了!
  • 【redis】redis的特性和主要应用场景
  • 部署后端WebSocket服务到AWS云服务器
  • 常见的集合
  • Swift知识点---RxSwift学习
  • 驾驭不断发展的人工智能世界
  • 冒泡排序——基于Java的实现
  • Mendix 创客访谈录|Mendix赋能汽车零部件行业:重塑架构,加速实践与数字化转型
  • 船舶机械设备5G智能工厂物联数字孪生平台,推进制造业数字化转型
  • 什么是jsonp请求
  • 【C++】STL容器详解【上】
  • 助贷行业的三大严峻挑战:贷款中介公司转型债务重组业务
  • 力扣第42题 接雨水
  • 轻松录制每一刻:探索2024年免费高清录屏应用
  • 【小沐学OpenGL】Ubuntu环境下glfw的安装和使用
  • [数据集][目标检测]汽油检泄漏检测数据集VOC+YOLO格式237张2类别
  • 图文解析保姆级教程:Postman专业接口测试工具的安装和基本使用
  • jenkins配置流水线
  • SQL 编程基础