Форум программистов, компьютерный форум CyberForum.ru

Постфиксный и префиксный декремент - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
BloodyWo1f
Сообщений: n/a
26.06.2013, 19:22     Постфиксный и префиксный декремент #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using std::cout;
int main() 
{
int a=5;
 cout << (--a)-- << " "; 
 cout << a << " ";
 cout << (--a)-- << " "; 
 cout << (--a)-- << " "; 
 cout << a << " ";
system("pause"); 
return 0;
}
Помогите пожалуйста. Не могу понять почему сперва выводит 4 но а=3 потом выводит 2 а потом 0 но а=-1. Почему сначала отнимает 1 а потом 2.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
FireProoF
17 / 17 / 1
Регистрация: 28.10.2012
Сообщений: 190
26.06.2013, 19:36     Постфиксный и префиксный декремент #2
А так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "stdafx.h"
#include <iostream>
using std::cout;
 
int main() 
{
int a=5;
 cout << --(--a) << " "; 
 cout << a << " ";
 cout << --(--a) << " "; 
 cout << --(--a) << " "; 
 cout << a << " ";
system("pause"); 
return 0;
}
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
26.06.2013, 19:43     Постфиксный и префиксный декремент #3
потому что есть разница между постфиксным и префиксным декрементом.

префиксной записью называется та, где оператор стоит перед операндом, --а
постфиксной соответственно наоборот а--

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

в Вашем примере a = 5; cout << (--a)--;

порядок выполнения команд будет следующий

1. присвоить 5 в а
2. выполнить префиксный декремент а (инструкция --а) а = 4
3. вывести а на экран (cout << a) (а = 4 см. предыдущую строку)
4. выполнить постфиксный декремент (инструкция а--) а = 3

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

Добавлено через 4 минуты
для более детального понимания я приведу пример

C++
1
2
3
4
5
6
a[c++] = 5;
 
// эквивалентно 
 
a[c] = 5;
c += 1;
C++
1
2
3
4
5
a[++c] = 5;
 
