Понимание C: увеличение указателей - PullRequest
1 голос
/ 28 мая 2011

Я готовлюсь к экзамену по языкам программирования и наткнулся на это (написано на C):

*tp++ = *sp++;

Я понял, что *tp = *sp; может, но здесь, когда указатели увеличиваются? до, после получения значений? в каком порядке? Я ценю ваши ответы

Ответы [ 6 ]

7 голосов
/ 28 мая 2011

Поскольку оператор ++ следует после переменных, значения будут увеличиваться после вычисления выражения.Таким образом, это присвоит значение, на которое в данный момент указано sp, местоположению, на которое в данный момент указано tp, затем увеличит оба указателя.

Если вместо выражения было

*(++tp) = *(++sp)

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

Эти конструкции обычно встречаются внутри циклов.

3 голосов
/ 28 мая 2011

Вы должны быть осторожны, веря слову «после». Это правда, что в этом примере поведение выглядит так, как будто указатели увеличиваются после присваивания, но компилятор C не обязан фактически выполнять действия в таком порядке, так как Пока результат один и тот же.

В частности, есть следующие шаги:

  1. Получить значение sp (назовите его sp0)
  2. Получить значение tp (назовите его tp0)
  3. Рассчитать sp0 + 1 (назовите это sp1)
  4. Рассчитать tp0 + 1 (назовите его tp1)
  5. Хранить sp1 в sp
  6. Магазин tp1 на tp
  7. Используйте sp0 для получения значения (назовите его v)
  8. Используйте tp0 для хранения v

Единственные ограничения порядка - это очевидные ограничения: значения должны быть доступны до их использования. Вы не можете знать и не должны пытаться угадать, какой порядок выберет компилятор. С другой стороны, точка с запятой (терминатор оператора) является «точкой последовательности», сообщающей компилятору о том, что ему нельзя переупорядочивать эффекты через него - если только он не может доказать, что он не меняет результат (но может быть быстрее, например).

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

3 голосов
/ 28 мая 2011
*tp++ = *sp++;

эквивалентно

*tp = *sp;
tp++;
sp++;

, поэтому копирует значение, на которое указывает sp, в местоположение, на которое указывает tp, а затем увеличивает оба указателя.

1 голос
/ 28 мая 2011

В

*tp++ = *sp++;

происходит четыре вещи:

  • приращение tp
  • приращение sp
  • выборказначение в sp перед инкрементом
  • присвоение этого значения в tp перед инкрементом

Пока результат правильный, любой ордер действителен (зависит только от QOI)

  • *tp = *sp; tp++; sp++;
  • savedtp_register = tp; tp++; *savedtp_register = *sp; sp++;
  • savedsp_register = *sp; sp++; *tp = savedsp_register; tp++;
  • ...
1 голос
/ 28 мая 2011

++ - это операторы после приращения, так как они сразу появляются после указателей (а не непосредственно перед); оба указателя увеличиваются после назначения (адресов, на которые нет ссылок).

Это эквивалентно:

*tp = *sp;
tp++;
sp++;
0 голосов
/ 28 мая 2011

Они увеличиваются после того, как адреса указателей равны друг другу. Если вы этого не хотите, вы должны использовать ++*tp и ++*sp.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...