c语言中字符串比较的库函数是什么

news2024/11/24 11:58:51

说起比较运算,肯定第一时间想到了C语言中关于比较的相关运算符 “>、<、!=、>=、<=、==”,那么要比较两个字符串是否相等是不是直接用“==”比较就行了。下面就来看看这种方法行不行?

先看一个例子

void main( void )
{
    char s1[] = "abc";
    char s2[] = "abc";    
    __asm( "sim" );                             //禁止中断
    SysClkInit();
    delay_init( 16 );
    LED_GPIO_Init();
    BEEP_GPIO_Init();
    Uart1_Init( 9600 );
    __asm( "rim" );                             //开启中断
    while( 1 )
    {
        if( s1 == s2 )
        {
            printf( "equal" );
        }
        else
        {
            printf( "Not equal" );
        }
    }
}

复制

有两个字符串s1和s2,内容都是”abc”,在if语句中通过”==”运算符进行比较。

运行结果是s1和s2不相等,那为什么是不相等呢,通过右边的观察窗口可以看到,s1和s2是内部的两个存储空间,地址不一样,但是地址中的内容是一样的。那么用“ if( s1 == s2 )”这行语句去比较的时候,其实比较的是s1和s2的地址,不是比较地址中的内容,而s1和s2的地址是不相同的。

要比较内容的话,代码需要修改一下。

  if(( s1[0] == s2[0] )&&( s1[1] == s2[1] )&&( s1[2] == s2[2] ))
        {
            printf( "equal" );
        }
        else
        {
            printf( "Not equal" );
        }

复制

将代码修改为依次比较字符串中的内容

通过字符串的每一位依次比较,这样的比较方式,就可以判断出字符串相等。

将字符串数组改为指针看看

将s1和s2改为指针,可以看到通过”==”比较,结果是相等的。通过右边的观察窗口可以看出s1和s2的地址是相同的,也就是这两个字符串指向了同一个地址空间。说明此时比较的还是地址,而不是地址中的内容。我们需要比较的是内容。

将代码修改为获取指针的内容,发现比较结果也是相等的。那么能不能说明这种比较方法是可以的。将字符串内容修改一下在看看。

内容改变后,指针的地址也发生了改变,此时”s1==s2″语句就不成立了。

但是这时候”*s1==*s2″依然是相等的,这是为什么呢?通过右侧的观察窗口可以看到,此时*s1和*s2的内容是”a”,而不是整个字符串的内容。说明这行代码比较的是字符串的第一个字符,而不是整个字符串。那么要比较整个内容的话,还得每个字符挨个比较。

通过上面的分析可能会有一个疑问,为什么用”==”运算符比较单个字符的时候比较的就是内容,而比较字符串的时候,比较的却是地址?

这就要说下一字符串在C语言中比较特殊的一点,在C语言中处理一般的变量如整形、字符型、浮点型时,直接操作的是变量的值,比如 int a,b; a=b;在执行这行代码的时候,是将b的值拷贝一份然后复制给a。比较运算符“==”在使用的时候,也直接比较的是变量的值。而C语言在使用字符串的时候,是通过地址引用而不是值引用来操作的。

通过数组定义的字符串,系统分配的是两个不同的地址,虽然内容相同,但是实际上地址是不相同的,通过相等运算符”==”比较时,比较的是s1和s2本身的值,s1和s2本身的值是一个地址,这两个地址不同,所以比较结果就不相等。

用指针定义的两个字符串,系统分配的是同一个地址空间,说明虽然他们的名字不一样,但是实际上是共用了同一个地址。通过相等运算符”==”比较时,比较的是s3和s4本身的值,s3和s4本身的值是一个地址,这两个地址相同,所以比较结果相等。

通过上面的分析,发现在处理字符串的时候不能直接用”==”运算符去比较,那么要如何去比较呢?

可以直接使用 C 库函数 int strcmp(const char *str1, const char *str2)str1 所指向的字符串和 str2 所指向的字符串进行比较。

该函数返回值如下:

  • 如果返回值小于 0,则表示 str1 小于 str2。
  • 如果返回值大于 0,则表示 str1 大于 str2。
  • 如果返回值等于 0,则表示 str1 等于 str2。

strcmp函数实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着 比较第二个字符然后第三个字符等等。

这个函数其实就是相当于把上面例程中对字符串每个字符独立比较方法的一个封装,内部函数实现方式类似于下面这样。

由于字符串在C语言中的处理比较特殊,所以C语言提供了一个专门操作字符串的库。关于字符串的操作在”string.h”这个头文件中可以看到。

有字符串增加,字符串删除,字符串拷贝,字符串比较,字符串查找等等各种功能的函数封装,这样在处理字符串的时候就可以直接调用库函数来实现。

