Запутанные ответы: один говорит, что *myptr++ сначала увеличивает указатель, другой говорит, что *p++ разыменовывает старое значение указателя.

Буду признателен, если вы проясните это для меня. Вот два недавних вопроса с их принятыми ответами:

1) Что такое разница между *myptr++ и *(myptr++) в C

2) Еще одна последовательность точечный запрос: как работает *p++ = getchar()?

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

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

В нем ясно сказано, что в *p++ разыменовывается строго старый адрес p. У меня мало причин сомневаться в правильности ответа на второй вопрос с самым высоким рейтингом, но, честно говоря, я чувствую, что он противоречит ответу пользователя H2CO3 на первый вопрос. Итак, может ли кто-нибудь объяснить простым и понятным языком, что означает ответ на второй вопрос и как come *p++ разыменовывает старое значение p во втором вопросе. Разве p не должно увеличиваться первым, поскольку ++ имеет более высокий приоритет? Как, черт возьми, старый адрес может быть разыменован в *p++Спасибо.


person Rüppell's Vulture    schedule 29.04.2013    source источник
comment
«Принятый ответ на первый вопрос [...] гласит, что, поскольку ++ имеет более высокий приоритет, чем *, сначала выполняется приращение к указателю myptr, а затем он разыменовывается». Где это сказано?   -  person Pascal Cuoq    schedule 29.04.2013
comment
@PascalCuoq Если в *myptr++ ++ имеет более высокий приоритет, то разве не очевидно, что myptr будет сначала увеличиваться, а затем разыменовываться?   -  person Rüppell's Vulture    schedule 29.04.2013
comment
Когда x++ не находится непосредственно между точками последовательности (скажем, 2 + 3 + *p + x++), вы не знаете, когда увеличивается x. Это может быть любое время между предыдущей точкой следования и следующей точкой следования, независимо от приоритета. Но вы все равно не сможете увидеть разницу, потому что запрещено писать или читать из x в другом месте между одними и теми же точками последовательности.   -  person Pascal Cuoq    schedule 29.04.2013


Ответы (3)


Оператор приращения постфикса имеет более высокий приоритет, чем оператор разыменования, но приращение постфикса на переменная возвращает значение этой переменной до увеличения.

*myptr++

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


Ответ на первый вопрос, на который вы ссылаетесь, не является неправильным, он отвечает на другой вопрос.

Между *myptr++ и *(myptr++) нет никакой разницы, потому что в обоих случаях сначала выполняется приращение, а затем разыменовывается предыдущее значение myptr.

person Praetorian    schedule 29.04.2013
comment
Спасибо. Вы разъяснили очень важный нюанс, который я так долго упускал. - person Rüppell's Vulture; 29.04.2013

Принятый ответ на первый вопрос, краткий и понятный, гласит, что, поскольку ++ имеет более высокий приоритет, чем *,

Верно. Это верно.

сначала выполняется приращение к указателю myptr, а затем он разыменовывается.

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

То, что приоритет ++ выше, чем приоритет косвенности *, говорит о том, что

*myptr++

точно такой же (конечно, не на уровне кода курса), как

*(myptr++)

и это означает, что косвенность применяется к результату

myptr++

часть выражения, старое значение myptr, тогда как (*myptr)++ применит оператор приращения к тому, на что указывает myptr.

Результатом приращения постфикса является старое значение операнда, поэтому

*myptr++ = something;

имеет тот же эффект, что и

*myptr = something;
myptr++;

Когда происходит побочный эффект сохранения увеличенного значения myptr, не указано. Это может произойти до оценки косвенности или после этого, это зависит от компилятора.

person Daniel Fischer    schedule 29.04.2013

В разделе 6.5.2.4 спецификации C обсуждаются постфиксные операторы инкремента и декремента. И второй абзац там в значительной степени отвечает на ваш вопрос:

Результатом постфиксного оператора ++ является значение операнда. В качестве побочного эффекта значение объекта операнда увеличивается (то есть к нему добавляется значение 1 соответствующего типа).
...
Вычисление значения результата выполняется до побочного эффекта обновления сохраненного значения операнда.

Итак, учитывая *myptr++, да, это правда, что часть ++ имеет более высокий приоритет; но приоритет не определяет исключительно ваш результат. Язык определяет это с помощью спецификаций. В этом случае возвращается значение myptr, затем выполняется «побочный эффект» увеличения myptr.

person Mike    schedule 29.04.2013