字符函数和字符串函数(C语言进阶)

字符函数和字符串函数

  • 一.求字符串长度
    • 1.strlen
  • 二.长度不受限制的字符串函数介绍
    • 1.strcpy
    • 2.strcat
    • 3.strcmp

前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。
字符串常量适用于那些对它不做修改的字符串函数

一.求字符串长度

1.strlen

size_t strlen ( const char * str );

在这里插入图片描述

代码演示:
#include <string.h>int main()
{const char* str = "abcdef";//"abcdef"==strsize_t len1 = strlen("abcdef");size_t len2 = strlen(str);printf("%d\n", len1);printf("%d\n", len2);return 0;
}

运行结果:
在这里插入图片描述

1.字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
在这里插入图片描述

2.参数指向的字符串必须要以 ‘\0’ 结束。
数组中不含‘\0’,所以计算strlen为随机值
在这里插入图片描述

3.注意函数的返回值为size_t,是无符号的( 易错 )
让我们来证明下strlen的类型为size_t(无符号整型),看以下代码:

int main()
{//两个无符号数相减得到的还是无符号数// 3 - 6 = -3// -3//10000000000000000000000000000011 原码//11111111111111111111111111111100 反码//11111111111111111111111111111101 补码if (strlen("abc") - strlen("abcdef") > 0)printf(">=\n");elseprintf("<\n");return 0;
}

让我们看看运行结果:
在这里插入图片描述

对运行结果进行分析
在这里插入图片描述

若想比较两个strlen算出的实际大小,将strlen强转成int类型如下

代码演示:
#include<stdio.h>
#include <string.h>
int main()
{if ((int)strlen("abc") - (int)strlen("abcdef") > 0)printf(">=\n");elseprintf("<\n");return 0;
}

运行结果:
在这里插入图片描述

模拟实现strlen

1. 计数器
#include<stdio.h>
int my_strlen(const char* str)
{int count = 0;while (*str != '\0'){str++;count++;}return count;
}
int main()
{int ret = 0;char arr[] = "abcdef";ret = my_strlen(arr);printf("%d\n", ret);
}

运行结果:
在这里插入图片描述

2. 指针-指针
#include<stdio.h>
int my_strlen(const char* str)
{const char* p = str;while (*str != '\0'){str++;}return str - p;
}
int main()
{int ret = 0;char arr[] = "abcdef";ret = my_strlen(arr);printf("%d\n", ret);
}

运行结果:
在这里插入图片描述

3. 递归
#include<stdio.h>
int my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
int main()
{int ret = 0;char arr[] = "abcdef";ret = my_strlen(arr);printf("%d\n", ret);
}

运行结果:
在这里插入图片描述

二.长度不受限制的字符串函数介绍

1.strcpy

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

在这里插入图片描述

代码案例:
#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = { 0 };char arr2[] = "Hello";strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}

运行结果:
在这里插入图片描述

1.源字符串必须以 ‘\0’ 结束。
对比以下两张图:
没有‘\0’:

有‘\0’:
在这里插入图片描述

2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
在这里插入图片描述

3.目标空间必须足够大,以确保能存放源字符串。
在这里插入图片描述

4.目标空间必须可变。
在这里插入图片描述

模拟实现strcpy

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{char* ret = dest;assert(dest && src);while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[20] = { 0 };char arr2[] = "abcd";printf("%s\n", my_strcpy(arr1,arr2));return 0;
}

运行结果:
在这里插入图片描述

2.strcat

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

在这里插入图片描述