比如在处理串口命令的时候,如果串口命令为字符串,就可以直接用字符串比较命令去实现。

 if ( strcmp( uartRecStr, "led1 on" ) == 0 )
            {
                led1_on();
            }
            else if ( strcmp( uartRecStr, "led1 off" ) == 0 )
            {
                led1_off();
            }
            else if ( strcmp( uartRecStr, "led2 on" ) == 0 )
            {
                led1_off();
            }
            else if ( strcmp( uartRecStr, "led2 off" ) == 0 )
            {
                led1_off();
            }

复制

将接收到字符串和指定的字符串比较,如果字符串相等,就调用相关的函数,这样通过if语句就可以简单的处理串口的指令。

不过通过if语句比较的话,程序的分支太多,程序看起来比较臃肿,能不能用switch语句去实现呢?但是switch语句中不支持字符串的比较直接比较,那要怎么实现?

char *cmdStr[] = {"led1 on", "led1 off", "led2 on", "led2 off"};  //字符串命令数组
len = sizeof( cmdStr ) / sizeof( cmdStr[0] );       //计算字符串个数
         for( i = 0; i < len; i++ )
            {
                if( strcmp( uartRecStr, cmdStr[i] ) == 0  )
                {
                    switch( i )//分支语句不支持字符串,通过字符串数组的下标确定是哪个字符串。
                    {
                    case 0:
                        led1_on();
                        break;
                    case 1:
                        led1_off();
                        break;
                    case 2:
                        led2_on();
                        break;
                    case 3:
                        led2_off();
                        break;
                    default:
                        break;
                    }
                }
            }

复制

可以将字符串存储在数组中,通过数组的下标去调用不同的字符串,然后使用字符串比较函数去判断字符串,这样switch语句的分支判断就可以转换为字符串的下标。

通过这种方法就可以直接在串口中处理简单的通信命令了。

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

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

相关文章

chatgpt赋能python:Python中如何使用局部变量

Python中如何使用局部变量 Python是一种高级编程语言&#xff0c;它是一种解释型语言&#xff0c;因此它的速度可能不如C 或Java等编译型语言快&#xff0c;但是Python的语法简洁&#xff0c;易于阅读和编写&#xff0c;并且具有强大的功能。 在Python中&#xff0c;变量是一…

SAP VK11税码的理解

背景:销售订单税率获取逻辑 1.工厂&#xff0c;工厂定义维护了国家代码信息 (SO–工厂–国家代码) 2.客户主数据通用数据维护了国家代码 (SO-客户–国家代码) 3.客户主数据销售数据维护了国家代码对应的税分类&#xff08;此国家代码由销售组织对应国家代码维护的国家代码带出来…

DAY08_JavaScript

目录 1 JavaScript简介2 JavaScript引入方式2.1 内联脚本2.2 内部脚本2.3 外部脚本 3 JavaScript基础语法3.1 书写语法3.2 输出语句3.3 变量3.4 数据类型3.5 运算符3.5.1 \和区别3.5.2 类型转换 3.6 流程控制语句3.6.1 if 语句3.6.2 switch 语句3.6.3 for 循环语句3.6.4 while …

c++ ——day1 homework

1.整理思维导图 2.有以下定义&#xff0c;哪些变量可以改变 const和*的位置&#xff0c;const在前&#xff0c;里面的值不能动*p&#xff0c;地址可以动p const在后&#xff0c;地址不能动&#xff0c;值可以动 const char *p&#xff1a;内容不可变&#xff0c;地址可变 co…

PCL点云处理之添加高斯噪点的两种方法(详细注释版)(一百八十一)

PCL点云处理之添加高斯噪点的两种方法(详细注释版)(一百八十一) 一、实验效果二、算法简介三、具体流程四、PCL自带函数实现1.代码2.结果五、Boost函数实现1.代码2.结果总结一、实验效果 通过实验测试,效果如上所示,算法可以正常运行 二、算法简介 高斯噪声是指它的概率…

实习内容总结

目录 项目BMS后台管理系统FantasyPayment通用支付框架 技术文档 实习时间&#xff1a;2022.12 &#xff5e; 2023.06 公司是初创公司&#xff0c;主要专精于AIGC方向&#xff0c;之前主要是To C的业务&#xff0c;做三消类游戏。今年刚刚转向To B业务&#xff0c;我去的时候Go…

Java性能权威指南-总结6

