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. Cursor--游标

    游标--cursor['kɜːsə]   概念:                         在执行SQL语句时,Oracle服务器将分配一个内存区域,不仅存储这个语句,还存储语句的结果 — 称为 ...

  2. Linux C 程序 文件属性,文件删除(15)

    dup ,dup2,fcntl,ioctl系统调用 . dup ,dup2 函数 int dup(int oldfd) int dup(int oldfd , int newfd) dup用来复制参数 ...

  3. ASP.NET的WebFrom组件LinkButton使用

    在ASP.NET的WebForm组件中的LinkButton组件也是一个服务器端的组件,这个组件有点类似于HTML中的<A>标识符.它的主要作用是就是在ASP.NET页面中显示一个超链接. ...

  4. SQL Server数据库连接类SQLHelper.cs

    using System; using System.Collections.Generic; using System.Text; using System.Configuration; using ...

  5. [OC] UITabBarController

    1. New CocoaTouch class -> Select Objective C -> named RootViewController 2. Disable APC error ...

  6. Android类库常用类库一览

    在Android SDK中包括很多包文件,通过了解这些包的功能也有助于了解可以开发的功能. 在Android类库中,各种包写成android.*的方式,重要包的描述如下所示: android.app ...

  7. C# Winform程序请求管理员权限

    如果你的Winform程序需要管理员权限才能正常执行,请加入如下代码: static class Program { /// <summary> /// 应用程序的主入口点. /// &l ...

  8. WPF中的文字修饰

    我们知道,文字的修饰包括:空心字.立体字.划线字.阴影字.加粗.倾斜等.这里只说划线字的修饰方式,按划线的位置,我们可将之分为:上划线.中划线.基线与下划线.如图: 从上至下,分别为上划线(Overl ...

  9. Android中获取应用程序(包)的大小-----PackageManager的使用(二)

    通过第一部分<<Android中获取应用程序(包)的信息-----PackageManager的使用(一)>>的介绍,对PackageManager以及 AndroidMani ...

  10. Oracle修改表空间大小

    在向orale数据库导入数据的时候报 ORA-01658: 无法为表空间 XXX中的段创建 INITIAL 区错误. Oracle我在创建表空间的时候初始化大小为200M,当数据库中数据量达到这个值, ...