贝蒂详解<string.h>(下)

✨✨欢迎大家来到贝蒂大讲堂✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:C语言学习
贝蒂的主页:Betty‘s blog
目录
1. 简介
2. memset()函数
2.1用法
2.2实例
2.3 实现memset()
3. memcmp()函数
3.1用法
3.2 实例
3.3 实现memcmp()
3.4strcmp,strncmp,memcmp之间的区别
4. memcpy()函数
4.1用法
4.2 实例
4.3实现memcpy()
4.4strcpy,strncpy,memcpy之间的区别
5. memmove()函数
5.1用法
5.2实例
5.3实现memmove()
1. 简介
除了字符函数和字符串函数,<string.h>中还有一类内存操作函数,如memset(),memcmp()等函数,他们在功能和某些字符串函数很像,但作用范围更广,除了作用于字符串外,还可以作用于int ,double等类型,但因为是以字节为单位改变,所以限制也很大。下面就让我们来看看吧~
2. memset()函数
2.1用法
1. 声明:void *memset(void *str, int c, size_t n)
- str -- 指向要填充的内存块。
- c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
- n -- 要被设置为该值的字符数。
2. 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
3. 返回值:该值返回一个指向存储区 str 的指针。
2.2实例
#include <stdio.h>
#include <string.h>
int main()
{char str[] = "hello world";memset(str, 'x', 6);//以字节为单位printf(str);return 0;
}
输出结果:xxxxxxworld
int main()
{int arr[4] = { 1,2,3,4 };memset(arr, 1, sizeof(arr));int i = 0;for (i = 0; i < 4; i++){printf("%d ", arr[i]);}return 0;
}
输出结果:16843009 16843009 16843009 16843009
贝蒂说:“虽然memset可以作用于int,float等类型,但是memset设置是以字节为单位,容易造成不符合我们预期的情况哦~”
2.3 实现memset()
思路:memset()函数和strcpy()函数有点像,都是替换,但是内在实现也有区别,因为memset()函数还可以用于不同数据类型,所以要先强制类型为(char*),再以字节为单位替换。
代码实现:
#include <string.h>
#include<assert.h>
void* my_memset(void*str, int c, size_t n)
{assert(str);//防止str为空指针char* tmp= (char*)str;//以字节为单位改变while (n--){*tmp = c;tmp++;}return str;
}
int main()
{char str[] = "hello world";my_memset(str, 'x', 6);//以字节为单位printf(str);return 0;
}
贝蒂说:“memset()函数常用于初始化哦~”
3. memcmp()函数
3.1用法
1. 声明:int memcmp(const void *str1, const void *str2, size_t n)
- str1 -- 指向内存块的指针。
- str2 -- 指向内存块的指针。
- n -- 要被比较的字节数。
2. 作用:把存储区 str1 和存储区 str2 的前 n 个字节进行比较。
3. 返回值:
- 如果返回值 < 0,则表示 str1 小于 str2。
- 如果返回值 > 0,则表示 str1 大于 str2。
- 如果返回值 = 0,则表示 str1 等于 str2。
3.2 实例
#include <stdio.h>
#include <string.h>
int main()
{char str1[] = "Hello, World!";char str2[] = "Hello, World!";char str3[] = "Hello, Betty!";// 比较相同的字符串if (memcmp(str1, str2, strlen(str1)) == 0){printf("str1 和 str2 相同。\n");}// 比较不同的字符串if (memcmp(str1, str3, strlen(str1)) != 0) {printf("str1 和 str3 不同。\n");}return 0;
}
输出:
str1 和 str2 相同。
str1 和 str3 不同。
3.3 实现memcmp()
思路:总体思路与strncmp差不多,只是也需要先强制类型转换
#include<stdio.h>
#include<assert.h>
int my_memcmp(const void* str1, const void* str2, size_t n)
{assert(str1 && str2);//char* p1 = (char*)str1;char* p2 = (char*)str2;while (n--&&(*p1==*p2)){if (*p1 == '\0'){return 0;}p1++;p2++;}return *p1 - *p2;
}
贝蒂说:“memcmp()函数也是以字节比较,所以限制也很大哦~”
3.4strcmp,strncmp,memcmp之间的区别
- memcmp是比较两个存储空间的前n个字节,即使字符串已经结束,仍然要比较剩余的空间,直到比较完n个字节。
- strcmp比较的是两个字符串,任一字符串结束,则比较结束。
- strncmp在strcmp的基础上增加比较个数,其结束条件包括任一字符串结束和比较完n个字节。
- strcmp比较的字符串,而memcmp比较的是内存块,strcmp需要时刻检查是否遇到了字符串结束的 /0 字符,而memcmp则完全不用担心这个问题,所以memcmp的效率要高于strcmp
4. memcpy()函数
4.1用法
1. 声明:void *memcpy(void *str1, const void *str2, size_t n)
- str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
- n -- 要被复制的字节数。
2. 作用:从存储区 str2 复制 n 个字节到存储区 str1。
3. 返回值:该函数返回一个指向目标存储区 str1 的指针。
4.2 实例
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };memcpy(arr2, arr1, 20);//前五个元素int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;
}
输出结果:1 2 3 4 5 0 0 0 0 0
4.3实现memcpy()
思路:自然也是和strcpy()差不多啦,嘻嘻
void* my_memcpy(void* dest, const void* src, size_t n)
{assert(dest && src);//防止空指针void* ret = dest;while (n--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
贝蒂说:“因为memcpy()函数实现机制,所以不能自己对自己进行拷贝哦~”
4.4strcpy,strncpy,memcpy之间的区别
- memcpy是从源存储空间拷贝到目标存储空间;而strcpy,strncpy是从源字符串拷贝到目标字符串。
- memcpy拷贝时是按照参数n作为结束标志的,即拷贝n个字节就结束;strncpy是以参数n或者‘\0’为结束标志;strcpy是判断‘\0’为结束标志。
5. memmove()函数
5.1用法
我们上面说过memcpy()无法对自己进行拷贝,那有没有能对自己拷贝的函数呢,当然有啦,就是我们的memmove()函数。
1. 声明:void *memmove(void *str1, const void *str2, size_t n)
- str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
- n -- 要被复制的字节数。
2. 作用:从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
3. 返回值:该函数返回一个指向目标存储区 str1 的指针。
5.2实例
#include <stdio.h>
#include <string.h>
int main()
{char str[] = "Hello, World!";printf("Original string: %s\n", str);// 将字符串前6个字符移动到字符串的末尾memmove(str, str + 7, 6);printf("Modified string: %s\n", str);return 0;
}
输出结果:
Original string: Hello, World!
Modified string: World! World!
5.3实现memmove()
分析如下:
情况1:
//假设需要拷贝以下场景
int arr1[9] = { 1,2,3,4,5,6,7,8,9 };
my_memmove(arr1, arr1 + 2, 12);
1. 假设我们从3的位置开始拷贝,3-1,4-2,5-3,拷贝成功。
2. 假设我们从5的位置开始拷贝,5-3,4-2,5-1,拷贝失败。
情况2:
//假设我们要拷贝的情况如下
int arr1[9] = { 1,2,3,4,5,6,7,8,9 };
my_memmove(arr1+4, arr1 + 2, 12);
1. 假设我们从3的位置开始拷贝,3-5,4-6,3-7,拷贝失败。
2. 如果我们从5的位置开始拷贝,:5-7,4-6,3-5,拷贝成功。
情况3:
int arr1[9] = { 1,2,3,4,5,6,7,8,9 };
my_memmove(arr1+1, arr1 + 5, 12);
my_memmove(arr1 + 5, arr1 + 1, 12);
1. 假设从6开始拷贝,6-2,7-3,8-4,拷贝成功。
2. 假设从8开始拷贝,8-4,7-3,6-2,拷贝成功。
1. 假设从2开始拷贝,2-6,3-7,4-9,拷贝成功。
2. 假设从4开始拷贝,4-8,3-7,2-6,拷贝成功。
总结:如果dest字符串在src的字符左边,则从首元素拷贝。如果dest字符串在src右边,则从末尾元素开始拷贝。
代码实现:
void* my_memmove(void* dest, const void* src, size_t n)
{assert(dest && src);//防止空指针void* ret = dest;if (dest <= src)//dest在src左侧{while (n--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else//dest在src的右侧{dest = (char*)dest + n - 1;//指向末尾src = (char*)src + n - 1;//指向末尾while (n--){*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}return ret;
}
🎈🎈完结撒花🎈🎈
🎈🎈完结撒花🎈🎈
相关文章:
贝蒂详解<string.h>(下)
✨✨欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C语言学习 贝蒂的主页:Betty‘s blog 目录 1. 简介 2. memset()函数 2.1用法 2.2实例 2.3 实现me…...
问题 F: 分巧克力
题目描述 儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有 N 块巧克力,其中第i 块HiWi 的方格组成的长方形。 为了公平起见,小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。 切出的巧克力需要满足&am…...
安装pillow可能遇到的问题
安装命令 pip install Pillow安装 Pillow 这个 Python 图像处理库时可能会遇到多种问题。以下一些常见的安装问题及其解决方法: 缺少依赖项: Pillow 安装可能需要一些基础库,如 libjpeg 和 zlib。如果在安装时提示缺少这些库,你需要先安装它…...
详解ajax、fetch、axios的区别
众所周知它们都用来发送请求,其实它们区别还蛮大的。这也是面试中的高频题,本文将详细进行讲解。 1. ajax 英译过来是Aysnchronous JavaScript And XML,直译是异步JS和XML(XML类似HTML,但是设计宗旨就为了传输数据&a…...
致远OA getAjaxDataServlet XXE漏洞复现(QVD-2023-30027)
0x01 产品简介 致远互联-OA 是数字化构建企业数字化协同运营中台,面向企业各种业务场景提供一站式大数据分析解决方案的协同办公软件。 0x02 漏洞概述 致远互联-OA getAjaxDataServlet 接口处存在XML实体注入漏洞,未经身份认证的攻击者可以利用此漏洞读取系统内部敏感文件…...
力扣最热一百题——只出现一次的数字
这个合集已经很久没有更新了,今天来更新更新~~~ 目录 力扣题号 题目 题目描述 示例 提示 题解 Java解法一:Map集合 Java解法二:位运算 C位运算代码 力扣题号 136. 只出现一次的数字 - 力扣(LeetCode) 下述题…...
UE5 UE4 修复GPU驱动程序崩溃
原贴链接:https://mp.weixin.qq.com/s/e5l9XtfwEFWgwhHi1b2idg UE5 UE4在处理含有大量图形的项目时,你有可能会遇到GPU崩溃 可以通过修改注册表,修复崩溃。 GPU崩溃情况概述 UE5 UE4在处理含有大量图形的项目时,你有可能会遇到G…...
SpiderFlow爬虫平台 前台RCE漏洞复现(CVE-2024-0195)
0x01 产品简介 SpiderFlow是新一代爬虫平台,以图形化方式定义爬虫流程,以流程图的方式定义爬虫,不写代码即可完成爬虫,是一个高度灵活可配置的爬虫平台。 0x02 漏洞概述 SpiderFlow爬虫平台src/main/java/org/spiderflow/controller/FunctionController.java文件的Functi…...
帆软report 设置条件属性,值为负数标为红色功能时,不生效
详细情况: 在设置负数为红色功能前,已经有一个条件属性,数据集获取的值为空或者为0时,转换成 - 符号。如下图: 具体表单显示效果如下: 条件属性2设置 原因 因为条件属性1设置的 - 符号没有设置颜色…...
QML实现的图片浏览器
很久之前实现了一个QWidget版本的图片浏览器:基于Qt5的图片浏览器QHImageViewer 今天用QML也实现一个,功能差不多: ●悬浮工具栏 ●支持图片缩放、旋转、还原、旋转、拖动。 ●拖动图片时,释放鼠标图片会惯性滑动。 ●支持左右翻页查看文件夹中的图片。 ●支持保存图片至本…...
【HTML】对字体的所有操作详解(经典)
目录 一、文字样式设置的基本标签二 、 设置文字的颜色三、设置文字的尺寸四、 设置文字的字体五、 使文字倾斜六、 使文字加粗七、处理网页中的特殊字符十、 如何更方便地忽略浏览器对部分HTML的解析十一、 其他文字修饰方法十二、为了让文字富有变化,或者为了着意…...
关于调查项目的讨论
怎么安排一个调查项目 要安排一个调查项目,你需要经过以下步骤: 1. 确定调查目的:明确你为什么要进行这个调查,你想了解什么问题或获得什么信息。 2. 制定研究问题:根据调查目的,确定需要回答的具体问题…...
Matlab三维绘图
绘制三维图plot3 t0:pi/50:10*pi; xsin(t); ycos(t); zt; plot3(x,y,z); 产生栅格数据点meshgrid 这个接口在绘制三维图像里面相当重要,很多时候要将向量变成矩阵才能绘制三维图。 x0:0.5:5; y0:1:10; [X,Y]meshgrid(x,y); plot(X,Y,o); x和y是向量,…...
一体式气象站的优点是什么?带大家了解一下
一体式气象站是一款高度集成、低功耗、可快速安装、便于野外监测使用的高精度自动气象观测设备。 一体式气象站的优点主要体现在以下几个方面: 集成度高:一体式气象站集成了多种气象传感器、数据处理单元、显示单元和通讯模块等,可以同时监…...
第八讲_css定位
css定位 1. css定位介绍2. 静态定位(static)3. 相对定位(relative)4. 绝对定位(absolute)5. 固定定位(fixed)6. 粘性定位(sticky) 1. css定位介绍 在 css 中…...
找出字符串中第一个匹配项的下标(Leetcode28)
例题: 分析: 题目的意思就是: 先给出一个字符串pattern,要拿着pattern字符串和原始字符串(origin)比对,若在origin中找到了pattern字符串,则返回pattern字符串在原始字符串origin中的…...
【分布式微服务专题】从单体到分布式(四、SpringCloud整合Sentinel)
目录 前言阅读对象阅读导航前置知识一、什么是服务雪崩1.1 基本介绍1.2 解决方案 二、什么是Sentinel2.1 基本介绍2.2 设计目的2.3 基本概念 三、Sentinel 功能和设计理念3.1 流量控制3.2 熔断降级3.3 系统负载保护 四、Sentinel 是如何工作的 笔记正文一、简单整合Sentinel1.1…...
RHCE9学习指南 第19章 网络时间服务器
19.1 时间同步的必要性 对于一些服务来说对时间要求非常严格,例如,图19-1所示由三台服务器搭建的ceph集群。 图19-1 三台机器搭建的集群对时间要求比较高 这三台服务器的时间必须要保持一样,如果不一样,就会显示报警信息。那么…...
大模型 RAG 问答技术架构及核心模块盘点:从 Embedding、prompt-embedding 到 Reranker
对于RAG而言,2023年已经出现了很多工作,草台班子有了一堆,架构也初步走通,2024年应该会围绕搜索增强做更多的优化工作。 因此我们今天来系统回顾下RAG中的模块,包括一些架构,文本嵌入embedding等ÿ…...
基于Selenium+Python的web自动化测试框架
一、什么是Selenium? Selenium是一个基于浏览器的自动化测试工具,它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分:Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE:Firefo…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