代码演示:
int main()
{char arr1[20] = "abc";char arr2[] = "def";strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

运行结果:
在这里插入图片描述
1.源字符串必须以 ‘\0’ 结束。(保证能找到目标空间末尾)
在这里插入图片描述
在这里插入图片描述
2.原字符串也必须有‘\0’,再拷贝时将原字符串‘\0’拷贝过去
在这里插入图片描述

3.目标空间必须有足够的大,能容纳下源字符串的内容,目标空间必须可修改。
在这里插入图片描述

4.字符串自己给自己追加,如何?

代码结果:
int main()
{char arr1[20] = "abc";strcat(arr1, arr1);printf("%s\n", arr1);return 0;
}

运行结果:
在这里插入图片描述

模拟实现strcpy

代码案例:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{char* ret = dest;assert(dest && src);//1. 找到目标空间的末尾while (*dest != '\0'){dest++;}//2. 数据追加while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[20] = "abc";char arr2[] = "def";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

运行结果:
在这里插入图片描述
注:这种模拟实现不可以完成自身追加
在这里插入图片描述
为什么不能实现自身追加呢?
在这里插入图片描述

3.strcmp

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

在这里插入图片描述

标准规定:

第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

模拟实现:

//代码演示:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}return *str1 - *str2;
}int main()
{char arr1[] = "abq";char arr2[] = "abc";if (my_strcmp(arr1, arr2) > 0){printf(">\n");}else{printf("<=\n");}return 0;
}

运行结果:
在这里插入图片描述
💘不知不觉,字符函数和字符串函数1(C语言进阶)以告一段落。通读全文的你肯定收获满满,不久的将来会继续更新字符函数和字符串函数,让我们继续为C语言学习共同奋进!!!

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

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

相关文章

逆向学习路径

逆向学习路径 PC端手机端(Android) PC端 计算机操作系统C、C编程语言基础STL等库知识数据结构与算法汇编知识&#xff08;放在这里是因为前面学C、C的时候会有所涉及&#xff0c;学起来简单些&#xff09;windows apiwindows 驱动调试技术&#xff08;6、7有涉及&#xff09;软…

百度SEO优化技巧大揭秘(提高网站排名的必备SEO技术)

SEO优化技术介绍&#xff1a; SEO优化技术是指通过对网站的结构、内容、链接等方面进行优化&#xff0c;提高网站在搜索引擎中的排名&#xff0c;从而增加流量、提升品牌知名度和销售额。目前&#xff0c;在众多搜索引擎中&#xff0c;百度占据了国内搜索引擎市场的主导地位&a…

React(react18)中组件通信04——redux入门

React&#xff08;react18&#xff09;中组件通信04——redux入门 1. 前言1.1 React中组件通信的其他方式1.2 介绍redux1.2.1 参考官网1.2.2 redux原理图1.2.3 redux基础介绍1.2.3.1 action1.2.3.2 store1.2.3.3 reducer 1.3 安装redux 2. redux入门例子3. redux入门例子——优…

电子电子架构——AUTOSAR信息安全机制有哪些(下)

电子电子架构——AUTOSAR信息安全机制有哪些&#xff08;下&#xff09; 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 人们会在生活中不断攻击你。他们的主要…

Jenkins自动化部署前后端分离项目 (svn + Springboot + Vue + maven)有图详解

1. 准备工作 本文的前后端分离项目&#xff0c;技术框架是&#xff1a; Springboot Vue Maven SVN Redis Mysql Nginx JDK 所以首先需要安装以下&#xff1a; 在腾讯云服务器OpenCLoudOS系统中安装jdk&#xff08;有图详解&#xff09; 在腾讯云服务器OpenCLoudOS系统…

如何在Qt Creator 中开启OpenMP

如果是用Visual studio 编译器在.pro文件中加入如下两行&#xff1a; QMAKE_CXXFLAGS -openmp QMAKE_LFLAGS -openmp 如果是用GCC 编译器加入如下两行&#xff1a; QMAKE_CXXFLAGS -fopenmp QMAKE_LFLAGS -fopenmp

SVN的基本使用

一、SVN介绍 SVN&#xff08;Subversion&#xff09;是一个开源的版本控制系统&#xff0c;它专门用于管理文件和目录的变更。SVN 提供了一种集中式的版本控制方案&#xff0c;其中有一个中央仓库存储所有文件的历史记录和变更。 SVN使用方式相对简单&#xff0c;可以通过命令…

Python中TensorFlow的长短期记忆神经网络(LSTM)、指数移动平均法预测股票市场和可视化...

原文链接&#xff1a;http://tecdat.cn/?p23689 本文探索Python中的长短期记忆&#xff08;LSTM&#xff09;网络&#xff0c;以及如何使用它们来进行股市预测&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 在本文中&#xff0c;你将看到如何使用…

DAZ To UMA⭐二.设置DAZ导出的形态键 和 Daz贴图位置

文章目录 🟧 形态键介绍及在Unity3D中的用途1️⃣ Daz中的形态键2️⃣ Blender 中的形态键3️⃣ 形态键在Unity中的作用🟩 设置DAZ导出的形态键1️⃣ 找到要导出的形态键名称2️⃣ 打开导出面板3️⃣ 设置导出规则举例 : 导出身体Morphs举例:导出嘴部Morphs🟦 获取模型纹…

浅析工具dirpro v1.2源码

文章目录 前言源码分析dirpro.pystart.pybackup.pyrely.pyresults.pyend.py 前言 工具简介 dirpro 是一款由 python 编写的目录扫描器专业版&#xff0c;操作简单&#xff0c;功能强大&#xff0c;高度自动化 自动根据返回状态码和返回长度&#xff0c;对扫描结果进行二次整理…

VLAN聚合简介

定义 VLAN聚合&#xff08;VLAN Aggregation&#xff0c;也称Super VLAN&#xff09;指在一个物理网络内&#xff0c;用多个VLAN&#xff08;称为Sub-VLAN&#xff09;隔离广播域&#xff0c;并将这些Sub-VLAN聚合成一个逻辑的VLAN&#xff08;称为Super-VLAN&#xff09;&…

【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux进程 1. 前言2. PCB初认…

一文读懂Llama 2(从原理到实战)

简介 Llama 2&#xff0c;是Meta AI正式发布的最新一代开源大模型。 Llama 2训练所用的token翻了一倍至2万亿&#xff0c;同时对于使用大模型最重要的上下文长度限制&#xff0c;Llama 2也翻了一倍。Llama 2包含了70亿、130亿和700亿参数的模型。Meta宣布将与微软Azure进行合…

iOS16新特性:实时活动-在锁屏界面实时更新APP消息 | 京东云技术团队

简介 之前在 《iOS16新特性:灵动岛适配开发与到家业务场景结合的探索实践》 里介绍了iOS16新的特性&#xff1a;实时更新&#xff08;Live Activity&#xff09;中灵动岛的适配流程&#xff0c;但其实除了灵动岛的展示样式&#xff0c;Live Activity还有一种非常实用的应用场景…

【Vue2.0源码学习】生命周期篇-模板编译阶段(template)

文章目录 1. 前言2. 模板编译阶段分析2.1 两种$mount方法对比2.2 完整版的vm.$mount方法分析 3. 总结 1. 前言 前几篇文章中我们介绍了生命周期的初始化阶段&#xff0c;我们知道&#xff0c;在初始化阶段各项工作做完之后调用了vm.$mount方法&#xff0c;该方法的调用标志着初…

LeetCode322. 零钱兑换

322. 零钱兑换 文章目录 [322. 零钱兑换](https://leetcode.cn/problems/coin-change/)一、题目二、题解方法一&#xff1a;完全背包二维数组方法二&#xff1a;一维数组 三、注意 一、题目 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 a…

【跟小嘉学习区块链】二、Hyperledger Fabric 架构详解

系列文章目录 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 文章目录 系列文章目录[TOC](文章目录) 前言一、Hyperledger 社区1.1、Hyperledger(面向企业的分布式账本)1.2、Hyperledger社区组织结构 二、Hype…

java性能安全:OOM问题排查、Arthas分析高CPU问题、防止Dos攻击

一、OOM问题 分析流程&#xff1a; 第一步&#xff1a;进程分析&#xff0c;分析老年代回收次数和消耗时间 第二步&#xff1a;日志分析&#xff0c;找出OOM发生时间的日志来锁定执行方法&#xff0c;对应的机器ip 第三步&#xff1a;找到对应的ip机器查看&#xff0c;进一步分…

UML六大关系总结

UML六大关系有&#xff1a;继承、关系、聚合、组合、实现、依赖。分为通过图和代码总结这些关系。 1、继承 继承&#xff08;Inheritance&#xff09;&#xff1a;表示类之间的继承关系&#xff0c;子类继承父类的属性和方法&#xff0c;并可以添加自己的扩展。 继承&#x…

Java反序列化漏洞

我想时至今日&#xff0c;这个漏洞依然存在&#xff0c;据说都已经有人写出了webshell&#xff0c;很恐怖呀。 接下来分析下这个漏洞。 Java序列化和反序列化 具体实现细节可参考: Java序列化机制和原理。 一个简易的漏洞程序 在Java反序列化中&#xff0c;会调用被反序列化…