Могу ли я получить обратную связь для этой функции strcmp (), которую я реализовал в C? - PullRequest
2 голосов
/ 24 октября 2010

Я изучаю C.

Я нахожу, что хорошо изучаю программирование, когда пытаюсь что-то делать и получаю отзывы от известных программистов на языке.

Я решил написать свой strcmp()функция, просто потому что я думал, что смогу:)

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

Я пытался заставить его работать, увеличивая указатель в состоянии while, но не мог понять, как это сделать return.Я собирался написать код C , чтобы сделать как можно больше в одной строке:)

Могу ли я получить отзывы от известных программистов на C?Можно ли улучшить этот код?У меня есть вредные привычки?

Спасибо.

Ответы [ 6 ]

3 голосов
/ 24 октября 2010

Если вы хотите сделать все в операторе while, вы можете написать

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

Лично я не большой поклонник этого стиля программирования - читатели все равно должны мысленно «распаковать» порядок операций, пытаясь понять его (и выяснить, если код содержит ошибки или нет). Ошибки памяти особенно коварны в C, где перезапись памяти на один байт выше или раньше, где вы должны вызывать всевозможные необъяснимые сбои или ошибки намного позже, в отличие от первоначальной причины.

Современные стили программирования на С подчеркивают правильность, последовательность и дисциплину больше, чем краткость. Функции кратких выражений, такие как операции до и после приращения, изначально были способом заставить компилятор генерировать лучший машинный код, но оптимизаторы могут легко сделать это сами в наши дни.

Как пишет @sbi, я бы предпочел const char * аргументы вместо простых char * аргументов.

2 голосов
/ 24 октября 2010
  1. Функция не изменяет содержимое a и b. вероятно, следует объявить об этом, указав указатель на строку const.
  2. Большинство стилей C гораздо более краткие, чем стили многих других языков, но не пытайтесь быть слишком умными. (В вашем коде с несколькими условиями ANDed в условиях цикла, я не думаю, что есть способ поместить увеличение там, так что это даже не вопрос стиля, а правильности.)
1 голос
/ 24 октября 2010

Вы можете найти это интересное, от 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;
}
1 голос
/ 24 октября 2010

Я не знаю, потому что когда положить как можно больше, это считается в стиле C ... Я скорее ассоциирую (обфусцированный) Perl с этим ..

Пожалуйста, НЕ делайте этого. Лучше всего сделать одну команду на строку. Вы поймете, почему, когда вы попытаетесь отладить свой код:)

Для вашей реализации: мне это кажется вполне подходящим, но я бы поставил условие, что * b также не равно '\ 0', потому что вы не можете знать, что a всегда больше, чем b ... В противном случае вы рискуете чтение в нераспределенной памяти ...

0 голосов
/ 25 октября 2010

Эта функция не будет работать, если пределы (без знака) char равны или превышают пределы int из-за целочисленного переполнения.

Например, если вы скомпилируете его на DSP с 16-битным символом с ограничениями 0 ... 65536 и 16-битным int с пределами -32768 ... 32767, тогда, если вы попытаетесь сравнить строки вроде "/ uA640" и "A" результат будет отрицательным, что не соответствует действительности.

Это экзотическая и странная проблема, но она появляется, когда вы пишете универсальную реализацию.

0 голосов
/ 25 октября 2010

Очень тонкая ошибка: strcmp сравнивает байты, интерпретированные как unsigned char, но ваша функция интерпретирует их как char (что подписано в большинстве реализаций). Это приведет к сортировке не-ascii символов до ascii, а не после.

...