strcmp函数实现及分析

最近看C,看到strcmp函数,对它的实现原型不很清楚,于是到网上搜。网上算法一大堆,看了很多代码后自己做了一下总结

 strcmp函数是C/C++中基本的函数,它对两个字符串进行比较,然后返回比较结果,函数形式如下:
int strcmp(const char* str1, const char* str2);
其中str1和str2可以是字符串常量或者字符串变量,返回值为整形。返回结果如下规定:
① str1小于str2,返回负值或者-1(VC返回-1);                   
② str1等于str2,返回0;
③ str1大于str2,返回正值或者1(VC返回1);

strcmp函数实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着 比较第二个字符然后第三个字符等等。无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'/0'为止,就能得出结果。strcmp算法的可以有多种,不过我觉的可以把这么多算法分为两种,一种是利用减法运算判断结果,另一种是利用比较运算(==)得出结果。

减法运算的实现的代码如下:

[cpp] view
plain
copy

  1. int strcmp(const char* str1, const char* str2)  
  2. {  
  3.     int ret = 0;  
  4.     while(!(ret=*(unsigned char*)str1-*(unsigned char*)str2) && *str1)  
  5.     {  
  6.         str1++;  
  7.         str2++  
  8.     }  
  9.   
  10.   
  11.     if (ret < 0)  
  12.     {  
  13.         return -1;  
  14.     }  
  15.     else if (ret > 0)  
  16.     {  
  17.         return 1;  
  18.     }  
  19.     return 0;  
  20. }  

这个函数要注意一下几点
①使用*(unsigned char*)str1而不是用*str1。这是因为传入的参数为有符号数,有符号字符值的范围是-128~127,无符号字符值的范围是0~255,而字符串的ASCII没有负值,若不转化为无符号数这回在减法实现时出现错误。
例如 str1的值为1,str2的值为255。
作为无符号数计算时ret = -254,结果为负值,正确
作为有符号数计算时ret = 2,结果为正值,错误

②While循环中ret=*(unsigned char*)str1-*(unsigned char*)str2) && *str1,最后与上str1也可以换成str2,因为前面已经做了相减,无论哪个先为‘\0’都会退出。因为最后与上str1是为了判断str1是否结束,即是否为‘\0’。

③这个函数没有判断参数为NULL时的情况,所以当传入NULL时程序会崩溃。网上看别人说商业化代码都会在调用strcmp前先判断是否为NULL,所以可以不用判断NULL;我在VC6上测试string.h中的strcmp(NULL,NULL),程序也会崩溃。这里可以根据实际情况来决定。

若要判断NULL按下面方法更改代码,可以在这个函数最前面加入断言

assert((NULL != str1) && (NULL != str2))
但要注意断言assert 是仅在Debug 版本起作用的宏,是在Debug时做的无害测试。若想在Release 版也可
以判断NULL,那我们必须用别的代码来判断。
可以在程序前面加入if判断
if ((NULL != str1) && (NULL != str2))
{
return 0;
}
我用CFree 5测试sting.h中的strcmp(NULL,NULL),程序返回值为0(strcmp(NULL,str1)崩溃),这里我们可以返回其他的值如 -2。
我们也可以在函数前面加入while判断
while ((NULL != str1) && (NULL != str2))
{
//strcmp实现代码
}
return 0;
利用while就可以把每个字符都进行判断。

利用比较运算(==)算法如下

[cpp] view
plain
copy

  1. int strcmp(const char* str1, const char* str2)  
  2. {  
  3.     while ((*str1) && (*str1 == *str2))  
  4.     {  
  5.         str1++;  
  6.         str2++;  
  7.     }  
  8.   
  9.   
  10.     if (*(unsigned char*)str1 > *(unsigned char*)str2)  
  11.     {  
  12.         return 1;  
  13.     }  
  14.     else if (*(unsigned char*)str1 < *(unsigned char*)str2)  
  15.     {  
  16.         return -1;  
  17.     }  
  18.     else  
  19.     {  
  20.         return 0;  
  21.     }    
  22. }  

函数注意点和上面一样,有一点要注意不要为了简洁而写成下面

[cpp] view
plain
copy

  1. int strcmp(const char *str1,const char *str2)  
  2. {  
  3.     while ((*str1) && (*str1++ == *str2++)) //这里++会引起错误  
  4.     {  
  5.     NULL;  
  6.     }  
  7.   
  8.   
  9.     if (*(unsigned char*)str1 > *(unsigned char*)str2)  
  10.     {  
  11.         return 1;  
  12.     }  
  13.     else if (*(unsigned char*)str1 < *(unsigned char*)str2)  
  14.     {  
  15.         return -1;  
  16.     }  
  17.     else  
  18.     {  
  19.         return 0;  
  20.     }   
  21. }  

当str1为abcd,st2为abfd时,由于判断到第三个字符时while推出,而str指针又加了1,str都指向第四个字符输出结果为0,显然这是错误的。

这个函数也可以用for来实现

