关于C#:为什么strcmp()在输入相等时返回0?


Why does strcmp() return 0 when its inputs are equal?

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

strcmp("time","time")

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

有人能告诉我为什么C实现看起来要这样做吗?如果相等的话,我想它会返回一个非零值。我很好奇看到这种行为的原因。


strcmp返回一个词法差异(或者我应该称它为"短路串行字节比较器")?:-)作为参数提供的两个字符串。0表示两个字符串相等

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

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

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


像这样的实现的好处在于

1
2
3
4
5
6
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的比较如何与含义中的比较完全匹配。


对于公共或一种类型的情况,函数通常返回零;对于特殊情况,函数通常返回非零。以主函数为例,它通常在成功时返回零,而在失败时返回一些非零的值。精确的非零值表示出了什么问题。例如:内存不足,没有访问权限或其他内容。

在您的例子中,如果字符串相等,那么除了字符串包含相同的字符之外,没有理由它是相等的。但是如果它们不相等,那么第一个可以更小,或者第二个可以更小。如果它等于1,小于0,大于2,我觉得有点奇怪。

你也可以用减法来思考:

1
return = s1 - s2

如果s1的"词典编纂"较少,那么它将给出一个负值。


另一个原因是它的strcmp()返回码是否可以直接使用操作系统,这是在标准库函数qsort(),让你一个字符串数组排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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:
"
);
    for(i = 1; i < argc; i++)
        printf("Argument %i is %s
"
, i, argv[i]);
    qsort((void *)(argv + 1), argc - 1, sizeof(char *), sort_func);
    printf("Post-sort:
"
);
    for(i = 1; i < argc; i++)
        printf("Argument %i is %s
"
, i, argv[i]);
    return 0;
}

这个小示例程序:(一asciibetically将其所受的呼叫lexically)。看:

1
2
3
4
5
6
7
8
9
10
11
12
$ 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()返回(TRUE)是平等的1字符串和0(false)将是不可能的。inequal,它使用它来获取学位或不等式(即不同方向的知识,它是一个更大)之间的两个字符串,因此它不可能使用它制作的排序功能。

我不知道你是熟悉与C代码使用上述的一些最confusing概念C的指针的指针和函数的四则运算,recasting分-所以,如果你不明白这是一些代码,放心,你有没有时间。直到永远,你会有很多有趣的问题来问在线的计算器。);


你似乎希望strcmp像(假设的)一样工作

1
int isEqual(const char *, const char *)

要确保对整数结果的"零即假"解释是正确的,但这会使排序逻辑复杂化,因为在确定两个字符串不相同之后,您仍然需要了解"较早"出现的字符串。

此外,我怀疑一个常见的实现看起来像

1
2
3
4
5
6
7
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&R的方式,这是[编辑:有点]优雅。这里重要的一点是返回语句的方式(这一点越来越被代码的正确性所蒙蔽(显然我应该单独留下足够好的代码)):

1
   return (*q1 - *q2);

这就自然地给出了字符值的比较结果。


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

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

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


我想这只是为了对称:如果小于1,等于0,大于1。