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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
BloodyWo1f
Сообщений: n/a
#1

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

26.06.2013, 19:22. Просмотров 2038. Ответов 42
Метки нет (Все метки)

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.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2013, 19:22
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Постфиксный и префиксный декремент (C++):

Префиксный и постфиксный инкремент - C++
#include &lt;iostream&gt; using namespace std; int main() { int c=0; cout&lt;&lt;с++&lt;&lt;++с&lt;&lt;++с&lt;&lt;с++&lt;&lt;endl; return 0; ...

Как выполняется постфиксный и префиксный инкремент? - C++
Растолкуйте! Обычно, а = с++ толкуется как а = с+1 тогда а = ++с есть а = 1+с Если использовать последнюю запись (а = 1+с),верно...

Инкремент постфиксный и префиксный - принцип работы - C++
Hello World! Нужна ваша помощь, мозг отказывается понимать :wall:! Набрал код: #include &lt;iostream&gt; using namespace std; int...

Потокобезопасен ли префиксный инкремент/декремент? - C++
Потокобезопасен ли префиксный инкремент/декремент? Например такой код: // Объявляем глобальную переменную uint64_t i=0; // Тут...

Поясните как работает постфиксный и префиксный оператор на примере - C++
Здравствуйте. Здесь префиксный понятно, а что если изменить на постфиксный, как код будет работать? vector&lt;int&gt;::size_type...

Постфиксный, и префиксный экземпляры оператора приращения: в чем разница? - C++
постфиксный, и префиксный экземпляры оператора приращения в чем разница? i++ ++i ??

42
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
27.06.2013, 00:08 #31
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Это ты типа доказываешь, что "то утверждение неверно"?
Это я "типа" говорю, что никакого второго уменьшения после вывода на экран нет, выражение вычисляется один раз до вызова функции.

@Croessmah, я не вставил это в цитату, потому что, если верить сноски, то, как я уже писал, выражение ++++++i неявно оценивается компилятором как ++( ++( ++i )), что является UB, отсюда сделал вывод, что и ( --i )-- является UB.
0
ValeryS
Модератор
6651 / 5060 / 470
Регистрация: 14.02.2011
Сообщений: 16,918
27.06.2013, 00:11 #32
Цитата Сообщение от Toshkarik Посмотреть сообщение
std::cout << ( --i )--; раскрывается компилятором как cout.operator<<(( --i )--);, следовательно оно должно быть вычислено до вызова функции. В момент вызова функции постдекремент уже выполнен, а в функцию передается копия.
нехай так
передается копия
что это меняет
C++
1
2
int i=2;
std::cout << ( --i )--;
т.е на экран выведется 1
а в следующей строчке i==0;
при любых компиляторах
где тут неопределенное поведение?
и мне без разницы выведет он переменную а потом уменьшит или создаст копию уменьшит а потом выведет копию
главное результат предсказуем

ты ведь не заморачиваешься
fnc(2+2,5+6);
что сначала выполнится 2+2 или 5+6
главное в функцию уйдут 4 и 11
UB страшны не сами по себе, их в каждой строчке может быть сто штук
а в том что при определенных условиях они могут дать неизвестно что
например
это всегда отработает
C++
1
a=i++;
а это зависит то компилятора
C++
1
i=i++;
0
Croessmah
Эксперт CЭксперт С++
13407 / 7557 / 853
Регистрация: 27.09.2012
Сообщений: 18,590
Записей в блоге: 3
Завершенные тесты: 1
27.06.2013, 00:14 #33
Цитата Сообщение от ValeryS Посмотреть сообщение
а это зависит то компилятора
имхо, эта строчка интересней:
C++
1
foo((i = 10) + i)
0
ValeryS
Модератор
6651 / 5060 / 470
Регистрация: 14.02.2011
Сообщений: 16,918
27.06.2013, 00:21 #34
Цитата Сообщение от Croessmah Посмотреть сообщение
имхо, эта строчка интересней:
даже представить не могу сколько нужно выпить чтобы так написать
это как
C++
1
for (int i=0; i<5; i=i++)
клиент говорят долго возмущался что цикл зацикливается
0
Croessmah
27.06.2013, 00:26
  #35

Не по теме:

Цитата Сообщение от ValeryS Посмотреть сообщение
клиент говорят долго возмущался что цикл зацикливается

Я нарывался на такое:
C++
1
2
3
4
    int endval;
    for(int i=0,endval=0;i<5;++i)
        ++endval;
    std::cout<<endval<<std::endl;
вопрос был очевиден - почему endval не поменялся

0
ValeryS
Модератор
6651 / 5060 / 470
Регистрация: 14.02.2011
Сообщений: 16,918
27.06.2013, 01:20 #36
отвлекли вы меня от работы
начал баловаться
вот они UB
C++
1
2
3
4
5
6
int i = 0;
    std::cout << i++ << i++ << i++<<std::endl;
     i = 0;
    std::cout << ++i << ++i << ++i<<std::endl;
     i = 0;
    std::cout << i << ++i << i++<<std::endl;
результаты
210
333
220
0
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
27.06.2013, 07:17 #37
лурк тоже в теме =)

Добавлено через 7 минут
я на стороне Toshkarik, это UB, однако как я понимаю UB - в рамках разных компиляторов, а не в пределах одного, любопытства ради, можно запустить проверить на 1е9 тестах и посмотреть что будет, имхо ответ всегда будет 1 и тот же
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
27.06.2013, 09:42 #38
Все четко, нету UB в коде.
Вопрос знающим: кто-то смог хорошенько разобраться в определении UB в C++11 (sequenced before, sequenced after, etc)?
0
Croessmah
Эксперт CЭксперт С++
13407 / 7557 / 853
Регистрация: 27.09.2012
Сообщений: 18,590
Записей в блоге: 3
Завершенные тесты: 1
27.06.2013, 09:49 #39
@ForEveR, не разбирался еще, но можно узнать где описано конкретно? Приду с работы, попробую разобраться.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
27.06.2013, 09:53 #40
По ссылке, что я приводил, вроде, есть объяснение.
http://stackoverflow.com/questions/4...equence-points
Начинается примерно в середине.
1
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,926
Записей в блоге: 1
27.06.2013, 12:25 #41
@Toshkarik, я не понимаю о почему ты продолжаешь спорить. А хотя понимаю.
Ты не видишь, что UB это неопределённость ПОРЯДКА ДЕЙСТВИЙ, на которые разложит выражение компилятор. Это не генерация рандомного числа, и не гадание процессора на кофейной гуще.
Но ты всё равно утверждаешь, что
Цитата Сообщение от Toshkarik Посмотреть сообщение
Это undefined behaviour. Значит результат может быть каким угодно.
Нет! не каким угодно,
Код вычисления результата может отличаться на разных компиляторах! Но это будет осмысленный код, соответствующий стандарту.

В классическом примере UB i = ++i + ++i; такая неопределённость имеет место, т.к. этот пример может быть понят несколькими способами

способ 1) tmp=i; tmp++; i = tmp; tmp++; i += tmp;
способ 2) tmp=i; tmp++; tmp++; i = tmp + tmp;
возможно ещё способы...

вот в чём выражена неопределённость! а не в "каком угодно" результате.

В нашем примере cout << ( --i )--;
Есть единственный способ разложить это выражение на действия! i--; tmp=i; i--; cout<<tmp; Вот оно! Отсутствие UB! Все действия определены приоритетом операторов.

Заметь: в отличие от примера i=( --i )--;
Который может быть интерпретирован
или так i--; tmp=i; i--; i=tmp;
или так i--; tmp=i; i=tmp; i--;
то есть не определён вид и порядок действий в этой программе! Но поверь, "какого угодно" результата i=абракадабра1234; ты не получишь!
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
27.06.2013, 12:32 #42
@Kuzia domovenok,
Нет! не каким угодно,
Код вычисления результата может отличаться на разных компиляторах! Но это будет осмысленный код, соответствующий стандарту.
UB есть ничто иное, как то для чего НЕТУ правил в стандарте. Поэтому среди программистов С и С++ вполне распространены толкования UB как "произойти может что угодно", "в прошлый раз выполняющийся код выпил все пиво в моем холодильнике" и так далее. Это нормально. Понятно, что в действительности, систему программа с UB не отфарматирует, за пивом не сгоняет и т.д., ОДНАКО все отдается на откуп компилятора, как он обработает эту ситуацию и обработает-ли вообще - зависит целиком и полностью от разработчиков компилятора, стандарт умывает руки при UB. Так что не стоит спорить на этот счет.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
27.06.2013, 12:32 #43
@Kuzia domovenok, если честно, то мне уже лень что то писать по этому поводу, пусть каждый останется при своем мнении, я свое никому не навязываю.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2013, 12:32
Привет! Вот еще темы с ответами:

Указатели: почему так происходит? Постфиксный и префиксный инкремент - C++
В общем, вот код программы double q; for (int i(0);i&lt;10;i++) { q=i; } cout&lt;&lt;q&lt;&lt;endl; double* d=q; cout&lt;&lt;d&lt;&lt;&quot;...

не работает префиксный оператор в классе - C++
Проблема : не работает &quot;++plus&quot; в &quot;void ClassB::count()&quot; Есть вариант решить это так : поменять &quot;private&quot; на &quot;protected&quot; в обоих классах...

постфиксный инкремент - C++
class Inkrement { Inkrement(){}; Inkrement &amp;operator++(int) { Inkrement temp = *this; ++*this; return temp; ...

Указатель на постфиксный инкремент x - C++
Почему так нельзя делать? int *p = &amp;(x++); Вроде же все ясно должно быть компилятору


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

Или воспользуйтесь поиском по форуму:
43
Yandex
Объявления
27.06.2013, 12:32
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru