Копирование строки в C - PullRequest
       20

Копирование строки в C

7 голосов
/ 09 февраля 2010

Я запутался в этом коде: (http://www.joelonsoftware.com/articles/CollegeAdvice.html)

while (*s++ = *t++);

Какой порядок исполнения? * S = * t сначала выполняется, а затем увеличивается ли каждый из них? Или наоборот?

Спасибо.

РЕДАКТИРОВАТЬ: И что, если это было:

while(*(s++) = *(t++));

и

while(++*s = ++*t);

Ответы [ 7 ]

14 голосов
/ 09 февраля 2010
while (*s++ = *t++);

Из таблицы приоритетов ясно видно, что ++ имеет более высокий приоритет, чем *. Но ++ используется здесь как оператор постинкрементного увеличения, поэтому увеличение происходит после выражения присваивания. Таким образом, сначала происходит *s = *t, затем значения s и t увеличиваются.

EDIT:

while(*(s++) = *(t++));

То же, что и выше. Вы делаете это более явным с использованием скобок. Но помните, что ++ все еще является пост-инкрементом.

while(++*s = ++*t);

Рядом с s есть только один оператор. Таким образом, * применяется первым, и к этому результату применяется ++, что приводит к ошибке lvalue required.

while(*++s = *++t);

Опять просто оператор рядом с s, t. Таким образом, увеличение происходит первым, а затем копируется. Таким образом, мы фактически пропускаем копию первого символа от t до s.

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

Вы правы. * s = * t выполняется сначала, а затем они увеличиваются.

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

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

*s = *t

, затем s ++ и t ++

1 голос
/ 09 февраля 2010

EDIT ::

@ chrisgoyal

Порядок исполнения - неоднозначный термин. Здесь есть две разные вещи. Синтаксический порядок и семантика выражения.

Синтаксически, оператор ++ применяется первым. Если сначала применяется * s, то то, что сказал @Hogan, эквивалентно следующему:

(*s)++ = (*t)++

Что очень отличается от образца Джоэла.

Семантика оператора ++ заключается в том, что он выполняется после выражения.

Надеюсь, это проясняет, что я ела.


На самом деле, s++ и t++ применяются первыми. Не забывайте, что оператор пост-исправления выполняется после выражения. В основном оператор ++ применяется для обоих, , затем выполняется *s = *t.

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

Код: (while *s++ = *t++); примерно эквивалентен:

while (*s = *t) {
    ++s;
    ++t;
}

Второй точно такой же - дополнительные парены ничего не меняют (в данном случае). Чтобы парни могли что-либо делать, они должны быть такими: while ((*s)++ = (*t)++);. Это будет примерно так же, как и в третьем примере (см. Параграф ниже).

Последний пример: while(++*s = ++*t); совершенно другой. Поскольку разыменование (*) ближе к операнду, это разыменовывает операнд и увеличивает результат разыменования, что означает, что он увеличивает то, на что указывает указатель AT, вместо того, чтобы увеличивать сам указатель. В результате это будет копировать первый символ, затем увеличивать его, затем проверять, был ли этот символ ненулевым, и продолжать то же самое, пока он не стал нулевым. Результатом будет то, что и источник, и пункт назначения станут пустыми строками (поскольку первый символ обоих теперь будет нулем, что используется для завершения строк).

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

Итак, есть две формы приращения

++s // increment before using value
s++ // increment after using value

И результат этого может быть разыменован:

*++s // or...
*s++

Это сработало очень хорошо на одной из самых первых машин для запуска C, PDP-11, у которой был режим косвенной адресации регистра, который увеличивал регистр после. В аппаратном обеспечении были доступны следующие операции:

*--s // or
*s++

Вы можете сделать либо

*x++ = *y++; // or
*--x = *--y; // or some combination

И если вы это сделали, вся строка произошла в одной инструкции. Так как // комментарии были введены C99, вы не могли обойтись без моего синтаксиса комментариев.

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

Сначала используется переменная операции Post Post, а затем после ее изменения.

...