Is this the only return value for strcmp() in C?
我正在学习C,目前正在学习字符串处理。从我正在学习的地方,
This is a function which compares two strings to find out whether they
are same or different. The two strings are compared character by
character until there is a mismatch or end of one of the strings is
reached, whichever occurs first. If the two strings are identical,
strcmp( ) returns a value zero. If they’re not, it returns the numeric
difference between the ASCII values of the first non-matching pairs of
characters.
有一个示例程序,这是我的问题是 -
1 2 3 4 5 6 7 8 9 10 11 |
我在我的Windows(64位)机器上运行Dev-C ++上的这个程序,得到了这个输出 -
现在,这本书给出的输出为
In the first call to strcmp( ), the two strings are identical—"Jerry"
and"Jerry"—and the value returned by strcmp( ) is zero. In the second
call, the first character of"Jerry" doesn't match with the first
character of"Ferry" and the result is 4, which is the numeric
difference between ASCII value of ‘J’ and ASCII value of ‘F’. In the
third call to strcmp( )"Jerry" doesn’t match with"Jerry boy",
because the null character at the end of"Jerry" doesn’t match the
blank in"Jerry boy". The value returned is -32, which is the value of
null character minus the ASCII value of space, i.e., ‘\0’ minus ‘ ’,
which is equal to -32.
为了确认这本书的内容,我将这段代码添加到我的程序中,只是为了验证J和F之间的ASCII差异:
然后我相应地在输出中得到了这个 -
1 2 | Ascii value of J is 74 Ascii value of F is 70 |
这是根据书中所说的,然而,正如你所看到的,我得到不同的j和k值,也就是说,当字符串不匹配时。我确实在SO上查找了类似的问题,并得到了其中的一些,但是对于不同的输出(当它返回
这里的问题似乎有些类似,问题描述包含有关
The strcmp() and strncmp() functions return an integer less than,
equal to, or greater than zero if s1 (or the first n bytes thereof) is
found, respectively, to be less than, to match, or be greater than s2
在其中一个答案中,我遇到了这个记录
The strcmp() function shall compare the string pointed to by s1 to the
string pointed to by s2.The sign of a non-zero return value shall be determined by the sign of
the difference between the values of the first pair of bytes (both
interpreted as type unsigned char) that differ in the strings being
compared.RETURN VALUE
Upon completion, strcmp() shall return an integer greater than, equal
to, or less than 0, if the string pointed to by s1 is greater than,
equal to, or less than the string pointed to by s2, respectively.
因此,在阅读了所有这些之后,我倾向于认为无论使用的实现/平台如何,
我的理解是正确的吗?
C语言规范是用英语编写的文档。
标准化委员会的成员仔细选择他们的话,允许实施者做出自己的实施选择。
在某些硬件(或实现)上,返回任何整数(遵守规范的约束)可能比仅返回-1,0,1更快(或更简单或更小的代码)(就像dvm的答案中提出的函数一样)。 FWIW,musl-libc的
BTW,使用GCC和GNU libc(例如在大多数Linux系统上),
尝试编译以下函数(在文件
1 2 |
启用优化并查看汇编代码。在我的Debian / Sid / x86-64上使用GCC 4.9.1,用
你应该关心可移植代码,因此你不应该期望一个特定的值(只要你的供应商的
还阅读有关未定义的行为,这是一个相关的想法:语言规范是自愿不精确的,以允许各种实现者做不同的实现选择
Upon completion, strcmp() shall return an integer greater than, equal to, or less than 0, if the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2, respectively.
你写道:
So, after reading all this, I'm inclined to think that 0, 1 or -1 are the only possible outcomes the strcmp() function.
为什么?确切地说,未指定返回整数的实际值,仅指定其符号。
以下是来自Apple的libc在C中的
1 2 3 4 5 6 7 8 | int strcmp(const char *s1, const char *s2) { for ( ; *s1 == *s2; s1++, s2++) if (*s1 == '\0') return 0; return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); } |
FreeBSD的libc实现:
1 2 3 4 5 6 7 8 | int strcmp(const char *s1, const char *s2) { while (*s1 == *s2++) if (*s1++ == '\0') return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); } |
这是GNU libc的实现,它返回字符之间的差异:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int strcmp (p1, p2) const char *p1; const char *p2; { const unsigned char *s1 = (const unsigned char *) p1; const unsigned char *s2 = (const unsigned char *) p2; unsigned char c1, c2; do { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0') return c1 - c2; } while (c1 == c2); return c1 - c2; } |
这就是为什么我读过的大多数比较都是用
在这种情况下的含义:
-
Zero (0)表示字符串相等。 -
Negative (-1或任何其他)表示第一个字符串较少。 -
Positive (1或任何其他)表示第一个字符串更多。