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

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

strcmp("time","time")

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

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

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

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

负值意味着s1将在字典中的s2之前。

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

你可以说,这样的实现很好用

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

注意与0的比较与暗示中的比较完全匹配。

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

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

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

 return = s1 - s2 

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

strcmp()返回它所执行的代码的另一个原因是它可以直接在标准库函数qsort() ,允许您对字符串数组进行排序:

 #include  // for strcmp() #include  // for qsort() #include  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),那么就不可能用它来获得两者之间的不等式的程度方向 (即多么不同,哪一个更大)字符串,因此无法将其用作排序function。

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

你似乎希望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&R方式。 这里的重点(通过正确的代码越来越模糊(显然我应该留下足够好))是return语句的方式:

  return (*q1 - *q2); 

它在字符值方面自然给出了比较结果。

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

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

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

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