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

为什么strcmp()的输入相等时返回0?,c,C,当我调用C字符串比较函数时,如下所示: strcmp(“时间”,“时间”) 它返回0,这意味着字符串不相等 有人能告诉我为什么C实现似乎会这样做吗?如果相等,我认为它将返回一个非零值。我很好奇看到这种行为的原因。strcmp返回您作为参数给出的两个字符串的词法差异(或者我应该称之为“短路串行字节比较器”?:-)。 0表示两个字符串相等 正值表示在字典中s1位于s2之后 负值表示在字典中s1在s2之前 因此,在比较“时间”和“金钱”时,你的非零值是明显不同的,即使有人会说时间就是金钱!:-) 你似

当我调用C字符串比较函数时,如下所示:

strcmp(“时间”,“时间”)

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


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

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

正值表示在字典中s1位于s2之后

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


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

你似乎想让strcmp像一个(假设的)机器一样工作

为了确保整数结果的“zero is false”解释是正确的,但这会使排序逻辑复杂化,因为在确定两个字符串不相同之后,您仍然需要了解“更早”出现的字符串

此外,我怀疑一个常见的实现

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风格。这里最重要的一点(由于代码的正确性(显然我本应该离开这里)越来越模糊)是return语句的方式:

   return (*q1 - *q2);

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

对于函数来说,一般情况下返回零,对于特殊情况返回非零是很常见的。以main函数为例,它通常在成功时返回零,在失败时返回一些非零值。精确的非零值表示出现了什么问题。例如:内存不足、没有访问权限或其他问题

在您的例子中,如果字符串是相等的,那么除了字符串包含相同的字符外,没有其他原因可以说明它是相等的。但是如果它们不相等,那么第一个可以更小,或者第二个可以更小。让它返回1表示相等,0表示较小,2表示较大,我认为这有点奇怪

你也可以从减法的角度来考虑:

return = s1 - s2

如果s1在“词典编纂”上更少,那么它将给出一个负值

我想这只是为了对称:-1如果更小,0如果相等,1如果更多。

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

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
if(strcmp(,)>0)//表示stringA>stringB
if(strcmp(,)==0)//表示stringA==stringB
if(strcmp(,)<0)//表示stringA=0)//表示stringA>=stringB

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

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


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

另一个原因是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;
}
如果
strcmp()
对于相等的字符串返回
1
(true),对于不相等的字符串返回
0
(false),则不可能使用它来获得两个字符串之间不相等的程度或方向(即差异有多大,哪个更大),从而无法将其用作排序函数


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

time!=直接用钱——你必须先进行单位换算。@Remador:我想问多少愚蠢的笑话就问多少。对那些感兴趣的人来说,最初的问题是:“为什么strcmp(“时间”、“金钱”)返回0而不是非零?”。编辑:返回非零而不是0。strcmp()不做词法比较,它只是比较每个字符的值,直到出现差异或两个字符串都终止。我可以发誓我读过说strcmp()的文档进行词汇比较,但一些快速的谷歌搜索表明费鲁乔是正确的。。。它会在某个时候改变吗?嗯,我很确定这是一个词汇比较!我认为它会随着“词汇”的定义而改变。我也看到strcmp()被称为“词汇”比较器,尽管它显然没有考虑不同的本地化、排序等。也许最好称之为“短路串行字节比较器”。它只是使用每个字符的ASCII值进行比较,其顺序如下:ABCDE…ABCDE。词法比较会对它们进行排序,如:AaBbCcDdEe。该“公共实现”不会离开缓冲区(通过空终止吗?)我看不出它将如何返回0…我认为如果您到达\0,您必须终止循环:)u
#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;
}
$ 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