当前位置: 首页 > news >正文

strlen 函数的使用与模拟实现

目录

一、strlen 函数的基本特性

二、使用注意事项

补码是计算机表示有符号整数的标准方式,其核心规则是:(后面会讲解)

具体执行过程

为什么会出现这种情况

补码计算详细解释

三、strlen 的模拟实现

方法1:计数器方式

方法2:递归方式(不创建临时变量)

方法3:指针相减方式

四、实际应用建议


一、strlen 函数的基本特性

strlen 是 C 语言标准库中用于计算字符串长度的函数,其原型如下:

size_t strlen(const char *str);

该函数具有以下特点:

  1. 以 '\0' 为结束标志:字符串必须以空字符 '\0' 结尾,函数返回的是 '\0' 前面出现的字符个数(不包含 '\0' 本身)

  2. 返回值类型:返回值为 size_t 类型,这是一个无符号整型(unsigned integer),这在比较字符串长度时容易导致错误

  3. 头文件:使用前需要包含 <string.h> 头文件


二、使用注意事项

        在这个例子中,关键问题在于 strlen() 返回的是 size_t 类型(无符号整数),而两个无符号整数相减的结果也是无符号整数,这会导致一些违反直觉的比较结果。

#include <stdio.h>
#include <string.h>int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";if(strlen(str2) - strlen(str1) > 0){printf("str2 > str1\n");  // 这个分支会被执行}else{printf("str1 > str2\n");}return 0;
}

        上述代码会输出 "str2 > str1",尽管直观上 "abcdef" 比 "bbb" 长。这是因为无符号数相减的结果也是无符号数,永远不会小于0。

补码是计算机表示有符号整数的标准方式,其核心规则是:(后面会讲解)

  • 正数的补码 = 其二进制原码(和原码相同)

  • 负数的补码 = 其绝对值的二进制表示取反(按位取反)后加 1

具体执行过程

  1. strlen(str2) 返回 3(size_t 类型)

  2. strlen(str1) 返回 6(size_t 类型)

  3. 计算 3 - 6

    • 对于无符号整数,这个操作不会产生负数

    • 在32位系统中,size_t 通常是32位无符号整数

    • 3 - 6 的补码计算:

      • 3 的二进制: 0000 0000 0000 0000 0000 0000 0000 0011

      • -6 的二进制(补码): 1111 1111 1111 1111 1111 1111 1111 1010

      • 相加结果: 1111 1111 1111 1111 1111 1111 1111 1101

    • 这个结果解释为无符号整数是一个很大的正数(4294967293)

  4. 比较 (4294967293 > 0) 结果为真

为什么会出现这种情况

  • 无符号整数没有负数的概念,当减法结果为"负"时,会回绕到最大的无符号整数

  • 这是C语言中常见的安全隐患,称为"无符号整数回绕"(unsigned integer wrap-around)

补码计算详细解释

在计算机中,负数用补码表示,减法实际上是加负数的补码:

  1. 计算 -6 的补码:

    • 6 的二进制: 0000 0000 0000 0000 0000 0000 0000 0110

    • 取反: 1111 1111 1111 1111 1111 1111 1111 1001

    • 加1: 1111 1111 1111 1111 1111 1111 1111 1010 (这就是-6的补码)

  2. 计算 3 + (-6):

      0000 0000 0000 0000 0000 0000 0000 0011 (3)
    + 1111 1111 1111 1111 1111 1111 1111 1010 (-6)
    -----------------------------------------1111 1111 1111 1111 1111 1111 1111 1101 (结果)
  3. 如果解释为有符号整数,这是-3

  4. 但作为无符号整数,这是4294967293


三、strlen 的模拟实现

方法1:计数器方式

#include <assert.h>
#include <stdio.h>int my_strlen(const char* str)
{int count = 0;assert(str != NULL);  // 确保指针非空while (*str != '\0'){count++;str++;}return count;
}int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";printf("%zu\n", my_strlen(str1));printf("%zu\n", my_strlen(str2));return 0;
}

方法2:递归方式(不创建临时变量)

#include <assert.h>
#include <stdio.h>int my_strlen(const char* str)
{assert(str != NULL);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";printf("%zu\n", my_strlen(str1));printf("%zu\n", my_strlen(str2));return 0;
}

先拆分(递推),再回归(返回):(忘记了的话可以先回顾递归那一章节的知识点)

方法3:指针相减方式

#include <assert.h>
#include <stdio.h>int my_strlen(const char* str)
{assert(str != NULL);const char* p = str;  // 使用const保持一致性while (*p != '\0')p++;return p - str;  // 指针相减得到元素个数
}int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";printf("%zu\n", my_strlen(str1));printf("%zu\n", my_strlen(str2));return 0;
}


四、实际应用建议

  1. 安全性:在实际项目中,应考虑添加参数检查(如使用assert)

  2. const修饰:使用const修饰指针参数可以防止意外修改字符串内容

  3. 性能考虑:指针相减的方式通常效率最高,递归方式最不推荐在实际项目中使用

  4. 边界情况:处理空字符串("")时应返回0,处理NULL指针时应进行错误处理

        这些实现方式展示了C语言中字符串操作的多种思路,理解它们有助于深入掌握指针和字符串处理的核心概念。

http://www.xdnf.cn/news/1328905.html

相关文章:

  • 算法——质数筛法
  • 106、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(下)
  • yolov5s.onnx转rk模型以及相关使用详细教程
  • 玳瑁的嵌入式日记D20-08019(数据结构)
  • 安装DDNS-go
  • Linux操作系统编程——进程间的通信
  • RocketMq消费者动态订阅topic
  • RK3568 Linux驱动学习——Linux设备树
  • Linux下Mysql命令,创建mysql,删除mysql
  • Win/Linux笔记本合盖不睡眠设置指南
  • 小程序插件使用
  • RWA加密金融高峰论坛星链品牌全球发布 —— 稳定币与Web3的香港新篇章
  • Vue 2 项目中快速集成 Jest 单元测试(超详细教程)
  • 哈希:两数之和
  • 从零开始的云计算生活——第四十六天,铁杵成针,kubernetes模块之Configmap资源与Secret资源对象
  • 【技术揭秘】AI Agent操作系统架构演进:从单体到分布式智能的跃迁
  • 告别手写文档!Spring Boot API 文档终极解决方案:SpringDoc OpenAPI
  • 大数据数据库 —— 初见loTDB
  • 视觉采集模块的用法
  • A股大盘数据-20250819 分析
  • 云原生俱乐部-shell知识点归纳(1)
  • 力扣57:插入区间
  • 决策树剪枝及数据处理
  • AI 药物发现:化学分子到机器学习数值特征的转化——打通“化学空间”与“模型空间”关键路径
  • 【Git 子模块与动态路由映射技术分析文档】
  • Matplotlib数据可视化实战:Matplotlib子图布局与管理入门
  • 疏老师-python训练营-Day50预训练模型+CBAM注意力
  • PCL+Spigot服务器+python进行MC编程(使用Trae进行AI编程)---可以生成彩虹
  • Hugging Face 核心组件介绍
  • 35岁对工作的一些感悟