Поиск конца строки: * s ++ VS * s затем s ++ - PullRequest
2 голосов
/ 01 февраля 2010

Я пишу простую программу конкатенации строк.

Программа работает так, как я ее опубликовал. Однако я сначала написал его, используя следующий код, чтобы найти конец строки:

while (*s++)
    ;

Однако этот метод не сработал. Строки, которые я передал ему, не были правильно скопированы. В частности, я попытался скопировать «abc» в переменную char [], которая содержала «\ 0».

Из чтения книги C K & R похоже, что она должна работать. Эта компактная форма должна предпринимать следующие шаги.

  1. * с сравнивается с '\ 0'
  2. s указывает на следующий адрес

Так почему же это не работает? Я собираю с gcc на Debian.

Я обнаружил, что эта версия работает:

strncat(char *s, const char *t, int n)
{
    char *s_start = s;

    while (*s)
        s++;

    for ( ; n > 0 && *t; n--, s++, t++)
        *s = *t;

    *(s++) = '\0';

    return s_start;
}

Заранее спасибо.

Ответы [ 5 ]

15 голосов
/ 01 февраля 2010

После окончания while (*s++);, s указывает на символ после нулевого терминатора. Примите это во внимание в следующем коде.

6 голосов
/ 01 февраля 2010

Проблема в том, что

 while (*s++)
     ;

Всегда Увеличивает s, даже когда s равно нулю (* s равно false)

 while (*s)
    s++;

увеличивает значение s только тогда, когда * s отлично от нуля

поэтому первый из них будет указывать s на первый символ после первого \ 0, а второй - на s, указывая на первый \ 0.

4 голосов
/ 01 февраля 2010

Есть разница. В первом случае s будет указывать на позицию после '\ 0', а во втором остановится прямо на '\ 0'.

2 голосов
/ 01 февраля 2010

Как сказал Джон Ноллер, в конце цикла он будет указывать на местоположение после NULL. НО Нет необходимости жертвовать производительностью ради правильного решения. Взгляните сами:

while (*s++); --s;

Должен сделать свое дело.

0 голосов
/ 01 февраля 2010

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

...