C语言_字符串+内存函数的介绍

字符函数和字符串函数

本章重点

重点介绍处理字符和字符串的库函数的使用和注意事项

  • 求字符串长度
    • strlen
  • 长度不受限制的字符串函数
    • strcpy
    • strcat
    • strcmp
  • 字符串查找
    • strstr
    • strtok
  • 错误信息报告
    • strerror
  • 字符操作
  • 内存操作函数
    • memcpy
    • memmove
    • memset
    • memcmp

1. 字符函数介绍

1.1 strlen

size_t strlen ( const char * str );

  • 字符串已经\0作为结束标志,strlen函数返回的是在字符串中\0前面出现的字符个数(不包含\0)。
  • 参数指向的字符串必须要以\0结束。
  • 注意函数的返回值为size_t,是无符号的(易错)
  • 学会strlen函数的模拟实现

在我们模拟实现strlen之前,先要会用strlen函数,以下案例是正确的嘛?

在这里插入图片描述

输出结果:

在这里插入图片描述

很多人就好奇为什么3 - 6 > 0。
因为strlen返回类型是size_t,是以无符号类型进行返回的,那么无符号 - 无符号 得到的答案肯定也就是无符号类型了。
值确实是-3,但是在内存中存储,因为是负数,需要转换为补码,补码可是一个很大的数字,然后又要以无符号类型进行输出,得到的答案就是>0

模拟实现strlen函数

在这里插入图片描述

1.2 strcpy

char* strcpy(char * destination, const char * source );

  • 源字符串必须以\0结束。
  • 会将源字符串中的\0拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。
  • 学会模拟实现。

使用库函数strcpy看看效果

在这里插入图片描述

模拟实现strcpy

在这里插入图片描述

1.3 strcat

char * strcat ( char * destination, const char * source );

  • 源字符串必须以\0结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

先来看看库函数strcat的使用
在这里插入图片描述

模拟实现库函数strcat

在这里插入图片描述

那么自己追加自己是否成立呢?

在这里插入图片描述

画图详解

在这里插入图片描述

1.4 strcmp

int strcmp ( const char * str1, const char * str2 );

  • 标准规定:
    • 第一个字符串大于第二个字符串,则返回大于0的数字
    • 第一个字符串等于第二个字符串,则返回0
    • 第一个字符串小于第二个字符串,则返回小于0的数字
  • 那么如何判断两个字符串?

先来看看库函数xtrcmp的使用

在这里插入图片描述

模拟实现库函数strcmp

在这里插入图片描述

1.5 strncpy

char * strncpy ( char * destination, const char * source, size_t num );

  • 拷贝num个字符从源字符串到目标空间。

  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

在这里插入图片描述

1.6 strncat

char * strncat ( char * destination, const char * source, size_t num );

  • 将源的前Num个字符追加到目标,外加一个终止NUL字符。
  • 如果SOURCE中的C字符串的长度小于Num,则只包含到终止NUL的内容,字符被复制。

在这里插入图片描述

1.7 strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

在这里插入图片描述

1.8 strstr

char * strstr ( const char *, const char * );

  • 返回指向str1中str2的第一个匹配项的指针,如果str2不是str1的一部分,则返回空指针。

在这里插入图片描述

模拟实现strstr库函数

在这里插入图片描述
输出结果:

在这里插入图片描述

1.9 strtok

char * strtok ( char * str, const char * sep );

  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用\0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回NULL 指针。

在这里插入图片描述

1.10 strerror

char * strerror ( int errnum );

  • 返回错误码,所对应的错误信息。

在这里插入图片描述

2. 内存函数

2.1 memcpy

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

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到\0的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。

在这里插入图片描述

模拟实现库函数memcpy

在这里插入图片描述

输出结果:

在这里插入图片描述

当我们想要自己拷贝自己的时候,从3的位置开始拷贝1开始的位置,拷贝20个字节,能实现1 2 1 2 3 4 5 8 9 10嘛?

在这里插入图片描述

总结:memcpy是用来处理不重叠的内存空间拷贝。
这里就延续出了memmove库函数的用法

2.2 memmove

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

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

成功使用库函数memmove实现重叠的内存空间拷贝

