2009-02-27 143 views
11

當我做給C字符串調用比較函數是這樣的:爲什麼strcmp()在其輸入相等時返回0?

strcmp("time","time")

它返回0,這意味着該字符串不相等。

誰能告訴我爲什麼C實現似乎這樣做?如果相等,我會認爲它會返回一個非零值。我很好奇我看到這種行爲的原因。

+0

時間=金錢直接 - 你必須首先使用單位轉換! – 2009-02-27 16:28:55

+4

讚揚誰將這個垃圾郵件問題重新編入可能對新手有用的東西。我仍然不願意爲此投票,以免它鼓勵OP再次發佈這樣的肚子。 – rmeador 2009-02-27 17:04:03

+3

@remeador:謝謝,但不要侮辱OP。 – GEOCHET 2009-02-27 17:14:48

回答

22

strcmp返回您給出的兩個字符串作爲參數的詞法差異(或者我應該稱之爲「short-circuit serial byte comparator」?:-))。 0意味着兩個字符串相等

正值意味着s1將在字典中的s2之後。

負值表示s1在字典中的s2之前。

因此,當比較「時間」和「金錢」時,您的非零值顯然不同,即使人們會說時間就是金錢! :-)

3

你似乎想strcmp像(假設的)工作

int isEqual(const char *, const char *) 

可以肯定,這將是真實的整數結果的「零是假的」的解釋,但它會複雜化因爲在確定兩個字符串不一樣的情況下,你仍然需要知道哪些是「較早」出現的。

而且,我懷疑是常見的實現看起來像

int strcmp(const char *s1, const char *s2){ 
    const unsigned char *q1=s1, *q2=s2; 
    while ((*q1 == *q2) && *q1){ 
     ++q1; ++q2; 
    }; 
    return (*q1 - *q2); 
} 

這是[編輯:還挺]優雅在A K & [R的一種方式。最重要的一點(這是越來越多的得到正確的代碼遮蔽(顯然我應該離開不夠好孤單))就是這樣return語句:

return (*q1 - *q2); 

這給比較的結果自然來講字符值。

5

對於常見的或者特殊情況下返回零的函數和特殊情況下非零的函數是很常見的。採用主函數,通常在成功時返回零,而失敗則返回非零值。精確的非零值表示出了什麼問題。例如:內存不足,沒有訪問權限或別的東西。

在你的情況下,如果字符串相等,那麼沒有理由爲什麼它是平等的,而不是字符串包含相同的字符。但是,如果它們不相等,那麼第一個可以更小,或者第二個可以更小。讓它等於1返回1,更小的0和更大的2會讓我覺得很奇怪。

你也可以考慮一下減法方面:

return = s1 - s2 

如果S1是「字典順序」少,那麼它會給爲負值。

0

我想這是簡單地爲對稱:-1,如果少,0如果相等,1,如果更多。

10

關於這樣一個實現的好處是你可以說

if(strcmp(<stringA>, <stringB>) > 0) // Implies stringA > stringB 
if(strcmp(<stringA>, <stringB>) == 0) // Implies stringA == stringB 
if(strcmp(<stringA>, <stringB>) < 0) // Implies stringA < stringB 
if(strcmp(<stringA>, <stringB>) >= 0) // Implies stringA >= stringB 
if(strcmp(<stringA>, <stringB>) <= 0) // Implies stringA <= stringB 
if(strcmp(<stringA>, <stringB>) != 0) // Implies stringA != stringB 

注意0的相比如何蘊涵的比較完全匹配。

2

有三種可能的結果:串1串自帶2之前,串1串來後2,串1是一樣的字符串2.重要的是要保持這三個不同的結果; strcmp()的一個用途是對字符串進行排序。問題是你想如何爲這三個結果賦值,以及如何保持事物的一致性。您也可以查看qsort()和bsearch()的參數,它們需要與strcmp()類似的比較函數。

如果你想要一個字符串相等功能,它會爲相等的字符串和非等零字符串返回非零,用C對真假規則一起去。這意味着將無法區分字符串1是在字符串2之前還是之後。對於一個int或任何其他C類型的數據,您只需要指定一個值,但只有一個爲真。

因此,具有有效的strcmp()傳回真正的字符串是否相等將需要大量更改語言的休息,這根本不會發生的。

4

另一個原因strcmp()返回它確實是這樣,它可以直接在標準庫函數qsort()使用,讓您排序字符串數組代碼:

#include <string.h> // for strcmp() 
#include <stdlib.h> // for qsort() 
#include <stdio.h> 

int sort_func(const void *a, const void *b) 
{ 
    const char **s1 = (const char **)a; 
    const char **s2 = (const char **)b; 
    return strcmp(*s1, *s2); 
} 

int main(int argc, char **argv) 
{ 
    int i; 
    printf("Pre-sort:\n"); 
    for(i = 1; i < argc; i++) 
     printf("Argument %i is %s\n", i, argv[i]); 
    qsort((void *)(argv + 1), argc - 1, sizeof(char *), sort_func); 
    printf("Post-sort:\n"); 
    for(i = 1; i < argc; i++) 
     printf("Argument %i is %s\n", i, argv[i]); 
    return 0; 
} 

這個小示例程序對其進行排序參數ASCIIbetically(有些人會稱之爲詞法)​​。 Lookie:

$ gcc -o sort sort.c 
$ ./sort hi there little fella 
Pre-sort: 
Argument 1 is hi 
Argument 2 is there 
Argument 3 is little 
Argument 4 is fella 
Post-sort: 
Argument 1 is fella 
Argument 2 is hi 
Argument 3 is little 
Argument 4 is there 

如果strcmp()回到1(真)平等串和0(假)的不相等的,就不可能用它來獲得程度方向不平等(即如何不同的,哪一個更大),因此不可能將它用作排序功能。

我不知道你對C是多麼熟悉。上面的代碼使用了一些C最令人困惑的概念 - 指針算術,指針重鑄和函數指針 - 所以如果你不明白某些代碼,別擔心,你會及時到達那裏。在此之前,您將在StackOverflow上提出很多有趣的問題。 ;)

相關問題