【C语言】详解strlen函数 您所在的位置:网站首页 自己写strlen函数 【C语言】详解strlen函数

【C语言】详解strlen函数

2024-05-21 18:13| 来源: 网络整理| 查看: 265

【C语言】详解strlen函数 | 模拟实现strlen函数的三种方法 | 写库函数的人是如何实现这个函数的_c语言

前言:

本篇将专门为 strlen 函数进行讲解,总结了模拟实现 strlen 函数的三种方法,并对其进行详细的解析。手写库函数是非常常见的题目,希望通过本篇博客能够加深大家对 strlen 的理解。最后,祝大家国庆节快乐!

一、strlen函数介绍

【百度百科】strlen 所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符 \0 为止,然后返回计数器值(长度不包含 \0 )。

【C语言】详解strlen函数 | 模拟实现strlen函数的三种方法 | 写库函数的人是如何实现这个函数的_#include_02

📜 头文件: string.h

📚 说明:字符串以 \0 作为结束标志,strlen 返回的是在字符串中 \0 前面出现的字符个数。因为求的是字符串的长度,也就是字符的个数,所以不包括  \0 字符。(注:sizeof 包括 \0

📌 注意事项:

① 参数指向的字符串必须以  \0 

② 函数的返回值为 size_t ,即无符号整数(unsigned)的别名。参见宏定义:typedef unsigned int size_t;

❓ 为什么返回无符号呢?

💡 既然是求字符串长度,那么出现负数就没有意义,所以使用 size_t 

💬 使用方法演示:

#include #include

int main() { char arr[] = "abcdef"; int len = strlen(arr); printf("len = %d\n", len);

return 0;}

🚩  运行结果: 6

二、模拟实现 strlen(介绍三种方法)法1:计数器(需创建临时变量)

💬 模拟实现 strlen 函数:

#include

size_t my_strlen(const char* str) { int count = 0; //创建计数器 while (*str != '\0') { //对 str 解引用,如果 *str 不是 \0 str++; // 指针向后移动1位(char) count++; // 计数器+1 } return count; //返回计数器}

int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("len = %d\n", len);

return 0;}

💡 解析:加上 const 修饰提高代码的健壮性,用 const char* 接收传入的参数。因为 arr 数组名是首元素地址,所以需要用指针变量接收。创建变量 count 来作为计数器,在循环内进行指针加整数,直到碰到 \0 跳出循环,最后返回计数器 count 。

⚡ 简化: 

#include

size_t my_strlen(const char* str) { int count = 0; while (*str) { str++; count++; } return count;}

int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("len = %d\n", len);

return 0;}

法2:递归实现

💬 模拟实现 strlen 函数(禁止创建临时变量):

#include

size_t my_strlen(const char* str) { if (*str != '\0') { return 1 + my_strlen(str + 1); } else { return 0; }}

int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("len = %d\n", len);

return 0;}

💡 解析:首先进行判断,对 str 进行解引用,如果不是 \0 就返回 1 + my_strlen(str + 1) ,此时 " 1+ " 就起到了计数的作用,随后自己调用自己 my_strlen(str + 1) ,递归下去直到是 \0 为止,碰到后返回 0,随后再一步步倒回去,就可以返回长度了。当然,如果传入的字符串长度为 0,会直接走 else 返回 0。

📌 注意:不要将 my_strlen(str + 1)  写成 my_strlen(str++)  ,在这里使用 后置++ 是非常致命的!

法3:指针减指针

💬 模拟实现 strlen 函数(禁止创建临时变量):

#include

size_t my_strlen(const char* str) { const char* start = str; //字符串的起始位置就是str const char* end = str;

while (*end != '\0') { //用来找到字符串的末尾处 end++; }

return end - start; //最后指针减指针,巧妙地得到了字符串的长度}

int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("len = %d\n", len);

return 0;}

 💡 解析:利用 " 指针减指针得到的是元素之间元素的个数" 这一特性得到字符串的长度。首先创建 start 变量用于记录字符串的起始位置,随后创建 end 变量并找到末尾位置( 不是 \0 就往后推进的方法 )。最后返回 end - start,末尾位置减去起始位置即可得到字符串的长度。

⚡ 其实库函数就用了这种方法,真的是妙不可言!不过将代码进一步地简化了: 

#include

size_t my_strlen(const char* str) { const char* end = str; while (*end++); return end - str - 1;}

int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("len = %d\n", len);

return 0;}

💡 解析:首先其实大可不必创建 start 变量,因为 str 本身就记录着起始位置。while 括号中这种情况下自然可以省去 \0 ,库函数作者直接将 end++ 的操作直接丢入判断条件中。*end++ 优先级相同,根据结合性(从右向左)。因为 while 循环条件会比循环体多执行一次,放进循环条件内的*end++ 因为这个 "特性" 多执行了一次,所以最后 end - start 要手动 -1。返回 end - start - 1 ,即字符串长度。

📌 注意事项:while

​​【维生素C语言】第二章 - 分支和循环​​

📂 最后贴上 src 文件夹中的 strlen.c

/****strlen.c - contains strlen() routine** Copyright (c) Microsoft Corporation. All rights reserved.**Purpose:* strlen returns the length of a null-terminated string,* not including the null byte itself.********************************************************************************/

#include #include

#pragma function(strlen)

/****strlen - return the length of a null-terminated string**Purpose:* Finds the length in bytes of the given string, not including* the final null character.**Entry:* const char * str - string whose length is to be computed**Exit:* length of the string "str", exclusive of the final null byte**Exceptions:********************************************************************************/

size_t __cdecl strlen ( const char * str ){ const char *eos = str;

while( *eos++ ) ;

return( eos - str - 1 );}

是不是赏心悦目?编写库函数的人就连代码风格都这么霸气!

参考资料:

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

封面作者:迷因烧鸭

📌 作者:王亦优

📃 更新: 2021.10.1

❌ 勘误: 无

📜 声明: 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!

本篇完。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有