Постинкремент или присвоение в таблице приоритетов операций C ++ - PullRequest
2 голосов
/ 10 марта 2019

Я наткнулся на https://en.cppreference.com/w/cpp/language/operator_precedence

На графике я вижу, что оператор постинкрементного увеличения (++) намного выше оператора присваивания (=).

enter image description here

Однако я знаю, что

int a[] = {10,20};
int* b = &a[0];

*(b++) = 5;

cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]

Я всегда принимаю за грант, что постинкремент происходит после оператора присваивания.Однако, если я буду следовать диаграмме приоритетов операций, то не будет ли происходить постинкрементное выполнение до операции =?Разве ответ не должен быть a={10, 5}, а не a={5, 20}?

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

«Приоритет» вводит в заблуждение.В общем случае он имеет мало общего с порядком оценки (что происходит первым), но вместо этого определяет, какой операнд каждого оператора используется для оценки.Но давайте рассмотрим ваш пример.

*(b++) = 5;

Это означает, что 5 должно быть присвоено lvalue слева.А начиная с C ++ 17, мы знаем, что 5 оценивается полностью до *(b++).До этого они могли оцениваться в любом порядке.

Теперь b++ имеет значение "приращения b, но оценивается как его предыдущее значение".Так что b++ может привести к тому, что приращение произойдет до назначения, да, но значение (b++) является адресом до приращения.И именно поэтому b обновляется, чтобы указывать на следующий элемент, изменяя текущий, в одном выражении.

1 голос
/ 10 марта 2019

Постинкрементное увеличение (b++) увеличивается b, , а затем возвращает предыдущее значение b.

Предварительное увеличение (++b) с шагом b, *Затем 1010 * возвращает новое значение b.

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

Например:

#include <iostream>

int main() {
  int a[] = {10, 20};
  int *b = &a[0];

  *(++b) = 5;

  std::cout << a[0] << std::endl;
  std::cout << a[1] << std::endl;
  std::cout << *b << std::endl;
}

Выводит следующий вывод:

10
5
5
...