Java性能权威指南-总结6 垃圾收集入门垃圾收集概述GC算法选择GC算法 垃圾收集入门 垃圾收集概述 GC算法 JVM提供了以下四种不同的垃圾收集算法: Serial垃圾收集器 Serial垃圾收集器是四种垃圾收集器中最简单的一种。如果应用运行在Client型虚拟机(Windows平台上的32位JVM或…

【TaskMatrix.AI - Visual ChatGPT】连接超大模型和超多API来完成任务

Github项目地址&#xff1a;https://github.com/microsoft/TaskMatrix 目前大规模预训练模型&#xff08;比如ChatGPT&#xff09;已经能够完成多个任务&#xff0c;例如 提供强大的对话功能&#xff0c;in-context learning能力和代码生成能力生成高层次的解决问题框架 然而…

Vue.js 比较重要知识点总结四

概述 ref toRef toRefs进阶&#xff0c;深入理解vue3 setupVue3为何比Vue2快&#xff1f;怎样理解 Vue 的单向数据流&#xff1f;Vue 中事件绑定原理vue3 mitt 使用 ref toRef toRefs进阶&#xff0c;深入理解 为何需要ref&#xff1f; 返回值类型&#xff0c;会丢失响应式se…

【常用设计模式】待补充

Github仓库地址 概述 23中设计模型分为常见的三大类&#xff1a;创建型模式、结构型模式和行为型模式 创建型模式 简单工厂模式 描述 简单工厂模式不是23中设计模式中的。简单工厂模式不直接向客户端暴露对象创建的细节&#xff0c;而是通过一个工厂类来负责创建产品类的实…

12.MSP432E4 Keil烧录报错Error Flash Download failed - Cortex-M4

一、简介 前段时间琢磨了一块新板子&#xff0c;ESP432E401Y。 遇到一个问题&#xff0c;简单记录一下&#xff0c;问题是在keil中正常烧录程序后&#xff0c;在CCS下也烧录了一次程序&#xff0c;然后就一直无法再到keil中烧录&#xff0c;但是CCS一直是正常烧录的。keil报错…

Spark集群搭建

系列文章目录 Ubuntu常见基本问题 Hadoop3.1.3安装&#xff08;单机、伪分布&#xff09; Hadoop集群搭建 HBase2.2.2安装&#xff08;单机、伪分布&#xff09; Zookeeper集群搭建 HBase集群搭建 Spark安装和编程实践&#xff08;Spark2.4.0&#xff09; Spark集群搭建 文章目…

linux开发:linux最大线程数分析

linux最大线程数分为&#xff0c;进程最大线程数&#xff0c;用户最大进程数&#xff0c; 整个系统已用的线程或进程数。 我们可以用下面命令进行查询这三个进程数。 linux系统可生成最大线程数可以用这个命令查询 cat /proc/sys/kernel/threads-max 进程最大线程数查询方式 ps…

家用儿童帆布床出口欧盟CE认证EN716测试

1.标准适用范围 该标准规定了内部长度大于900mm但不超过1400mm的家用童床的安全要求。该安全要求适用于完全组装完毕待用的童床。可以转换成其它产品的童床&#xff08;如&#xff1a;可变产品、游戏床&#xff09;转换后应该符合相关欧洲标准。该标准不适用于提篮、婴儿床和摇…

hacknet攻略(更新中)

序章 然后点自己的电脑&#xff0c;再点一下SCAN(扫描可用主机)&#xff0c;再点断开 然后点蓝色的电脑&#xff0c;是连接的意思 点中间Probe系统图标&#xff0c;看开放端口数 若端口数为0可以使用porthakc命令直接黑入系统 几个会用到的命令cd, rm * ,dc关闭连接&…

Unity制作二次元卡通渲染角色材质——4 、内外描边和细节添加

Unity制作二次元材质角色 回到目录 大家好&#xff0c;我是阿赵。 这里继续讲二次元角色材质。这次打算讲一下描边和细节的添加。 一、外描边 外描边的做法也不止一种&#xff0c;比如后处理方法的偏导数ddx/ddy之类的&#xff0c;也能整个屏幕的求出边缘。但一般来说单模型渲…

MySQL数据库学习笔记(九)实验课六之触发器和存储过程

没想到这就是最后一次实验了。 一点知识&#xff1a; 道具 – delimiter / DELIMITER 这是用于指定语句分隔符的特殊命令 默认情况下&#xff0c;MySQL使用分号&#xff08;;&#xff09;作为语句的结束符。然而&#xff0c;当我们需要定义存储过程、触发器或函数等包含多条S…

51智能小车-串口控制、循迹、避障

目录 1.串口控制小车 2.循迹小车 3.避障小车 1.串口控制小车 L9110s概述 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是不对&#xff0c;根据下节课实际调试 IA1输入高电平&#xff0c;IA1输入低电平&#xff0c;【OA1 OB1】电机…

总结890

学习目标&#xff1a; 月目标&#xff1a;6月&#xff08;线性代数强化9讲2遍&#xff0c;背诵15篇短文&#xff0c;考研核心词过三遍&#xff09; 周目标&#xff1a;线性代数强化3讲&#xff0c;英语背3篇文章并回诵&#xff0c;检测 每日必复习&#xff08;5分钟&#xff…

STM32开发——简介、开发环境(Keil5、CubeMX)、HAL库

目录 1.简介-初识STM32 2.开发环境 2.1使用Keil5 2.2使用STM32CubeMX 3.标准库与HAL库区别 4.推挽输出与开漏输出 1.简介-初识STM32 什么是单片机&#xff1f; 单片机&#xff08;Single-Chip Microcomputer&#xff09;是一种集成电路芯片&#xff0c;把具有数据处理能…