[cpp] view
plain
copy

  1. int strcmp(const char *str1, const char *str2)  
  2. {  
  3.     for ( ; *str1 == *str2; str1++, str2++)  
  4.     {     
  5.         if (*str1 == '\0')  
  6.         return 0;  
  7.     }  
  8.       
  9.     if (*(unsigned char*)str1 > *(unsigned char*)str2)  
  10.     {  
  11.         return 1;  
  12.     }  
  13.     else if (*(unsigned char*)str1 < *(unsigned char*)str2)  
  14.     {  
  15.         return -1;  
  16.     }  
  17.     //如果只返回正负的话可以用 return *(unsigned char*)str1 - *(unsigned char*)str2;  
  18. }  

转载链接:http://blog.csdn.net/wgenek/article/details/7257435

时间: 2024-09-30 00:49:09

strcmp函数实现及分析的相关文章

PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)_php技巧

本文实例讲述了PHP中strnatcmp()函数"自然排序算法"进行字符串比较用法.分享给大家供大家参考,具体如下: PHP中strnatcmp()函数使用"自然"算法来比较两个字符串(区分大小写),通常在自然算法中,数字 2 小于数字 10.而在计算机排序中,10 小于 2,这是因为 10 中的第一个数字小于 2. strnatcmp()函数的定义如下: strnatcmp(string1,string2) 参数说明: string1  必需.规定要比较的第一个字

js常用系统函数用法实例分析

 这篇文章主要介绍了js常用系统函数用法,实例分析了escape.parseInt.parseFloat.isNaN.isFinite等函数的用法,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了js常用系统函数用法.分享给大家供大家参考. 具体代码如下: 代码如下: <html> <head> </head> <body> <script type="text/javascript"> //1. escap

c语言-strcmp()函数的使用问题

问题描述 strcmp()函数的使用问题 明明相等的两个数组为什么判断相等得到的返回值不是0? 解决方案 strcmp函数的使用strcmp函数的使用的一个坑matlab中strcmp函数的使用 解决方案二: 这个strcmp是自己实现的? 怎么有三个参数 解决方案三: strcmp函数的用法是strcmp(str1,str2),同时字符串要以""结尾,否则不知会比出什么结果 解决方案四: 数组,当参数用后变为指针,但你的数组没有结束符,所以比较了不至6个字符,它会一直比较到遇到字符串

(一)strcmp函数

(一)strcmp函数            strcmp函数是比较两个字符串的大小,返回比较的结果.一般形式是:                    i=strcmp(字符串,字符串);          其中,字符串1.字符串2均可为字符串常量或变量:i   是用于存放比较结果的整型变量.比较结果是这样规定的:   ①字符串1小于字符串2,strcmp函数返回一个负值; ②字符串1等于字符串2,strcmp函数返回零; ③字符串1大于字符串2,strcmp函数返回一个正值;那么,字符中的大

php函数 strcmp函数实例教程

定义和用法 该strcmp ( )函数比较两个字符串. 这个函数返回: 0 -如果这两个字符串相等 " 0 -如果字符串小于字符串 " 0 -如果字符串大于字符串 语法 strcmp(string1,string2) Parameter Description string1 必需的.指定的第一个字串比较 string2 必需的.指定第二个字符串比较 提示和说明注: strcmp ( )函数是二进制安全和区分大小写. 例如 <?php echo strcmp("Hell

python中enumerate函数用法实例分析

  本文实例讲述了python中enumerate函数用法.分享给大家供大家参考.具体分析如下: 今日发现一个新函数 enumerate .一般情况下对一个列表或数组既要遍历索引又要遍历元素时,会这样写: ? 1 2 for i in range (0,len(list)): print i ,list[i] 但是这种方法有些累赘,使用内置enumerrate函数会有更加直接,优美的做法,先看看enumerate的定义: ? 1 2 3 4 5 6 7 def enumerate(collect

python回调函数用法实例分析

  这篇文章主要介绍了python回调函数用法,较为详细的分析了常用的调用方式,并实例介绍了Python回调函数的使用技巧,需要的朋友可以参考下 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用.同步调用是一种阻塞式调用,调用方要等待对方执行完毕 才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它 的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,

Python中threading模块join函数用法实例分析

  本文实例讲述了Python中threading模块join函数用法.分享给大家供大家参考.具体分析如下: join的作用是众所周知的,阻塞进程直到线程执行完毕.通用的做法是我们启动一批线程,最后join这些线程结束,例如: ? 1 2 3 4 5 6 7 8 9 for i in range(10): t = ThreadTest(i) thread_arr.append(t)   for i in range(10): thread_arr[i].start()   for i in ra

javaScript中push函数用法实例分析

  本文实例讲述了javaScript中push函数用法.分享给大家供大家参考.具体分析如下: javaScript 中的 push 方法,将新元素添加到一个数组中,并返回数组的新长度值. arrayObj.push([item1 [item2 [. . . [itemN ]]]]) 参数 arrayObj,必选项.一个 Array 对象. item, item2,. . . itemN, 可选项.该 Array 的新元素. 说明 push 方法将以新元素出现的顺序添加这些元素.如果参数之一为数