在这里插入图片描述

当我们想要模拟实现库函数memmove的时候会遇到以下几个问题

在这里插入图片描述

下面来实现代码:

在这里插入图片描述

输出两种类型结果:

第一种:dest < src

在这里插入图片描述

第二种: dest> src

在这里插入图片描述

2.3 memcmp

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

  • 比较从ptr1和ptr2指针开始的num个字节

在这里插入图片描述

在内存中可以观察到直到第九个字节比对都是一模一样的,所以ret接收了一个0。

2.4 memset

void *memset(void *str, int c, size_t n);

  • str – 指向要填充的内存区域的指针。
  • c – 要设置的值,通常是一个无符号字符。
  • n – 要被设置为该值的字节数。

在这里插入图片描述

总结:本章主要讲解了一些字符串函数以及内存函数的使用方法,极个别的实现了手搓库函数,让我们了解到了函数底层的运行原理。

本章完~

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

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

相关文章

【含文档】基于Springboot+Vue的白云山景点门票销售管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

「从零开始的 Vue 3 系列」:第十三章——架构一个Vue项目(简单版)

前言 本系列将从零开始&#xff0c;系统性地介绍 Vue 3 的常用 API&#xff0c;逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示&#xff0c;帮助大家掌握 Vue 3 的基础与进阶知识&#xff0c;最终具备独立搭建完整 Vue 3 项目的能力。 从零开始使用 Vite 和 Vue 3…

Mysql(七) --- 索引

文章目录 前言1.简介1.1.索引是什么&#xff1f;1.2.为什么使用索引? 2.索引应该使用什么数据结构&#xff1f;2.1.Hash2.2.二叉搜索树2.3.N叉树2.4.B树2.4.1. 简介2.4.2. B树的特点2.4.3. B树和B树的对比 3.Mysql中的页3.1.为什么要使用页3.2.页文件头和页文件尾3.3.页主体3.…

设置故障恢复机制

在分布式系统和实时数据处理场景中&#xff0c;设置故障恢复机制是确保系统稳定性和数据一致性的关键。 对于使用Flink CDC实时同步MySQL数据的场景&#xff0c;是一些设置故障恢复机制的建议&#xff1a; 1. Flink Checkpointing&#xff08;检查点&#xff09; 启用Checkp…

小新学习Docker之Docker--harbor私有仓库部署与管理

目录 一、Harbor简介 1.1、Harbor概述 1.2、Harbor的特性 1.3、Harbor的构成 二、Harbor构建Docker私有仓库 2.1、部署Harbor服务 2.2、启动 Harbor 2.3、查看 Harbor 启动镜像&#xff0c;检查harbor是否安装成功 2.4、创建一个新项目 2.5、非本地主机进行下载镜像 …

STM32学习--4-1 OLED显示屏

接线图 OLED.c #include "stm32f10x.h" #include "OLED_Font.h"/*引脚配置*/ #define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x)) #define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))/*引脚初始化*/ void …

软件安全漏洞挖掘: 基础知识和概念

1. 软件漏洞原理和漏洞检测方法 文章目录 1. 软件漏洞原理和漏洞检测方法1. 漏洞披露2. 漏洞定义和分类1. 漏洞的定义2. 漏洞的分类3. 漏洞检测方法常见方法1. 程序切片2. 形式化方法1. 符号执行3. 污点分析污点分析步骤/流程*污点分析流程的详细介绍1. 识别source和sink点2. 污…

Pycharm通过ssh远程docker容器搭建开发环境

本地pycharm通过ssh方式远程连接服务器&#xff08;Ubuntu&#xff09;上的docker容器&#xff0c;搭建开发环境。实现功能&#xff1a;将环境依赖打包成docker镜像&#xff0c;并在远程服务器中启动容器&#xff08;启动时做好端口映射和文件夹挂载&#xff09;&#xff0c;通…

使用vscode导入库失败解决方法

导入库失败原因 在使用vscode写python代码时&#xff0c;有时会遇见导入库失败的情况&#xff0c;如下图&#xff1a;无法解析导入“xxxxx” 或者 运行时报错&#xff1a;ModuleNotFoundError: No module named xxxxx。 原因可能有&#xff1a; 根本没有下载库&#xff1b…

