2

我正在学习C。

当我尝试一些事情并从该语言的成熟程序员那里收到反馈时,我发现我学习编程很好。

我决定编写自己的strcmp()函数,只是因为我认为我可以:)

int strcompare(char *a, char *b) {
    while (*a == *b && *a != '\0') {
        a++;
        b++;
    }
    return *a - *b;
}

我试图通过whilereturn. 我想要C 风格的代码,尽可能多地在一行上做 :)

我可以从成熟的 C 程序员那里得到一些反馈吗?这段代码可以改进吗?我有什么坏习惯吗?

谢谢。

4

6 回答 6

3

如果你想在 while 语句中做所有事情,你可以写

while (*a != '\0' && *a++ == *b++) {}

我个人并不是这种编程风格的超级粉丝——读者在试图理解它时无论如何都需要在心理上“解包”操作顺序(并弄清楚代码是否有错误)。内存错误在 C 语言中特别隐蔽,在其中覆盖内存超过或超过一个字节的地方可能会在很久以后导致各种莫名其妙的崩溃或错误,远离最初的原因。

现代风格的 C 编程强调正确性、一致性和纪律性,而不是简洁性。简洁的表达式特性,如前增量和后增量操作,最初是让编译器生成更好的机器代码的一种方式,但现在优化器可以很容易地自己做到这一点。

正如@sbi 所写,我更喜欢const char *参数而不是简单的char *参数。

于 2010-10-24T12:29:54.833 回答
2
  1. 该函数不会改变aand的内容bconst它可能应该通过指向字符串的指针来宣布这一点。
  2. 大多数 C 风格都比许多其他语言的风格简洁得多,但不要试图太聪明。(在您的代码中,在循环条件中有几个条件与,我认为没有办法在其中添加增量,所以这甚至不是风格问题,而是正确性问题。)
于 2010-10-24T12:24:43.360 回答
1

我不知道,因为什么时候尽可能多地被认为是 C 风格......我宁愿将(混淆)Perl 与它联系起来......

请不要这样做。最好的办法是每行一个命令。当您尝试调试代码时,您会明白为什么:)

对你的实现:对我来说似乎很好,但我会设置 *b 也不是 '\0' 的条件,因为你不知道 a 总是大于 b ...否则你可能会读到 unallocated记忆...

于 2010-10-24T12:23:15.027 回答
1

您可能会发现这很有趣,来自eglibc-2.11.1. 它与您自己的实现没有太大区别。

/* Compare S1 and S2, returning less than, equal to or
   greater than zero if S1 is lexicographically less than,
   equal to or greater than S2.  */
int
strcmp (p1, p2)
     const char *p1;
     const char *p2;
{
  register const unsigned char *s1 = (const unsigned char *) p1;
  register const unsigned char *s2 = (const unsigned char *) p2;
  unsigned reg_char c1, c2;

  do
    {
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0')
    return c1 - c2;
    }
  while (c1 == c2);

  return c1 - c2;
}
于 2010-10-24T12:26:13.433 回答
0

一个非常微妙的错误:strcmp比较解释为的字节unsigned char,但您的函数将它们解释为char(在大多数实现上签名)。这将导致非 ascii 字符在 ascii 之前而不是之后排序。

于 2010-10-24T21:02:34.960 回答
0

如果由于整数溢出, (insigned) char 的限制等于或大于 int 的限制,则此函数将失败。

例如,如果你在 DSP 上编译它,它有 16 位字符,限制为 0...65536 和 16 位整数,限制为 -32768...32767,那么如果你尝试比较像“/uA640”和“A”这样的字符串结果将是否定的,这是不正确的。

这是一个奇异而奇怪的问题,但是当您编写通用实现时就会出现。

于 2010-10-24T22:48:49.483 回答