Разница между & ++ x и & x ++ - PullRequest
6 голосов
/ 08 апреля 2020

Хотя на этот вопрос можно где-то ответить, и я не смог его найти.

Ниже написано первое утверждение, а второе - нет? ПОЧЕМУ?

int main() {
  int x = 1, y = 2;

  int *p = &++x; // First
  std::cout << "*p = " << *p << std::endl;

  // int *q = &x++; // Second
  // std::cout << "*q = " << *p << std::endl;
}

1 Ответ

4 голосов
/ 08 апреля 2020

В этом объявлении

int *p = &++x;

используются два унарных оператора: преинкремент ++ и получение адреса. Унарные операторы выполняются справа налево. Поэтому сначала переменная x увеличивается, и ее адрес присваивается указателю p. Результатом оператора предварительного увеличения является lvalue увеличенного объекта.

Так, например, такое выражение, как это

++++x;

, является правильным.

В этом объявлении

int *p = &x++;

используется оператор postfix post-increment ++ и унарный оператор взятия адреса. Операторы Postfix имеют более высокий приоритет по сравнению с унарными операторами. Поэтому сначала выполняется постинкремент. Его результатом является временный объект, который имеет значение переменной x перед увеличением. Затем выполняется оператор получения адреса.

Однако вы не можете взять адрес временного объекта. Поэтому для этого объявления компилятор выдаст ошибку.

В противоположность оператору предварительного приращения такое выражение, как это

x++++;

, недопустимо.

Из C ++ 17 Стандарт (5.3.2 Увеличение и уменьшение)

1 Операнд префикса ++ изменяется путем добавления 1 или устанавливается в значение true, если это bool (это использование не рекомендуется). Операндом должно быть изменяемое значение l. Тип операнда должен быть арифметическим c типом или указателем на полностью определенный тип объекта. Результатом является обновленный операнд; это lvalue , и это битовое поле, если операнд является битовым полем ....

И (5.2.6 Увеличение и уменьшение)

1 Значением выражения postfix ++ является значение его операнда. [Примечание: полученное значение является копией исходного значения - примечание конца] ...

В C обе операции дают значение. Так что в C вы тоже не можете писать

++++x;
...