news 2026/5/1 10:17:20

C语言实现strschr函数功能(附带源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言实现strschr函数功能(附带源码)

一、项目背景详细介绍

字符串处理是 C 语言中最常见、最重要的基础能力之一。C 语言的字符串操作函数集中在<string.h>标准库,其中strchr是极为常用的函数,用于查找字符串中第一次出现某个字符的位置

项目要求我们自己实现一个与标准库功能等价的版本——此处命名为:

strschr

以避免覆盖系统函数名称。

实现strschr对理解:

  • C 语言字符串的内部结构

  • 指针运算

  • 内存布局

  • 字符数组遍历策略

  • 字符串终止符\0的意义

具有非常高的教学价值。

为什么要重新实现库函数?

在学习 C 语言过程中,重新实现标准函数有助于我们:

  • 深刻理解函数的具体执行过程

  • 学习高效与安全的实现方式

  • 理解边界检查的重要性

  • 掌握指针相关技术

  • 提升阅读和编写库级代码的能力

尤其对于初学者或希望深入学习 C 语言底层机制的学习者而言,这是非常重要的训练项目。

此外,当我们使用嵌入式系统或自己设计定制库时,很可能不能依赖<string.h>,这时就需要自行实现。

本项目将实现功能完整的strschr,并提供完整教学文档。


二、项目需求详细介绍

项目核心功能要求

实现一个函数:

char *strschr(const char *str, int ch);

其行为应完全等同于strchr

  • 在字符串str中查找字符ch

  • 返回:

    • 指向第一次出现位置的指针

    • 若未找到则返回NULL


详细需求点

  1. 必须正确处理空指针输入

  2. 必须正确处理字符串终止符\0

    • 如果 ch 是\0,必须返回字符串尾部

  3. 必须逐字符扫描,不得使用库函数

  4. 必须用 const 保护输入

  5. 必须返回字符的地址(实现指针运算)

  6. 必须保证性能 O(n)


边界情况需求

要求实现正确处理:

  • 字符串为空(长度为 0)

  • 查找的是字符串不存在的字符

  • 查找的是第一位字符

  • 查找的是最后一位字符

  • 查找'\0'

  • 字符串内有重复字符


项目扩展要求(用于后续加强)

  • 实现strrchr(从右向左查找)

  • 实现查找子串的strstr

  • 实现多字符查找的strpbrk

本项目将提供结构设计,让你未来非常容易扩展。


三、相关技术详细介绍

在实现strschr前,必须掌握如下 C 语言技术点。


1. C 字符串的本质

C 字符串 = 字符数组 + 结束符\0

例如:

"Hello"

实际上由 6 个字符构成:

| H | e | l | l | o | '\0' |


2. 指针遍历字符串

指针可直接访问数组内容:

const char *p = str; while (*p != '\0') { ... p++; }


3. 比较字符

字符是 int,可直接用于比较:

if (*p == ch)


4. 返回指针

如果找到 ch,返回其地址:

return (char *)p;


5. 空指针检查

避免对 NULL 解引用:

if (str == NULL) return NULL;


6. 查找 '\0' 的特殊情况

如果 ch 是'\0'

则结果应返回字符串末尾位置。


四、实现思路详细介绍


1. 函数声明

char *strschr(const char *str, int ch);


2. 逻辑流程

  1. 检查输入是否为 NULL

  2. 定义指针 p 指向 str

  3. 遍历整个字符串

  4. 如果找到匹配字符,返回位置指针

  5. 遍历到末尾仍未找到,则检查是否查找'\0'

  6. 返回 NULL


3. 使用逐字符遍历

遍历直到遇到'\0'

for (const char *p = str; ; p++)


4. 字符匹配判断

if (*p == ch) return (char *)p;


5. 查找 '\0'

循环条件必须允许访问末尾字符。

即使*p == '\0',循环仍需执行一次进行检查。


6. 安全性考虑

  • 输入 NULL 时不能访问内容

  • 函数返回必须是非 const,因为标准库如此设计


五、完整实现代码

/********************************************** * power.h → 已完成其他项目,此项目文件如下 * * 文件:strschr.h * 功能:声明 strschr 函数 **********************************************/ #ifndef STRSCHR_H #define STRSCHR_H #include <stdio.h> // 自定义 strchr 实现 char *strschr(const char *str, int ch); #endif /********************************************** * 文件:strschr.c * 功能:实现 strschr 函数 **********************************************/ #include "strschr.h" char *strschr(const char *str, int ch) { // 1. 空指针检查,防止崩溃 if (str == NULL) return NULL; // 2. 遍历整个字符串 const char *p = str; while (1) { // 判断是否匹配 if (*p == (char)ch) { // 强制转换为非 const,符合标准 strchr 行为 return (char *)p; } // 如果已经到达 '\0',则结束遍历 if (*p == '\0') break; // 移动到下一个字符 p++; } // 如果没有找到,返回 NULL return NULL; } /********************************************** * 文件:main.c * 功能:测试 strschr 实现 **********************************************/ #include "strschr.h" #include <string.h> // 用于对比标准的 strchr int main() { char s[] = "Hello C language!"; printf("原字符串:%s\n", s); char findChar; printf("请输入要查找的字符:"); scanf("%c", &findChar); char *res1 = strschr(s, findChar); char *res2 = strchr(s, findChar); // 用标准库对比 printf("\n=== 自定义 strschr 结果 ===\n"); if (res1) printf("找到字符 '%c',位置偏移:%ld\n", findChar, res1 - s); else printf("未找到字符 '%c'\n", findChar); printf("\n=== 标准 strchr 结果 ===\n"); if (res2) printf("找到字符 '%c',位置偏移:%ld\n", findChar, res2 - s); else printf("未找到字符 '%c'\n", findChar); return 0; }

六、代码详细解读


1. strschr

作用:
实现与strchr完全一致的功能:查找字符串中第一次出现指定字符的位置。

关键点:

  • 指针遍历

  • 字符比较

  • 支持查找\0

  • 支持返回字符位置的指针


2. main

作用:

  • 读取用户输入的字符

  • 调用自定义strschr

  • 调用标准strchr做对比

  • 输出两者的结果

用于验证自定义实现是否正确。


七、项目详细总结

本项目完整实现了strschr字符串查找函数,涵盖了:

  • C 字符串的内部结构

  • 指针操作与指针算术

  • 字符串逐字符遍历方式

  • 如何处理字符串结束符 '\0'

  • 如何正确比较字符与返回位置指针

  • 错误处理(NULL)

  • 与标准库函数行为保持一致

本项目不仅仅是代码实现,更是对 C 语言基础知识体系的全面训练,是每个学习 C 语言的人都应掌握的重要基础技能。


八、项目常见问题与解答


Q1:为什么返回值不是 const char*

因为标准库设计如此,返回非 const 指针以允许修改字符串内容。


Q2:为什么要检查 NULL?标准库没有检查。

因为我们需要提高安全性,避免访问无效指针导致程序崩溃。


Q3:为什么 ch 参数类型是 int?

因为标准库的 strchr 也是 int,支持 EOF 判断和所有 unsigned char 范围。


Q4:查找 '\0' 时应该如何处理?

字符串终止符也算一个合法字符,因此应返回字符串末尾。


Q5:速度是否足够快?

时间复杂度 O(n),属于最优解,无法再优化。


九、扩展方向与性能优化

你可以进一步扩展项目:


1. 实现 strrchr

从右向左搜索:

char *strrchr(const char *s, int c);


2. 实现 strstr

查找子串,难度更高,可使用:

  • 暴力匹配 O(nm)

  • KMP 算法 O(n+m)


3. 实现 strchrnul

GNU 扩展,返回指向 '\0' 的指针,而不是 NULL。


4. 性能优化:使用 SIMD

使用 SSE/AVX 批量比较字符,提高速度。


5. 检查 UTF-8 字符

支持多字节字符搜索,复杂性更高。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:48:25

知网AIGC检测原理是什么?知网AI率检测严格吗?

知网AIGC率过高是当前很多学生和研究者在论文写作中遇到的普遍问题。别慌&#xff0c;只要掌握正确的方法&#xff0c;完全可以将AI生成痕迹有效降低&#xff0c;顺利通过检测。 一、知网AIGC检测原理是什么&#xff1f; 知网等平台通过以下方式判断内容是否由AI生成&#xf…

作者头像 李华
网站建设 2026/4/25 12:14:12

20、强化Linux系统安全与高级管理技巧

强化Linux系统安全与高级管理技巧 1. 强化系统安全 虽然Linux是一个非常安全的操作系统,但仍可以采取一些额外的步骤来进一步加强系统安全。安全的首要原则是,如果你不使用某个特定的服务,就将其关闭。每禁用一个未使用的服务,都会减少系统的攻击面。 1.1 查看开放端口 …

作者头像 李华
网站建设 2026/5/1 9:13:02

Cesium快速入门16:Primitive多个实体与颜色修改

上一节课&#xff0c;我们初步认识了 Cesium 的图元&#xff08;Primitive&#xff09;&#xff0c;当时只放了一个几何体。 其实&#xff0c;一个 Primitive 可以同时塞进多个几何实例&#xff08;GeometryInstance&#xff09;。 这样做的好处很明显&#xff1a;一次合并&…

作者头像 李华
网站建设 2026/5/1 10:15:40

25、Linux Mint系统升级与MATE版本使用指南

Linux Mint系统升级与MATE版本使用指南 1. Linux Mint版本选择与升级考量 在商业和企业环境中,建议使用支持5年的LTS版本。系统管理员若所在公司采用Linux Mint系统,使用非LTS版本会带来大量不必要的工作,因为版本过时后需要大规模重新安装。LTS版本适用于需要稳定且持久运…

作者头像 李华
网站建设 2026/5/1 7:24:28

Cesium快速入门18:Entity材质设置

前面的课程里&#xff0c;我们先后讲了 Entity&#xff08;实体&#xff09;和 Primitive&#xff08;图元&#xff09;这两种“物体”。 它们都能贴材质&#xff0c;只不过用法有简有繁。 今天先集中火力把 Entity 的材质系统 撸一遍&#xff0c;看看 Cesium 到底给我们备好了…

作者头像 李华
网站建设 2026/5/1 9:07:21

《安卓逆向这档事》demo2----正己大佬

demo2 第二关 文本定位 首先&#xff0c;观察界面&#xff0c;查看文字&#xff0c;任务要求是获取硬币并一键三连。主要的两个分别是 获取硬币​ 和 一键三连​&#xff0c;回到 MT 管理器&#xff0c;搜索&#xff08;PS&#xff1a;MT 管理器如何提取安装包定位位置就不细…

作者头像 李华