Luminar Neo v1.21.0.13934 图像编辑软件绿色便携版

skylum Luminar Neo 是一款由未来 AI 技术驱动的创意图像编辑器。并且支持微软Windows及苹果Mac OX系统&#xff0c;它使创作者能够将他们最大胆的想法变为现实并乐在其中。借助 Luminar Neo 领先的 AI 技术和灵活的工作流程&#xff0c;完成创意任务并获得专业品质的编辑结果。…

java基础(5)继承与多态

目录 ​编辑 1.前言 2.正文 2.1继承 2.1.1继承概念 2.1.2继承语法 2.1.3子类访问父类 2.1.4super关键字 2.2多态 2.2.1多态概念 2.2.2多态条件 2.2.3重写 2.2.4向上转型与向下转型 2.2.5为什么要使用多态 3.小结 1.前言 哈喽大家好啊&#xff0c;今天继续来为大…

【微信小程序_12_全局配置之 tabBar】

摘要:本文介绍了微信小程序中的 tabBar,包括其定义、组成部分、节点配置项和每个 tab 项的配置选项。还通过案例详细说明了配置 tabBar 的步骤,如拷贝图标资源、新建 tab 页面和配置 tabBar 选项等。tabBar 可实现多页面快速切换,合理配置能提升用户体验。 微信小程序_12_全…

刷爆Leetcode Day2

leetcode 6. 和为s的两个数字7.三数之和8. 四数之和9. 长度最小的子数组10. 无重复字符的最长子串 6. 和为s的两个数字 题目 class Solution { public:vector<int> twoSum(vector<int>& price, int target) {//排序双指针sort(price.begin(),price.end());in…

C++ operator new和operator delete的深入讲解

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 前言 关于operator new和operator delete我们需要明确一个概念&#xff0c;这两个都是…

15.5 JDBC数据库编程5——DAO

目录 15.1.1 引言 实体类Product.java 异常类DaoException.java Dao.java ProductDao.java ProductDaoImpl.java ProductDaoTest.java 15.1.1 引言 Java是面向对象编程语言&#xff0c;主要操作对象&#xff0c;而关系数据库的数据并不是对象&#xff0c;Java程序插入…

linux线程 | 线程的控制(下)

前言&#xff1a; 本节内容是线程的控制部分的第二个小节。 主要是列出我们的线程控制部分的几个细节性问题以及我们的线程分离。这些都是需要大量的代码去进行实验的。所以&#xff0c; 准备好接受新知识的友友们请耐心观看。 现在开始我们的学习吧。 ps:本节内容适合了解线程…

对MVC详细解读

一、MVC模式的详细组成部分 1. 模型&#xff08;Model&#xff09; 数据结构&#xff1a; 模型通常使用类或结构来定义应用程序的数据结构。例如&#xff0c;在Ruby on Rails中&#xff0c;模型通常与数据库表相对应&#xff0c;使用Active Record模式。 数据访问层&#xff1…

动态内存管理(C语言 VS C++)

目录 一.动态内存管理的前置知识 1.栈区 a.栈区的特点 b.注意事项 2.堆区 a.堆区的特点 b.注意事项 3.全局/静态区 a.作用域和生命周期 b.注意事项 4.常量区 二.C语言动态内存管理 1.malloc 函数 a.接口简介与使用实例 b.注意要点 2.calloc 函数&#xff1a; 3.…

Flink Web UI 是使用和调试保姆级教程(持续更新)

Flink Web UI 是调试和监控 Flink 应用程序的重要工具&#xff0c;通过它&#xff0c;你可以实时查看正在运行的 Flink 任务的详细信息&#xff0c;包括作业的状态、性能指标、各子任务的运行情况、故障恢复情况等。Flink Web UI 的这些功能为开发者和运维人员提供了调试和优化…

化学元素分子量、氧化物系数计算python类

在网上找到的分子量计算类&#xff0c;做了少量修改,有原子量、分子量、氧化物系数的计算。 import re wt_dict{ #该原子量数据从CRC手册第95版提取。"H": 1.008,"He": 4.002602,"Li": 6.94,"Be": 9.0121831,"B": 10.…