轉自:strcmp函數實現及詳解


strcmp函數是C/C++中基本的函數,它對兩個字符串進行比較,然后返回比較結果,函數形式如下:
int strcmp(constchar*str1,constchar*str2);
其中str1和str2可以是字符串常量或者字符串變量,返回值為整形。返回結果如下規定:
①str1小於str2,返回負值或者-1(VC返回-1);②str1等於str2,返回0;
③str1大於str2,返回正值或者1(VC返回1);
strcmp函數實際上是對字符的ASCII碼進行比較,實現原理如下:首先比較兩個串的第一個字符,若不相等,則停止比較並得出兩個ASCII碼大小比較的結果;如果相等就接着比較第二個字符然后第三個字符等等。無論兩個字符串是什么樣,strcmp函數最多比較到其中一個字符串遇到結束符'/0'為止,就能得出結果。strcmp算法的可以有多種,不過我覺的可以把這么多算法分為兩種,一種是利用減法運算判斷結果,另一種是利用比較運算(==)得出結果。減法運算的實現的代碼如下:

復制代碼
 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     if(ret < 0)
10         return -1;
11     else if(ret > 0) 
12         return 1;
13     return 0;    
14 }
復制代碼

這個函數要注意一下幾點
①使用*(unsignedchar*)str1而不是用*str1。這是因為傳入的參數為有符號數,有符號字符值的范圍是-128~127,無符號字符值的范圍是0~255,而字符串的ASCII沒有負值,若不轉化為無符號數這回在減法實現時出現錯誤。例如str1的值為1,str2的值為255。
作為無符號數計算時ret=-254,結果為負值,正確作為有符號數計算時ret=2,結果為正值,錯誤
②While循環中ret=*(unsignedchar*)str1-*(unsignedchar*)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)){
return0;}
我用CFree5測試sting.h中的strcmp(NULL,NULL),程序返回值為0(strcmp(NULL,str1)崩潰),這里我們可以返回其他的值如-2。我們也可以在函數前面加入while判斷while((NULL!=str1)&&(NULL!=str2)){
//strcmp實現代碼}
return0;

利用while就可以把每個字符都進行判斷。利用比較運算(==)算法如下

復制代碼
 1 int strcmp( const char *str1, const char *str2 )
 2 {
 3     while( (*str1) && ( *str1 == *str2 ) )
 4     {
 5         str1++;
 6         str2++;
 7     }
 8     if( *(unsigned char*)str1 > *(unsigned char*)str2 )
 9         return 1;
10     else if( *(unsigned char*)str1 < *(unsigned char*)str2 )
11         return -1;
12     else
13         return 0;
14 }
復制代碼

 

還有一種for的實現以及一種錯誤的實現。這里不表了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM