2013-07-05 11:36:05

小结:

本函数给出了几种strlen的实现,有ugly implementation,也有good implementation。并参考标准库中的implementation,最后给出了比较好的implementation。

求字符串长度,可通过两种方式实现:

  1. 是在遍历字符串中字符的时候用一个计数器记录字符个数,如下面函数_strlen_1中所示;
  2. 可用指向字符串截尾的指针减去指向字符串开始的指针得到,这种方式写出的代码更加简洁,也是库函数采用的实现方式,如函数_strlen_2、_strlen_3、_strlen_4中采用的方式。

标准库函数并没有输入合法性检查,这将输入合法性检查的任务推给了函数的调用者。
对于strlen函数,好的implementation要考虑一下几点:

  1. 函数参数应为const;
  2. 返回值应为unsigned int;
  3. 注意输入合法性检查。

代码:

 #include <iostream>

 using namespace std;
#define SIZE 100 /***
*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:
*
*******************************************************************************/ //不好的implementation
//返回值应该用unsigned int或直接size_t,不应用int
int _strlen_1(const char *str) //参数要用const,防止改动
{
if (NULL == str)
{
return ;
} int len = ;
while (*str++ != '\0')
{
++len;
} return len;
} //使用指针计算长度,同时将返回值改为size_t类型
size_t _strlen_2(const char *str)
{
if (NULL == str)
{
return ;
} const char *pstr = str;
while (*pstr++ != '\0'); //循环结束时,pstr指向的是'\0'的下一个位置,而非'\0',因此下面要减1 //return (pstr - str + 1);
return (pstr - str - );
} //标准库函数给出的implementation
size_t _strlen_3 (
const char * str
)
{
const char *eos = str; while( *eos++ ) ; return( eos - str - );
} //标准库函数给出的implementation的改进,加上输入合法性检查
//好的implementation要考虑一下几点:
//1)函数参数应为const;
//2)返回值应为unsigned;
//3)注意输入合法性检查
size_t _strlen_4(const char *str) //typedef _W64 unsigned int size_t;
{
if (NULL == str) //标准库函数给出的implementation中没有判断字符串是否为空
{
return ;
} const char *eos = str; while ( *eos++ ); //等价于while (*eos++ != '\0'); return (eos - str - );
} int main()
{
//_strlen
char str[SIZE] = "hello world!"; cout<<"test _strlen_1..."<<endl;
cout<<"the length of string "<<str<<" is : "<<_strlen_1(str)<<endl;
cout<<"the length of string NULL is : "<<_strlen_1(NULL)<<endl; cout<<"test _strlen_2..."<<endl;
cout<<"the length of string "<<str<<" is : "<<_strlen_2(str)<<endl;
cout<<"the length of string NULL is : "<<_strlen_2(NULL)<<endl; cout<<"test _strlen_3(the standard implementation)..."<<endl;
cout<<"the length of string "<<str<<" is : "<<_strlen_3(str)<<endl;
/*cout<<"the length of string NULL is : "<<_strlen_3(NULL)<<endl;*/ cout<<"test _strlen_4..."<<endl;
cout<<"the length of string "<<str<<" is : "<<_strlen_4(str)<<endl;
cout<<"the length of string NULL is : "<<_strlen_4(NULL)<<endl; return ;
}

strlen的C/C+++实现的更多相关文章

  1. php的empty(),trim(),strlen()方法

    如果empty()函数的参数是非空或非零的值,则empty()返回FALSE.换句话说,"".0."0".NULL.array().var$var:以及没有任何 ...

  2. c/c++中关于sizeof、strlen的使用说明

    sizeof: 一般指类型.变量等占用的内存大小(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小) strlen: c字符串的长度(参数必须是字符型指针 char*,当数组名作 ...

  3. [PHP源码阅读]strlen函数

    文章来自:http://www.hoohack.me/2016/02/22/phps-source-analytics-strlen 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下, ...

  4. php每天一题:strlen()与mb_strlen()的作用分别是什么

    strlen()与mb_strlen()都是用于获取字符串长度的,那么它们两个有什么不同? strlen()与mb_strlen()的不同之处在于mb_strlen()第二个参数可以用于指定字符编码. ...

  5. sizeof与strlen的区别

    1 sizeof是操作符,而strlen是库函数: 2 sizeof的参数可以为任意变量或类型,而strlen必须以char*做参数,且字符串必须以‘/0’结尾: 3 数组名用作sizeof参数时不会 ...

  6. strlen()和sizeof()求数组长度

    在字符常量和字符串常量的博文里有提: 求字符串数组的长度 标准库函数strlen(s)可以返回字符串s的长度,在头文件<string.h>里. strlen(s)的判断长度的依据是(s[i ...

  7. Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解

      strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...

  8. 回文字符串的判断!关于strlen(char * str)函数

    #include <stdio.h> #include <string.h> int ishuiw(char * p); int main() { ;//true-false接 ...

  9. 关于strlen误用的一点记录

    今天帮一个朋友查一个错误,是运行时报vector iterator incompatible,一般这种问题是向量和迭代器的类型不兼容,或者是进行迭代器判等时前后向量的结构发生变化,如erase操作之后 ...

  10. sizeof、strlen、字符串、数组,整到一块,你还清楚吗?

    写在前面 sizeof.strlen.字符串.数组,提到这些概念,相信学过C语言的人都能耳熟能详,也能谈得头头是道,但是,在实际运用中,当这些内容交织在一起时,大家却不一定能搞地清清楚楚,本文的目的正 ...

随机推荐

  1. nodejs remote链接mysql数据库总结

    nodejs链接远端mysql,这个折腾了一个上午才搞定.本以为,直接使用就OK了,但是发现不行,后来查阅各种资料后,终于找到了方法. nodejs链接远端数据库主要分为几个步骤: 1)安装node- ...

  2. input获取永久焦点

    $(function () { $('#test').blur(function () { var that = this; //或者用闭包 setTimeout(function () { $(th ...

  3. PHP实现获得一段时间内所在的所有周的时间

    function getWeek($startdate,$enddate) { //参数不能为空 if(!empty($startdate) && !empty($enddate)){ ...

  4. php异步加载、多线程fsockopen()、fputs()

    index.php <?php function test() { $fp=fsockopen("localhost", 80, $errno, $errstr, 30); ...

  5. SQL Server— 存在检测、建库、 建表、约束、外键、级联删除

    /******************************************************************************** *主题: SQL Server- 存 ...

  6. zxing-master core编译

    1.下载 Maven: http://maven.apache.org/download.cgi 2.下载完以后,设一下系统变量:MAVE_HOME 3.Path中加入%MAVEN_HOME%\bin ...

  7. shell自定义函数

    Linux中提供了很多内置的函数,但有时我们需要根据自己的需求来创建自定义函数.下面介绍一下关于shell编程中的自定义函数. 1.函数定义 function hello(){    echo &qu ...

  8. 选中excel中的对象

    2007在查找和选择中点击“选择对象”,然后再全选全个sheet(ctrl+a)就可以看到了. 2010 “选择对象”在  开始——查找和选择——选择对象

  9. bnuoj 4357 传送阵

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=4357 [题意]:在1000个数中选择3个之和是m的倍数,可能有多种选择方案,请输出标号排序最小的一组 ...

  10. 归档 NSKeyedArchiver

    复杂对象无法象 NSString,NSArray等简单对象一样直接通过 writeToFile 实现持久化,当对复杂对象进行持久化时需要将其转化为 NSData (归档),但获取数据时,将 NSDat ...