模拟实现strcmp()(C语言)

C 库函数 - strcmp()

描述

C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。

声明

下面是 strcmp() 函数的声明。

c 复制代码
int strcmp(const char *str1, const char *str2);

参数

  • str1 -- 要进行比较的第一个字符串。
  • str2 -- 要进行比较的第二个字符串。

返回值

该函数返回值如下:

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

模拟实现

比较方式:依次比较 ASCII 大小,大返回正数,小于返回负数,等于则比较下一位。若全都相等则返回 0。

1.0 版本

c 复制代码
#include <stdio.h>
#include <assert.h>

int my_strcmp(const char *str1, const char *str2)
{
    assert(str1 && str2);

    // 依次比较 ascii 大小
    while (*str1 == *str2)
    {
        // 相等且都为 '\0'
        if (*str1 == '\0')
        {
            return 0;
        }
        str1++;
        str2++;
    }
    return (*str1 - *str2);
}

int main()
{
    const char *str1 = "aaaa";
    const char *str2 = "bbbb";
    int ret = my_strcmp(str1, str2);
    printf("%d\n", ret);
    return 0;
}

说明:原 1.0 版本中 if (str1 == '\0') 应改为 if (*str1 == '\0');char* 应改为 const char*,因为字符串字面量不可修改。

2.0 版本

c 复制代码
#include <stdio.h>
#include <assert.h>

int my_strcmp(const char *src, const char *dst)
{
    int ret = 0;
    assert(src != NULL);
    assert(dst != NULL);

    // 以字符类型(以字节为单位)进行整型计算
    while (*dst && *src && !(ret = *(unsigned char *)src - *(unsigned char *)dst))
        ++src, ++dst;

    if (ret < 0)
        ret = -1;
    else if (ret > 0)
        ret = 1;

    return ret;
}

代码优化

综合以上两种写法,可以优化为更简洁、更符合标准、更安全的版本:

c 复制代码
#include <stdio.h>
#include <assert.h>

int my_strcmp(const char *str1, const char *str2)
{
    assert(str1 != NULL && str2 != NULL);

    while (*str1 && *str1 == *str2)
    {
        ++str1;
        ++str2;
    }

    return (*(unsigned char *)str1 - *(unsigned char *)str2);
}

int main(void)
{
    const char *str1 = "aaaa";
    const char *str2 = "bbbb";
    int ret = my_strcmp(str1, str2);
    printf("%d\n", ret);
    return 0;
}
相关推荐
熊猫钓鱼>_>10 小时前
鸿蒙PC高分屏与键鼠交互适配:DPI缩放、右键菜单一次讲清
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙·鸿蒙心迹
系统集成-鹰翔10 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
octopus_c11 小时前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
Eiceblue11 小时前
用 Python 给 Word 文档加水印:文字、图片与批量处理
开发语言·vscode·python·word
j7~11 小时前
【C++ 面试笔记】(篇二):类与数据抽象 & STL 容器与算法
开发语言·c++·面试·stl容器和算法·类和数据抽象
Fuyo_111911 小时前
深入解析 C++ unordered_set 与 unordered_map 的核心特性与性能实战
开发语言·c++
软件技术NINI11 小时前
基于SpringBoot和Vue的摇滚乐鉴赏网站
vue.js·spring boot·后端·spring·html·毕业设计·毕设
ShineWinsu12 小时前
对于Qt:QPushButton常见属性的解析
开发语言·c++·qt·api·gui·按钮·qpushbutton
外贸GEO优化12 小时前
外贸独立站的可抓取性:JS 渲染、懒加载与无限滚动到底影响什么
开发语言·javascript·ecmascript
飞浪纪元[FWC–FE]12 小时前
Qt 工程创建与 CMake / qmake 构建规范
开发语言·数据库·qt