Как ++ * ptr ++ будет оцениваться компилятором, если ptr равен ptr первому элементу статического массива? - PullRequest
2 голосов
/ 31 марта 2019

Каков порядок оценки в ++*ptr++?Изменится ли он, когда в операции участвуют указатели и l-значения?

Если приоритет a++ выше *a или ++a, то почему ++*a++ оценивается как первый, возвращающий увеличенное значениезатем изменение указателя, а не изменение указателя, а затем увеличение значения в этом месте.Ссылка для приоритета: https://en.cppreference.com/w/cpp/language/operator_precedence

arr = {9, 99, 999 };
int *ptr = arr;
std::cout << ++*ptr++ << '\t';
std::cout << *ptr;

Я ожидал, что выход будет 100 100, но фактический выход был 10 99.

Ответы [ 4 ]

6 голосов
/ 31 марта 2019

Постфиксный инкремент a++ увеличивает указатель ptr, но возвращает копию ptr перед операцией (см. Разницу между префиксом / postfix).Таким образом, он может быть переписан (как отмечено в ответе Quimby) как ++ (* (ptr ++)) и выглядит следующим образом:

  1. ptr ++: увеличивает ptr так, чтобы он указывал на 99, но возвращает другой указатель, которыйвсе еще указывает на 9
  2. * ptr ++: разыменование, оценивается в 9
  3. ++ * ptr ++: увеличивает значение, на которое указывает скопированный указатель, то есть увеличивает на 9 и возвращает 10

Здесь хорошо объясняется логика пред / постинкрементного увеличения / уменьшения:

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

С: https://en.cppreference.com/w/cpp/language/operator_incdec

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

Операторы Postfix имеют более высокий приоритет, чем префикс, поэтому они BIND туго / сначала так: ++*ptr++ - это то же самое, что и ++(*(ptr++)), что сводится к тому, какой операнд работает с чем.Таким образом, postfix ++ будет применен к вашему указателю 'ptr', но 'после' первой строки std :: cout.Префикс ++ будет работать с разыменованным ptr, так что это все равно:

int arr[] = {9, 99, 999 };
int *ptr = arr;
++(*ptr); // 9+1=10
std::cout << *ptr << '\t';
ptr++; // now ptr points to 99
std::cout << *ptr; 
1 голос
/ 31 марта 2019

Короче говоря, потому что ++*ptr++ переписывается как ++(*(ptr++))

Правила в ссылке достаточно ясны:

  1. Постфикс ++ имеет наивысший приоритет => ++*(ptr++)
  2. Префикс ++ и * имеют одинаковый приоритет, и они ассоциативны справа => ++(*(ptr++))

Выражение также можно разбить на отдельные операторы, например:

arr = {9, 99, 999 };
int *ptr = arr;
int *ptr2 = ptr++;//ptr2 still points to the first element
int val = *ptr2; // 9
int incVal= ++val; // 10

Надеюсь, ясно, что ptr теперь указывает на второй элемент массива, а результатом выражения является увеличенное значение.

0 голосов
/ 31 марта 2019

Поскольку вы используете одномерный массив

++*ptr, относящийся к приращению указателя ptr к 0 элементам массива, после увеличения выходного значения для этого будет 10

Постфикс ++ имеет наивысший приоритет => ++*(ptr++)

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