// эквивалентно 
c += 1;
a[c] = 5;
BloodyWo1f
Сообщений: n/a
26.06.2013, 19:46     Постфиксный и префиксный декремент #4
Огромное спасибо) всё понял.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 19:53     Постфиксный и префиксный декремент #5
Это undefined behaviour. Результат может быть каким угодно.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.06.2013, 22:44     Постфиксный и префиксный декремент #6
Цитата Сообщение от Toshkarik Посмотреть сообщение
Это undefined behaviour. Результат может быть каким угодно.
Никак не могу согласиться. В чём тут проявляется UB?
C++
1
cout << (--a)--
UB возникает при определённых обстоятельствах. А именно (если я правильно понял статью http://alenacpp.blogspot.ru/2005/11/...ce-points.html) это происходит при обращении к значению изменённой переменной до прохождения точки следования.

В данном же случае поведение строго определено скобками и свойствами операторов предекремента/постдекремента.

Ответ:
-Сначала выполнится выражение в скобках.
-Переменная а будет уменьшена на 1 и возвращёно значение а после уменьшения, т.к. ПРЕдекремент.
-Затем значение а будет ещё раз уменьшено вторым оператором --, но на вывод будет возвращено значение а бывшее ДО декремента, т.к. ПОСТдекремент.
-Например, следующая программа выведет "-1 -2"
C++
1
2
3
int a=0;
cout << (--a)-- <<endl;
cout << a         <<endl;
Очевидно, что иногда люди, услышав где-то про классическое
- вопрос: какой результат у выражения i=i++ + i++;?
- ответ: UB
начинают распространять этот ответ на любые подобные(и не совсем подобные) выражения, не задумываясь о настоящих причинах UB или не UB. Так, что вот.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 22:49     Постфиксный и префиксный декремент #7
@Kuzia domovenok, переменная изменяет свое значение больше одного раза в пределах одной точки следования. http://stackoverflow.com/questions/4...equence-points
А именно:
From the above sentence the following expressions invoke Undefined Behaviour.

C++
1
2
3
4
5
6
7
i++ * ++i; // i is modified more than once
i = ++i    // same as above
++i = 2;   // same as above
i = ++i +1 // same as above
++++++i;   //parsed as (++(++(++i)))
 
i = (i,++i,++i); // Undefined Behaviour because there's no sequence point between `++i`(right most) and assignment to `i` (`i` gets modified more than once b/w two SP)
И, поверьте, я знаю, что говорю, а не "где то что то там услышал или прочитал".
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.06.2013, 22:57     Постфиксный и префиксный декремент #8
Цитата Сообщение от Toshkarik Посмотреть сообщение
И, поверьте, я знаю, что говорю, а не "где то что то там услышал или прочитал".
Именно, что ты где-то услышал про
i++ * ++i; // i is modified more than once
i = ++i // same as above
++i = 2; // same as above
i = ++i +1 // same as above
++++++i; //parsed as (++(++(++i)))

i = (i,++i,++i);
И даже не указал, к какому из перечисленных тобой вариантов UB относится обсуждаемый пример. Не удивительно! Ведь внимание! ответ... ни к какому из них!

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Toshkarik Посмотреть сообщение
И, поверьте
не выкайте мне, а то я тоже как начну всем выкать! Ужас!

Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:01     Постфиксный и префиксный декремент #9
Специально для Вас:
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
Добавлено через 2 минуты
Ну и если еще не совсем поняли, то если
++++++i; //parsed as (++(++(++i)))
UB, тогда
Цитата Сообщение от BloodyWo1f Посмотреть сообщение
(--a)--
уж подавно.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
26.06.2013, 23:03     Постфиксный и префиксный декремент #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
Специально для Вас:
только в данном случае она же меняется последовательно, а не как решит компилятор
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:07     Постфиксный и префиксный декремент #11
@Croessmah, не аналогично, так как операция запятая в данном случая является точкой следования.
Если ++++i парсится компилятором как ++( ++i ), и это является UB, то чем лучше ( --i )-- ? В любом случае переменная меняется два раза в одном выражении и в пределах одной точки следования.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
26.06.2013, 23:09     Постфиксный и префиксный декремент #12
Цитата Сообщение от Toshkarik Посмотреть сообщение
и это является UB, то чем лучше ( --i )--
тем, что для вычисления постинкремента нужно сначала вычислить выражение в скобках, иначе имеем постинкремент неизвестного значения, то бишь сначала выполниться выражение в скобках
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,056
26.06.2013, 23:13     Постфиксный и префиксный декремент #13
@Toshkarik,
а по твоему точка следования это только точка с запятой?
@Kuzia domovenok,
Здесь полностью прав(не часто мы с ним соглашаемся)
идет уменьшение
потом вывод на экран ( в поток) вот она точка следования
и потом еще раз уменьшение
никаких разночтений
вот интересная статья
http://alenacpp.blogspot.ru/2005/11/...ce-points.html
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:13     Постфиксный и префиксный декремент #14
@Croessmah, дело не в скобках, а дело в изменении переменной больше одного раза в одном полном выражении, в данном случае в выражениях ++( ++i ); и ( --i )--; переменная меняется два раза, а по стандарту:
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
это UB.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
26.06.2013, 23:14     Постфиксный и префиксный декремент #15
Цитата Сообщение от Toshkarik Посмотреть сообщение
@Croessmah, дело не в скобках, а дело в изменении переменной больше одного раза в одном полном выражении
В данном случае ЯВНО ЗАДАН ПОРЯДОК изменения
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:15     Постфиксный и префиксный декремент #16
@ValeryS, а я разве где то говорил об точке с запятой? Я никому ничего не навязываю, лишь говорю о том, что написано в стандарте. Хотя в новом стандарте вроде как убрали понятие sequence point
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,056
26.06.2013, 23:17     Постфиксный и префиксный декремент #17
@Croessmah,
а вот интересно а так что будет
C++
1
--i--;
и будет ли вообще что то?
у предикремента ведь приоритет выше ?
вопрос чисто академический, ибо так писать не собираюсь
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:18     Постфиксный и префиксный декремент #18
Цитата Сообщение от Croessmah Посмотреть сообщение
В данном случае ЯВНО ЗАДАН ПОРЯДОК изменения
Да причем тут "явно задан порядок" то. При вычислении этого выражения переменная изменяется дважды. Я приводил уже цитату по этому поводу, не я писал стандарт.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
26.06.2013, 23:21     Постфиксный и префиксный декремент #19
Цитата Сообщение от ValeryS Посмотреть сообщение
у предикремента ведь приоритет выше ?
у постфиксного выше
http://ru.cppreference.com/w/cpp/lan...tor_precedence
а значит имеем прединкремент временной переменной

Добавлено через 42 секунды
Цитата Сообщение от Toshkarik Посмотреть сообщение
При вычислении этого выражения переменная изменяется дважды.
Вот тут UB, ибо порядок
(--a) + (a--)
не задан
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2013, 23:23     Постфиксный и префиксный декремент
Еще ссылки по теме:

Перегруженный постфиксный оператор ++ C++
C++ постфиксный инкремент
Инкремент постфиксный и префиксный - принцип работы C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2013, 23:23     Постфиксный и префиксный декремент #20
@ValeryS, этот код не должен компилироваться.
Yandex
Объявления
26.06.2013, 23:23     Постфиксный и префиксный декремент
Ответ Создать тему
Опции темы

Текущее время: 15:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru