C/C++字符函数和字符串函数详解————内存函数详解与模拟

个人主页:点我进入主页

专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

C语言刷题

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂。

目录

1.前言

2 .memcpy函数

3.memmove函数

4.memset函数

 5.memcmp函数


1.前言

           前面学习了关于长度受限制的字符串函数和长度不受限制的字符串函数,其中strcmp对应strncmp函数,strcpy函数对应strncpy函数,strcat函数对应strncat函数,今天我们主要了解的是四个内存函数他们分别是memcpy函数,memmove函数,memset函数,memcmp函数。其中memcpy函数和strcpy函数的功能类似,memcmp函数和strcmp函数类似,接下来就让我们感受一下这些函数的魅力吧。

2 .memcpy函数

        对于memcpy函数,有很多人都是第一次接触到,我们进入cplusplus网站cplusplus进行查看memcpy函数的参数。

        我们看到函数的参数是void * destination, const void * source, size_t num,对于参数我们需要知道这个函数是有什么功能,它主要就是对任何类型的数据进行拷贝,所以destination和source都是void*类型,因为void*类型可任盛放任何类型的指针,其中destination是指向目标的指针,source是指向来源的指针,num是想要拷贝几个字节,接下来进行代码演示,代码如下:

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

 我么运行代码,结果如下:

接下来进行函数的模拟

#include<stdio.h>
#include <string.h>
void* my_memcpy(void* str1, const void* str2, size_t num)
{char* p = (char*)str1;while (num--){*(char*)str1 = *(char*)str2;str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}return p;
}
int main()
{int arr1[10] = { 0 };int arr2[5] = { 2,3,4,5,6 };my_memcpy(arr1, arr2, 20);int i;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

        在这里我们需要进行强制转化,转化为char*类型然后一个字节一个字节进行修改,但是这个函数有一定的局限性,当它的目的指针和来源指针指向同一数据且有有重叠部分时函数会出现与预期不同的结果,我们可以简单画一下:

当我们想要把str1拷贝到str2上时当我们拷贝了前三个数据,str1和原来的str2重合时

         想要再次进行修改就会出现 重复拷贝,根据c语言的标准memcpy函数是对来自不同数据的进行拷贝,但是对于来自同一数组的需要用另外的一个函数,此函数就是memmove函数接下来我们介绍memmove函数。

3.memmove函数

        我们同样进入cplusplus网站查看memmove函数的参数,以及功能

           我们看到函数的参数是void * destination, const void * source, size_t num,memmove函数的功能和memcpy函数的功能类似 ,只是memmove是对于来自同一数组的数据进行拷贝,destination和source都是void*类型,因为void*类型可任盛放任何类型的指针,其中destination是指向目标的指针,source是指向来源的指针,num是想要拷贝几个字节,接下来进行代码演示,代码如下:

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

运行结果如下:

接下啦我们进行memmove函数的模拟实现,代码如下:

#include <stdio.h>
#include <string.h>
#include <assert.h>
void my_memmove(void* str1, const void* str2, size_t sz)
{assert(str1 && str2);if (str1 < str2){while (sz--){*(char*)str1 = *(char*)str2;str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}}else{while (sz--){*((char*)str1 + sz) = *((char*)str2 + sz);}}
}
int main()
{int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };my_memmove(arr+3, arr , 20);int i;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;}

 在这里我们需要看两种情况,第一种是str1在str2前面

这种情况我们只需从前往后进行赋值即可。对于第二种

 str1在str2的后面我们不能从前向后进行拷贝,否则就会出现重复赋值,出现错误,这时我们只需要从后往前进行赋值就可以解决。

4.memset函数

         我们进入cplusplus网站进行查阅

        memset函数是对数据进行初始化的函数,这个数据可以是任意类型,但是字符串比较适用,ptr是指向想要修改的位置,value是想要修改为什么值,num是修改几个字节,我们直接进入代码演示,代码如下:

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

运行结果如下:

接下来进入我们模拟实现,代码如下:

#include <stdio.h>
#include<string.h>
#include <assert.h>
void* my_memset(void* str, int vaul, size_t sz)
{assert(str);char* p = (char*)str;while (sz--){*(char*)str = vaul;str = (char*)str + 1;}return p;
}
int main()
{char arr[] = "abcdefg";my_memset(arr, 'x', 4);printf("%s", arr);return 0;
}

 5.memcmp函数

        我们进入cplusplus网站查看函数的参数 

        memcmp函数的功能就是比较数据的大小,其中num是需要比较的数据的字节数,功能和strncmp类似,我们直接上代码:

 

#include <stdio.h>
#include <string.h>
int main()
{int arr[5] = { 0,1,2,3,4 };int arr1[5] = { 0 };int ret = memcmp(arr, arr1, 5);printf("%d", ret);return 0;
}

我们可以理解为 

前4个字节相同,第五个字节str1大于str2故返回1。运行结果如下;

 

接下来进行memcmp函数的模拟实现,代码如下:

#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_memcmp(const void* str1, const void* str2, size_t sz)
{assert(str1 && str2);int i;for (i = 0; i < sz; i++){if (*(char*)str1 >*(char*)str2){return 1;}else if (*(char*)str1 < *(char*)str2){return -1;}str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}return 0;
}
int main()
{int arr[5] = { 0,1,2,3,4 };int arr1[5] = { 0 };int ret = my_memcmp(arr, arr1, 5);printf("%d", ret);return 0;
}

今天的内容就结束了,希望大家可以学到一些东西。

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

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

相关文章

以太网基础学习(一)——以太网概述

一、以太网概述 以太网(Ethernet)指的是由 Xerox公司创建并由Xerox、Intel和 DEC公司联合开发的基带局域网规范&#xff0c;通用的以太网标准于1980年9月30日出台&#xff0c;是当今现有局域网采用的最通用的通信协议标准&#xff08;是局域网的一种&#xff09;。 以太网是一种…

(C++版)ROS2 bind函数解读

在ros2的发布者节点里面有这么一句话&#xff1a;估计没有学过C的人不太理解&#xff0c;这里我就发发好心帮忙解读一下timer_ this->create_wall_timer(500ms, std::bind(&MinimalPublisher::timer_callback, this)); timer_ this->create_wall_timer(500ms, std…

自动驾驶中的感知模型:实现安全与智能驾驶的关键

自动驾驶中的感知模型&#xff1a;实现安全与智能驾驶的关键 文章目录 引言感知模型的作用感知模型的技术安全与挑战结论 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;全新的PnC培训…

嵌入式数据库sqlite3基本命令操作基础(05)

前言 数据在实际工作中应用非常广泛&#xff0c;数据库的产品也比较多&#xff0c;oracle、DB2、SQL2000、mySQL&#xff1b;基于嵌入式linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。 本文主要讲解数据库SQLite&#xff0c;通过这个开源的小型的嵌入式数据…

基于阶梯碳交易的含P2G-CCS耦合和燃气掺氢的虚拟电厂优化调度(matlab代码)

目录 1 主要内容 系统结构图 P2G-CCS 耦合模型 其他算例对比 2 部分代码 3 下载链接 1 主要内容 该程序复现《基于阶梯碳交易的含P2G-CCS耦合和燃气掺氢的虚拟电厂优化调度》模型&#xff0c;以碳交易和碳封存成本、燃煤机组启停和煤耗成本、弃风成本、购气成本之和为目标…

CANoe.Diva生成测试用例

Diva目录 一、CANoe.Diva打开CDD文件二、导入CDD文件三、ECU Information四、时间参数设置五、选择是否测试功能寻址六、勾选需要测试服务项七、生成测试用例 一、CANoe.Diva打开CDD文件 CANoe.Diva可以通过导入cdd或odx文件&#xff0c;自动生成全面的测试用例。再在CANoe中导…

简单查找重复文本文件

声明这是最初 我的提问给个文本分类清单input查找文件夹下 .py .txt .excel .word 一模一样的文本不是找文件名 找相同格式下的文件文本是否一样 文件单独复制到文件夹下两个文件全部复制到文件夹下 print 打印相同文本文件的名字 比如查找到了3.py与4.5.是.py文件中的文本文件…

5.Vectors Transformation Rules

在上节&#xff0c;有个问题&#xff1a;向量分量的转换方式 与 新旧基底的转换方式相反 用例子来感受一下&#xff0c; 空间中一向量V&#xff0c;即该空间的一个基底&#xff1a;e1、e2 v e1 e2 现把基底 e1 、 e2 放大两倍。变成 基向量放大了两倍&#xff0c; 但对于…

Javascript 事件的动态绑定

动态绑定事件&#xff0c;是指在代码执行过程中&#xff0c;通过Javascript代码来绑定事件。这种技术可以大大增强网页的交互性和用户体验。上一期介绍的是通过事件监听器 EventListener 去实现元素颜色的变化。这一期将通过动态绑定方法去实现&#xff0c;对象.事件 匿名函数…

【广州华锐互动】鱼类授精繁殖VR虚拟仿真实训系统

随着科技的不断发展&#xff0c;虚拟现实技术在各个领域的应用越来越广泛。在养殖业中&#xff0c;VR技术可以帮助养殖户进行家鱼授精实操演练&#xff0c;提高养殖效率和繁殖成功率。本文将介绍利用VR开展家鱼授精实操演练的方法和应用。 首先&#xff0c;我们需要了解家鱼授精…

mysql双主+双从集群连接模式

架构图&#xff1a; 详细内容参考&#xff1a; 结果展示&#xff1a; 178.119.30.14(主) 178.119.30.15(主) 178.119.30.16(从) 178.119.30.17(从)

【C++】基础入门

万字复习C基础入门语法&#xff0c;适合学过C的朋友用来复习查阅&#xff0c;可能不太适合0基础的朋友。 一.c初识 (1) 第一个c程序 最简单的格式&#xff1a; // 导入头文件 #include<iostream> // 简化对命名空间std下函数和对象的使用 using namespace std; // …

STM32驱动步进电机

前言 &#xff08;1&#xff09;本章介绍用stm32驱动42步进电机&#xff0c;将介绍需要准备的硬件器材、所需芯片资源以及怎么编程及源代码等等。 &#xff08;2&#xff09;实验效果&#xff1a;按下按键&#xff0c;步进电机顺时针或逆时针旋转90度。 &#xff08;3&#xff…

Multisim14.0仿真(二十七)基于UC3842的反激式开关电源的设计及仿真

一、UC3842简介&#xff1a; UC3842为固定频率电流模式PWM控制器。它们是专门为OFF−线和直流到直流转换器应用与最小的外部组件。内部实现的电路包括用于精确占空比控制的修剪振荡器、温度补偿参考、高增益误差放大器、电流传感比较器和理想适合于驱动功率MOSFET的高电流温度极…

openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译

文章目录 openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译89.1 查询编译&#xff1a;PREPARE语句89.2 运行命令89.3 轻量执行支持的查询89.4 轻量执行不支持的查询89.5 JIT存储过程89.6 MOT JIT诊断89.6.1 mot_jit_detai…

调度程序以及调度算法的评价指标

1.调度器/调度程序 调度程序决定调度算法&#xff0c;时间片大小 ②&#xff0c;③由调度程序引起&#xff0c;调度程序决定: 1.调度时机 创建新进程进程退出运行进程阻塞I/O中断发生&#xff08;可能唤醒某些阻塞进程)非抢占式调度策略&#xff0c;只有运行进程阻塞或退出…

强化学习环境 - robogym - 学习 - 1

强化学习环境 - robogym - 学习 - 1 项目地址 https://github.com/openai/robogym 为什么选择 robogym 自己的项目需要做一些机械臂 table-top 级的多任务操作 robogym 基于 mujoco 搭建&#xff0c;构建了一个仿真机械臂桌面物体操作&#xff08;pick-place、stack、rearr…

视频讲解|基于DistFlow潮流的配电网故障重构代码

目录 1 主要内容 2 视频链接 1 主要内容 该视频为基于DistFlow潮流的配电网故障重构代码讲解内容&#xff0c;对应的资源下载链接为基于DistFlow潮流的配电网故障重构(输入任意线路)&#xff0c;对该程序进行了详尽的讲解&#xff0c;基本做到句句分析和讲解&#xff08;讲解…

【题解 动态规划】 Colored Rectangles

题目描述&#xff1a; 分析&#xff1a; 乍一看我还以为是贪心&#xff01; 猫 想想感觉没问题 但是局部最优并不能保证全局最优 比如这组数据 19 19 19 19 20 20 20 20如果按照贪心的做法&#xff0c;答案是20*20*2 但是其实答案是19*20*4 因此这道题用贪心是不对的 于是我…

MATLAB 函数签名器

文章目录 MATLAB 函数签名器注释规范模板参数类型 kind数据格式 type选项的支持 使用可执行程序封装为m函数程序输出 编译待办事项推荐阅读附录 MATLAB 函数签名器 MATLAB 函数签名器 (FUNCSIGN) &#xff0c;在规范注释格式的基础上为函数文件或类文件自动生成函数签名&#…