为什么 while(*s++ == *t++) 不能用来比较两个字符串

why does while(*s++ == *t++) not work to compare two strings

通过比较两个字符串之间不同的拳头值。

通过分离后缀增量和关系等于运算符来实现:

for (; *s==*t; s++, t++)
    if (*s=='[=10=]')
        return 0;
return *s - *t;

但是,将后缀增量和关系等于运算符分组不起作用(像这样):

while (*s++ == *t++)
    if (*s=='[=11=]')
        return 0;
return *s - *t;

后者总是 returns 0。我认为这可能是因为我们过早地递增指针,但即使在索引 5 处出现的两个字符串存在差异 10 仍然会产生同样的结果。

示例输入: strcomp("hello world", "hello xorld");

return 值: 0

我的直觉是这是因为运算符的优先级,但我并不肯定,如果是这样,我也无法准确指出原因。

感谢您的宝贵时间!

因为在 for 循环中,如果条件(*s==*t 在你的情况)是错误的。但是在您的 while 循环中,在这种情况下也会调用增量,因此对于 strcomp("hello world", "hello xorld"),两个指针最终都指向字符串中的 os。

由于在测试中总是递增st,所以如果字符串相等,则应参考s[-1]s[-1]t[-1] 以防它们不同。

另请注意,顺序由比较确定为unsigned char

这是修改后的版本:

int strcmp(const char *s, const char *t) {
    while (*s++ == *t++) {
        if (s[-1] == '[=10=]')
            return 0;
    }
    return (unsigned char)s[-1] - (unsigned char)t[-1];
}

根据 LL chux 的评论,这是一个完全符合非二进制补码表示的反常架构的实现 and/or CHAR_MAX > INT_MAX:

int strcmp(const char *s0, const char *t0) {
    const unsigned char *s = (const unsigned char *)s0;
    const unsigned char *t = (const unsigned char *)t0;

    while (*s++ == *t++) {
        if (s[-1] == '[=11=]')
            return 0;
    }
    return (s[-1] > t[-1]) - (s[-1] < t[-1]);
}

每个人都给出了正确的建议,但仍然很难在比较表达式中内联那些递增运算符,并做一些奇怪的事情。

下面只是感觉比较简单易读。任何指针都不会递增或递减到无效地址。

while ((*s == *t) && *s)
{
    s++;
    t++;
}
return *s - *t;

除了已经很好地回答了减法过程中的错误偏移量之外,为了完整性:

*s, *t 为负数时,

*s - *t; 不正确。

标准 C 库指定字符串函数比较 就好像 charunsigned char。因此,当字符为负数时,通过 char * 减去的代码会给出错误的答案。

For all functions in this subclause, each character shall be interpreted as if it had the type unsigned char (and therefore every possible object representation is valid and has a different value). C17dr § 7.24.1 3

int strcmp(const char *s, const char *t) {
  const unsigned char *us = (const unsigned char *) s;
  const unsigned char *ut = (const unsigned char *) t;
  while (*us == *ut && *us) {
    us++;
    ut++;
  }
  return (*us > *ut) - (*us < *ut);
}

此代码还解决了 的非 2 补码访问 -0 和 char 范围超过 int