为什么strcmp()在输入相等时返回0?

时间:2009-02-27 16:22:43

标签: c

当我调用C字符串比较函数时,这样:

strcmp("time","time")

返回0,表示字符串不相等。

有谁能告诉我为什么C实现似乎这样做?我认为如果相等,它将返回非零值。我很好奇我看到这种行为的原因。

7 个答案:

答案 0 :(得分:25)

strcmp返回一个词汇差异(或者我称之为“短路串行字节比较器”?:-))你给出的两个字符串作为参数。 0表示两个字符串相等

正值意味着s1将在字典中的s2之后。

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

因此,当比较明显不同的“时间”和“金钱”时,你的非零值,即使有人会说时间就是金钱! : - )

答案 1 :(得分:12)

像这样的实现的好处是你可以说

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 :(得分:6)

函数通常为常见 - 或者一种情况 - 返回零,对于特殊情况,非零。采用main函数,通常在成功时返回零,并且在失败时返回一些非零值。精确的非零值表示出了什么问题。例如:内存不足,没有访问权限或其他内容。

在你的情况下,如果字符串是相等的,那么除了字符串包含相同的字符之外,没有理由为什么它是相等的。但如果它们不相等,那么第一个可以更小,或者第二个可以更小。让它返回1表示相等,0表示较小,2表示较大,我认为会有点奇怪。

你也可以用减法来考虑它:

return = s1 - s2

如果s1“按字典顺序”减去,那么它将给出一个负值。

答案 3 :(得分: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(true)而对于不等的字符串则返回0(false),则无法使用它来获取方向(即多么不同,哪一个更大),因此无法将其用作排序函数。

我不知道你对C有多熟悉。上面的代码使用了一些C最令人困惑的概念 - 指针算法,指针重铸和函数指针 - 所以如果你不理解其中的一些代码,那就不要不用担心,你会及时到达那里。在那之前,你会在StackOverflow上提出很多有趣的问题。 ;)

答案 4 :(得分: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);
}

以K&amp; R的方式优雅[编辑:有点]。这里的重点(通过正确的代码越来越模糊(显然我应该已经足够好),这就是return语句的方式:

   return (*q1 - *q2);

自然地根据字符值给出比较结果。

答案 5 :(得分:2)

有三种可能的结果:字符串1出现在字符串2之前,字符串1出现在字符串2之后,字符串1与字符串2相同。重要的是将这三个结果分开; strcmp()的一个用途是对字符串进行排序。问题是你想如何为这三个结果赋值,以及如何保持事物的一致性。您还可以查看qsort()和bsearch()的参数,这些参数需要比较strcmp()的函数。

如果你想要一个字符串相等函数,对于相等的字符串,它将返回非零值,对于非相等的字符串,它将返回零,与c的规则一起使用true和false。这意味着无法区分字符串1是在字符串2之前还是在字符串2之后。对于int或您要注意的任何其他C数据类型,有多个真值,但只有一个是假的。

因此,有一个有用的strcmp()为字符串相等性返回true将需要对语言的其余部分进行大量更改,这根本不会发生。

答案 6 :(得分:0)

我想它只是对称性:-1如果更少,0如果相等,1如果更多。