【C语言 模拟实现memcpy函数、memcpy函数】
C语言程序设计笔记---027
- C语言之模拟实现memcpy函数、memcpy函数
- 1、介绍memcpy函数
- 1.1、模拟实现memcpy函数
- 2、介绍memmove函数
- 2.1、模拟实现memmove函数
- 3、结语
C语言之模拟实现memcpy函数、memcpy函数
前言:
通过C语言内存函数的知识,这篇将对memcpy函数、memcpy函数进行深入学习底层原理的知识,并模拟实现对应功能。
/知识点汇总/
内存相关的函数
1.memcpy –strcpy
2.memmove
3.memset
4.memcmp — strcmp
1、介绍memcpy函数
函数原型:void *memcpy( void dest, const void src, size_t count ); ---- void 说明,兼容任意类型
函数功能:将源头内存的数据,拷贝到目标内存中,返回值类型为void
头文件:<string.h>
使用注意事项:
(1)、与strncpy不同的是,参数num和count。一个是指需要拷贝的元素个数,一个是指需要拷贝的元素字节大小
(2)、相比strcpy函数仅仅是操作字符串进行拷贝,而memcpy内存中的数据,不仅仅是操作字符。
示例代码如下:
#include <stdio.h>
#include <string.h>
int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };memcpy(arr1, arr2, 20);//20 == 4*5int sz = sizeof(arr1) / sizeof(arr1[0]);for (int i = 0; i < sz; i++){printf("%d ", arr1[i]);}return 0;
}
1.1、模拟实现memcpy函数
#include <stdio.h>
#include <string.h>
#include <assert.h>
//注意:void* 不能进行运算操作
//另外,这里必须使用(char*)进行操作,因为如果是其它类型就会造成数据上的丢失等问题 --- 联想类似于qsort一个个字节进行操作
void* my_memcpy(void* dest, const void* src, size_t sz)//sz拷贝多少个字节
{assert(dest && src);while (sz--)//以一个字节一个字节的拷贝{*(char*)dest = *(char*)src;dest = (char*)dest + 1;//注意:强制类型转换具备临时属性,所以需要(char*)dest+1来赋值保存数据,不能用dest++src = (char*)src + 1;}
}
int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };my_memcpy(arr1, arr2, 20);//20 == 4*5for (int i = 0; i < 5; i++){printf("%d ", arr1[i]);}return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.sz–因为memcpy是以字节为单位进行的拷贝,所以为了兼容多种类型,就需要强转为char*类型之后再操作。(可回顾前面篇章,模拟qsort函数的内容)
扩展:memcpy对同一内存空间的操作问题
以我们自己模拟的memcpy函数,导致问题的原因:
调试可知,它是以一个一个字节进行的拷贝,
所以比如:对0x11223344进行拷贝为01操作是0x01010101达不到我们的预期,
而我们预期应该是0x11223301,然后下一个元素比如0x11224401
但是,库函数的memcpy在当前的编译器条件下,弥补了这样的错误问题。说明库函数作者完善的很全面,同时更复杂。
2、介绍memmove函数
函数原型:void *memmove( void dest, const void src, size_t count );
函数功能:将源头内存的数据。拷贝到目标内存中,且与memcpy相比可以拷贝同一空间的数据,返回值类型为void
头文件:<string.h>
使用注意事项:
(1)、memcpy只能对不同空间内存之间的数据进行操作
即:不重叠内存的拷贝,可以使用memcpy,而重叠的内存空间则需要用memmove函数
示例代码如下:
#include <stdio.h>
#include <string.h>
int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };memmove(arr1, arr2, 20);//20 == 4*5int sz = sizeof(arr1) / sizeof(arr1[0]);for (int i = 0; i < sz; i++){printf("%d ", arr1[i]);}return 0;
}
2.1、模拟实现memmove函数
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t sz)
{assert(dest && src);char* ret = (char*)dest;if (dest < src)//从前向后拷贝{while (sz--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//从后向前拷贝{while (sz--)//sz-- 先用再减,即先判断sz=20为真,用完后减1进入循环,此时sz=19{*((char*)dest + sz) = *((char*)src + sz);}}return ret;
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 20);//20 == 4*5int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.dest < src表示目标空间地址在源地址前面,适合从源地址的高位开始拷贝,即从前向后拷贝
值得注意的是,因为memmove是以字节为单位进行的拷贝,所以为了兼容多种类型,就需要强转为char*类型之后再操作。(可回顾前面篇章,模拟qsort函数的内容)
4.相反否则就是,目标空间地址在源地址后面,适合从源地址的低位开始拷贝,即从后向前拷贝
值得注意的是,对于源地址的最后一个数据地址是指针+sz从后向前偏移。
小结:
1.memcpy只能对不同空间内存之间的数据进行操作
即:不重叠内存的拷贝,可以使用memcpy,而重叠的内存空间则需要用memmove函数
2.库函数可以实现,标准规定:
以memcpy来实现不重叠的内存的拷贝,且要求能达到60即可
以memmove来实现重叠内存的拷贝
3.但是,发现当前的编译环境下,memcpy同样能实现重叠内存的拷贝,远远满足60分的要求,100分,所以于编译环境相关,建议相应的功能交给适合的函数实现即可
3、结语
学习函数的最实用的方式就是用自己的逻辑简单实现一些类似的功能
半亩方糖一鉴开,天光云影共徘徊。
问渠哪得清如许?为有源头活水来。–朱熹(观书有感)
相关文章:
【C语言 模拟实现memcpy函数、memcpy函数】
C语言程序设计笔记---027 C语言之模拟实现memcpy函数、memcpy函数1、介绍memcpy函数1.1、模拟实现memcpy函数 2、介绍memmove函数2.1、模拟实现memmove函数 3、结语 C语言之模拟实现memcpy函数、memcpy函数 前言: 通过C语言内存函数的知识,这篇将对memc…...
opencv视频文件的读取,处理与保存
文章目录 opencv视频文件的读取,处理与保存一、视频文件的读取:1、cv::VideoCapture是OpenCV库中用于处理视频输入的类,它提供了一种简单的方法来从摄像头,视频文件、或图像序列中读取帧;(1)打开…...
java - 七大比较排序 - 详解
前言 本篇介绍了七大比较排序,直接插入排序,希尔排序,冒泡排序,堆排序,选择排序,快速排序,归并排序,一些简单思想代码实现,如有错误,请在评论区指正…...
项目集成七牛云存储sdk
以PHP为例 第一步:下载sdk PHP SDK_SDK 下载_对象存储 - 七牛开发者中心 sdk下载成功之后,将sdk放入项目中,目录选择以自己项目实际情况而定。 注意:在examples目录中有各种上传文件的参考示例,这里我们主要参考的是…...
docker-compose一键启动neo4j
下载镜像 docker pull neo4j:3.5.22-community 编写配置文件 参考文档 编写docker-compose.yml文件 version: "3"services:neo4j:image: neo4j:3.5.22-communitycontainer_name: neo4j restart: alwaysports:- 7474:7474- 7687:7687environment:- NEO4J_AUTH:ne…...
深入剖析@ConfigurationProperties注解
当我们构建Spring Boot应用程序时,配置属性通常是不可或缺的一部分。Spring Boot提供了多种方式来管理这些属性,其中之一是使用ConfigurationProperties注解。这篇博客将详细解释ConfigurationProperties注解以及如何使用它来管理和映射配置属性。 什么…...
北京开发APP需要多少钱
北京开发一个移动应用(APP)的费用因多种因素而异,包括项目的规模、复杂性、所需功能、设计要求、技术选择、开发团队的经验和地理位置等。一般来说,北京的APP开发费用通常较高,因为这是中国的主要技术和创新中心之一&a…...
self-attention、transformer、bert理解
参考李宏毅老师的视频 https://www.bilibili.com/video/BV1LP411b7zS?p2&spm_id_frompageDriver&vd_sourcec67a2725ac3ca01c38eb3916d221e708 一个输入,一个输出,未考虑输入之间的关系!!! self-attention…...
junit @ExcludePackages排除多个包
在JUnit中,可以使用ExcludePackages注解来排除多个包。该注解可以用在测试类或测试方法上。 如果要排除多个包,可以在ExcludePackages注解的value属性中使用数组来指定要排除的包名。例如,要排除包com.example.package1和com.example.packag…...
Explain执行计划字段解释说明---select_type、table、patitions字段说明
1、select_type的类型有哪些 2、select_type的查询类型说明 1、SIMPLE 简单的 select 查询,查询中不包含子查询或者UNION 2、PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为Primary 3、DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生)&…...
云原生微服务 第六章 Spring Cloud Netflix Eureka集成远程调用、负载均衡组件OpenFeign
系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…...
四、2023.9.30.C++面向对象end.4
文章目录 49、 简述一下什么是常函数,有什么作用?50、 说说什么是虚继承,解决什么问题,如何实现?51、简述一下虚函数和纯虚函数,以及实现原理?52、说说纯虚函数能实例化吗,为什么&am…...
【Java】包
package 包(package):其实就是文件夹。 作用:对类进行分类管理。 包的定义格式 格式:package 包名(多级包用 . 分开) 范例:package com.mayikt.demo01 带包的Java类编译和执行 1. 手动建包 安装…...
Hive【Hive(二)DML】
启动 hive 命令行: hive DML 数据操作 1、数据导入 1.1、向表中装载数据(load) 语法: hive> load data [local] inpath 数据的path [overwrite] into table student [partition (partcol1val1,…)];(1&#x…...
HTTP的请求方法,空行,body,介绍请求报头的内部以及粘包问题
目录 一、GET与POST简介 二、空行和body 三、初识请求报头以及粘包问题 四、认识请求报头剩余部分 一、GET与POST简介 GET https://www.sogou.com/HTTP/1.1 请求报文中的方法,是最常规的方法(获取资源) POST:传输实体主体的方法…...
win10 ip设置
百度安全验证...
alibaba dragonwell jdk
阿里巴巴Dragonwell8快速指南 dragonwell-project/dragonwell8 Wiki GitHub 阿里巴巴Dragonwell8用户指南 dragonwell-project/dragonwell8 Wiki GitHub 阿里巴巴Dragonwell8常见问题 dragonwell-project/dragonwell8 Wiki GitHub...
jvm内存分配与回收策略
自动内存管理 解决两个问题 自动给对象分配内存 对象一般堆上分配(而实际上也有可能经过即时编译后被拆散为标量类型并间接地在栈上分配) 新生对象通常会分配在新生代,少数情况下(例如对象大小超过一定阈值)也可能…...
【Vue2和Vue3的双向绑定区别】
Vue2和Vue3的双向绑定区别 vue2 双向绑定原理vue3 双向绑定原理Vue2和Vue3的双向绑定存在以下区别: vue2 双向绑定原理 Vue2 双向绑定的实现主要依赖于 Object.defineProperty() 方法和观察者模式,其中 Object.defineProperty() 方法用于定义属性的 get…...
【再识C进阶3(下)】详细地认识字符分类函数,字符转换函数和内存函数
前言 💓作者简介: 加油,旭杏,目前大二,正在学习C,数据结构等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
