字符函数和字符串函数(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,一经查实,立即删除!

相关文章

百度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系统…

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;该方法的调用标志着初…

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

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

UML六大关系总结

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

【Spring Boot】Spring Boot源码解读与原理剖析

这里写目录标题 前言精进Spring Boot首选读物“小册”变“大书”&#xff0c;彻底弄懂Spring Boot全方位配套资源&#xff0c;学不会来找我&#xff01;技术新赛道&#xff0c;2023领先抢跑 前言 承载着作者的厚望&#xff0c;掘金爆火小册同名读物《Spring Boot源码解读与原理…

Windows11 手把手教授开放端口

首先在控制面板点击“系统与安全”&#xff0c;找到防火墙 然后点击“windows defender”打开防火墙 点击左侧目录栏中“高级设置” 点击“入站规则”&#xff0c;再点击新建入站规则&#xff08;开放端口有开放入站端口与开放出站端口之分&#xff0c;这里讲入站端口的开放…

老胡的周刊(第109期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 lobe-chat[2] LobeChat 是一个开源的、可扩展…

Redis 缓存雪崩、缓存穿透、缓存击穿

Redis 是一种常用的内存缓存工具&#xff0c;但在某些情况下&#xff0c;它可能会遭受缓存雪崩、缓存穿透和缓存击穿等问题。下面是一些预防这些问题的建议&#xff1a; 1、缓存雪崩 缓存雪崩指的是在某个时间点上&#xff0c;大量的缓存数据同时失效或过期&#xff0c;导致大…