Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
BloodyWo1f

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

26.06.2013, 19:22. Показов 5421. Ответов 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.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.06.2013, 19:22
Ответы с готовыми решениями:

Префиксный и постфиксный инкременты
Приветствую всех. Экспериментом установил, что префиксный инкремент переменной стандартного типа возвращает ссылку на эту же уже измененную...

Префиксный и постфиксный инкремент
#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; ...

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

42
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
26.06.2013, 23:27
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Toshkarik Посмотреть сообщение
При вычислении этого выражения переменная изменяется дважды.
и что?
на следующей строчке все в порядке будет
ведь мы здесь не присваиваем
или компилятор выбросит одно уменьшение?

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
у постфиксного выше
всегда думал наоборот
тогда действительно ерунда получается
Не будем так писать
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,538
Записей в блоге: 1
26.06.2013, 23:28
Цитата Сообщение от Toshkarik Посмотреть сообщение
При вычислении этого выражения переменная изменяется дважды.
И что, что изменяется дважды? Вот ты что-то споришь всё, утверждая:
Цитата Сообщение от Toshkarik Посмотреть сообщение
Результат может быть каким угодно.
А давай начнём с того, что при UB программа генерирует не какое-то рандомное значение -12345, а некую последовательность действий, которая для некоторых компиляторов разная, т.к. стандарт не описывает точное поведение в этих случаях.
Так вот ты утверждаешь, что эту программу возможно интерпретировать каким-то иным образом, кроме
Цитата Сообщение от ValeryS Посмотреть сообщение
идет уменьшение
потом вывод на экран ( в поток) вот она точка следования
и потом еще раз уменьшение
Можно поинтересоваться, какие тут могут быть альтернативные действия?
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
26.06.2013, 23:29
@Croessmah, да дело уже даже не в порядке, а в
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.
В данном случае ( --i )-- это и есть expression и в нем не соблюдается value modified at most once, уже и не знаю, что еще добавить, и как еще написать.
0
11 / 11 / 2
Регистрация: 20.05.2011
Сообщений: 71
26.06.2013, 23:35
при
C++
1
cout<< ++i + ++i ;
будет 4,
а значение i=2.
(т.е. сначала выполнятся 2 раза ++, а потом сложатся)

при
C++
1
cout<< i++ + i++;
выведется 0, i = 2;

при
C++
1
cout << ++i + i++;
выведется 2, i =2

делайте простые выводы
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
26.06.2013, 23:41
Цитата Сообщение от razor_ua Посмотреть сообщение
делайте простые выводы
а теперь сделайте так:
C++
1
(i++ - i++)
на разных компиляторах получите разные ответы.
А у Вас получались одинаковые, потому что хоть задом наперед все сделай, все равно будет одинаковый ответ. А вот при разности, ну или при разных подвыражениях будет бо-бо...
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
26.06.2013, 23:52
@Kuzia domovenok, я не занимаюсь исследованием компиляторов, мне это не к чему. Возможно, что все существующие компиляторы оценят это выражения так, как описано в теме. Но это ничего не меняет по отношению к стандарту.

И да, это утверждение не верно:
Цитата Сообщение от ValeryS
потом вывод на экран ( в поток) вот она точка следования
и потом еще раз уменьшение
std::cout << ( --i )--; раскрывается компилятором как cout.operator<<(( --i )--);, следовательно оно должно быть вычислено до вызова функции. В момент вызова функции постдекремент уже выполнен, а в функцию передается копия.

@razor_ua, мда, тут все понятно...
0
11 / 11 / 2
Регистрация: 20.05.2011
Сообщений: 71
26.06.2013, 23:55
мда.... при ВЫЧИТАНИИ сначала выполняется ++ 2 раза, пофиг с какой стороны, и выводится результат отнимания..

а при сложении только 1 инкремент...
теперь ночью будут кошмары сниться )))
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
26.06.2013, 23:57
Цитата Сообщение от Toshkarik Посмотреть сообщение
Но это ничего не меняет по отношению к стандарту.
Что же Вы одно предложение выдернули то из стандарта?
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified(53)
Between the previousand next sequence point a scalar object shall have its stored value modified at most once by the evaluation
of an expression. F
и еще сноска внизу:
(53)The precedence of operators is not directly specified, but it can be derived from the syntax.
То бишь никакого UB, если порядок может быть получен из синтаксиса
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,538
Записей в блоге: 1
27.06.2013, 00:00
Цитата Сообщение от Toshkarik Посмотреть сообщение
std::cout << ( --i )--; раскрывается компилятором как cout.operator<<(( --i )--);, следовательно оно должно быть вычислено до вызова функции. В момент вызова функции постдекремент уже выполнен, а в функцию передается копия.
Это ты типа доказываешь, что "то утверждение неверно"?
Больше похоже наоборот, на подтверждение слов @Croessmah
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
27.06.2013, 00:08
@Toshkarik, UB происходит в данных случаях от того, что в разных компиляторах дерево строится по разному и все зависит от того, в каком порядке это дерево "обходится", а это зависит от реализации. А значит нет однозначного ответа в каком порядке будут выполнены подвыражения. В случае с (--a)-- скобки влияют на построение дерева таким образом, что выполнить по другому просто не получится
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
27.06.2013, 00:08
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Это ты типа доказываешь, что "то утверждение неверно"?
Это я "типа" говорю, что никакого второго уменьшения после вывода на экран нет, выражение вычисляется один раз до вызова функции.

@Croessmah, я не вставил это в цитату, потому что, если верить сноски, то, как я уже писал, выражение ++++++i неявно оценивается компилятором как ++( ++( ++i )), что является UB, отсюда сделал вывод, что и ( --i )-- является UB.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
27.06.2013, 00:11
Цитата Сообщение от 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
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
27.06.2013, 00:14
Цитата Сообщение от ValeryS Посмотреть сообщение
а это зависит то компилятора
имхо, эта строчка интересней:
C++
1
foo((i = 10) + i)
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
27.06.2013, 00:21
Цитата Сообщение от Croessmah Посмотреть сообщение
имхо, эта строчка интересней:
даже представить не могу сколько нужно выпить чтобы так написать
это как
C++
1
for (int i=0; i<5; i=i++)
клиент говорят долго возмущался что цикл зацикливается
0
27.06.2013, 00:26

Не по теме:

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

0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
27.06.2013, 01:20
отвлекли вы меня от работы
начал баловаться
вот они 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
36 / 36 / 2
Регистрация: 28.04.2013
Сообщений: 110
27.06.2013, 07:17
лурк тоже в теме =)

Добавлено через 7 минут
я на стороне Toshkarik, это UB, однако как я понимаю UB - в рамках разных компиляторов, а не в пределах одного, любопытства ради, можно запустить проверить на 1е9 тестах и посмотреть что будет, имхо ответ всегда будет 1 и тот же
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
27.06.2013, 09:42
Все четко, нету UB в коде.
Вопрос знающим: кто-то смог хорошенько разобраться в определении UB в C++11 (sequenced before, sequenced after, etc)?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
27.06.2013, 09:49
@ForEveR, не разбирался еще, но можно узнать где описано конкретно? Приду с работы, попробую разобраться.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
27.06.2013, 09:53
По ссылке, что я приводил, вроде, есть объяснение.
http://stackoverflow.com/quest... nce-points
Начинается примерно в середине.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.06.2013, 09:53

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru