Не могу понять одну странность с приоритетом операторов в C++
void mass(int* der, int* a)
{
cout << der << endl; //der = 0009D870
*der = 5;
cout << der << endl; //der = 0009D870
*(der++) = 9; //тут проблема
cout << der << endl; //der = 0009D874 (инкрементируется также и при записи *++der)
}
void main()
{
int* der = new int[2];
der[0] = 3;
der[1] = 3;
mass(der, &der[1]);
cout « der[0] « '\n' « der[1];
}
Если записать так: *(der++), то сначала происходит разыменование, а потом инкремент, несмотря на скобки. Значение элемента der[0] меняется на 5, а потом на 9. Если записать так: *++der, то происходит сначала инкремент, потом разыменование, значение элемента массива der[0] меняется на 5, а der[1] на 9. Почему так происходит?
Приоритет операций в языках С и С++ не имеет прямого отношения к порядку их выполнения. Приоритет операций описывает лишь группировку между операторами и операндами во внешне неоднозначных случаях, т.е. отвечает на вопрос о том, какой оператор относится к какому оператору.
(Формально в С и С++ нет никакого "приоритета операций", а есть только грамматика, которая и задает такую группировку. Так называемый приоритет операций - это лишь упрощенный и более удобный способ запоминания этой группировки.)
Вы также наделяете термин выполняется некоей атомарностью, которой у него на самом нет. У каждого оператора, у каждого подвыражения в С и С++ обычно есть результат и потенциально есть побочные эффекты. Вычисление результата оператора (value computation) - это одна часть процесса выполнения оператора, а материализация его побочных эффектов - это другая часть процесса его выполнения. Эти части выполняются в общем случае независимо друг от друга, в совершено разные моменты времени. То есть выполнение оператора в полном объеме может быть "размазано" по всему процессу вычисления полного выражения.
Если записать так: *(der++), то сначала происходит разыменование, а потом инкремент, несмотря на скобки.
Здесь написана какая-то ерунда. Никакого "сначала происходит разыменование" тут нет и быть не может.
Из-за скобок никакой внешней неоднозначности тут нет: ++ относится к der, а * относится к результату ++. Сначала вычисляется именно результат ++. Так как это постфиксный ++, его результатом должно быть старое значение der. Что вы и наблюдаете.
И совершенно не важно, произошло ли уже изменение значения переменной der в момент применения оператора *. Может произошло, а может нет. Главное, что ++ в качестве результата вернул старое значение и именно старое значение попало на вход оператору *. Это все, что вас должно беспокоить: * применяется к старому значению der. Всякие "сначала" и "потом" вас беспокоить не должны вообще.
Скобки тут ни на что не влияют. Их можно убрать и тогда для правильного понимания внешне неоднозначного выражения придется применить приоритеты. Так как постфиксные операторы всегда обладают бОльшим приоритетом, чем префиксные, выражение *der++ разбирается как *(der++).
Если записать так: *++der, то происходит сначала инкремент, потом разыменование
В этом выражении неоднозначности нет и приоритеты никакой роли не играют вообще. ++ относится к der, а * применен к результату ++.
Опять же, важно тут не то, что выполняется первым, а что вторым, а только то, что результат префиксного ++ - это новое значение der. То есть * должен применяться к увеличенному на 1 значению der.
Здесь, кстати, языки С и С++ формально ведут себя по-разному. Язык С++ гарантирует, что когда оператор * получает на вход увеличенное значение der, сама переменная der тоже уже получила новое значение. А вот язык С такого не гарантирует: оператор * тоже получает на вход увеличенное значение der, но вот было ли к этому моменту уже выполнена модификация самой перменной der - не оговаривается.
int a[3]{};
int* der = a; //der содержит адрес первого элемента массива
int* p = der++;
указатель p тоже содержит адрес первого элемента, но der уже(сразу после выражения) указывает на второй элемент
int* q = ++p;
q указывает на второй элемент, т.е. q == der , так что тут скобки роли не играют, дело в результате постфиксного и префиксного инкремента
Сборка персонального компьютера от Artline: умный выбор для современных пользователей