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

Вывод в поток и операция инкремента / декремента - C++

Восстановить пароль Регистрация
 
D.E.S.P.E.R.O.
 Аватар для D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 13:33     Вывод в поток и операция инкремента / декремента #1
При использовании следующего оператора вывода в поток:
C++
1
2
int n = 10;
cout << n++ << ' ' << n << ' ' << --n << endl;
получил такой странный вывод:
9 10 10
Я знаю, что в принцыпе это undefined behavior и зависит от реализации компилятора, но все же... Результат схож с вычислением этих переменных при передаче в функция в VS, где вычисление выражений реализовано с права на лево, но ведь вывод в поток - это перегруженый оператор <<, то есть функция с одним параметром, возвращающая ссылку на поток.
Что еще печальнее, вывод аналогичен использованию:
C++
1
printf("%d %d %d\n", m++, m, --m);
А это вообще функция с неопределенным количеством аргументов, которые тоже должны вычислятся слева на право по смещению указателя на размер типа следующего аргумента...
Может кто-нибудь все-таки объяснит как это все реализовано?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11837 / 6816 / 771
Регистрация: 27.09.2012
Сообщений: 16,908
Записей в блоге: 2
Завершенные тесты: 1
09.11.2012, 13:48     Вывод в поток и операция инкремента / декремента #2
Приоритет операций Вам о чем-нибудь говорит?
Сначала выполняется --n, потом вызов cout, потом n+1, потом cout два раза.

Что касается второго случая, то сначала --m, потом вызов printf (m при этом равен m-1), потом m++

Добавлено через 5 минут
Разбейте вот так:
C++
1
2
3
cout <<n++<<' ';
cout<<n;
cout<<' '<<--n<< endl;
А вот так везде будет n:
C++
1
2
cout <<n++<<' ';
cout<<n<<' '<<--n<< endl;
D.E.S.P.E.R.O.
 Аватар для D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 13:57  [ТС]     Вывод в поток и операция инкремента / декремента #3
Цитата Сообщение от Croessmah Посмотреть сообщение
Что касается второго случая, то сначала --m, потом вызов printf (m при этом равен m-1), потом m++
Но почему тогда вывод точно такой же, как и с использованием потока? Ведь printf() вызывается с агрументом m - 1?


Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
2
3
1 cout <<n++<<' ';
2 cout<<n;
3 cout<<' '<<--n<< endl;
У Вас здесь точно все так? Ведь вывод совсем другой?
Oberok
 Аватар для Oberok
5 / 5 / 0
Регистрация: 11.03.2011
Сообщений: 40
09.11.2012, 14:00     Вывод в поток и операция инкремента / декремента #4
По моему тут дело не в приоритете операций а в использовании префиксного постфиксного инкремента.
Я думаю что объяснить такое поведение можно так:
Вы просто используете в первом вызове постфиксную версию инкремента i++, а в конце префиксную версию декремента --i.
Постфиксная версия работает следующим образом:
сначала возвращается старое значение, а затем прибавляется единица(вывели 10 прибавили единицу).
Далее выводится уже увеличенное на единицу значение(11).
И в конце используется префиксная форма декремента, которая сначала инкрементирует значение, а потом возвращает его( отняли единицу вывели значение 10).
А вывод как положено производится слева направо.
D.E.S.P.E.R.O.
 Аватар для D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 14:08  [ТС]     Вывод в поток и операция инкремента / декремента #5
Цитата Сообщение от Oberok Посмотреть сообщение
сначала возвращается старое значение, а затем прибавляется единица(вывели 10 прибавили единицу).
Далее выводится уже увеличенное на единицу значение(11).
И в конце используется префиксная форма декремента, которая сначала инкрементирует значение, а потом возвращает его( отняли единицу вывели значение 10).
А вывод как положено производится слева направо.
Но выводиться 9 10 10. Если предположить, что операторы выполняються по порядку с учитыванием приоритета, то должно было быть 9 9 10:
C++
1
2
3
cout << --n <<' ';
cout << n++;
cout << ' ' << n << endl;
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11837 / 6816 / 771
Регистрация: 27.09.2012
Сообщений: 16,908
Записей в блоге: 2
Завершенные тесты: 1
09.11.2012, 14:08     Вывод в поток и операция инкремента / декремента #6
Вот Вам интересный пример =)
C++
1
cout <<(n+=5)<<' '<<n++<<' '<<--n<<endl;
Результат: 14 9 15
Oberok
 Аватар для Oberok
5 / 5 / 0
Регистрация: 11.03.2011
Сообщений: 40
09.11.2012, 14:14     Вывод в поток и операция инкремента / декремента #7
Честно не знаю, у меня этот код выводит как и следовало ожидать 10 11 10.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using std::cout;
using std::endl;
 
int main()
{
  
  int n = 10;
  cout << n++ << ' ' << n << ' ' << --n << endl;
 
 
  system("PAUSE");
  return 0;
}
А этот 15 15 15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using std::cout;
using std::endl;
 
int main()
{
  int n = 10;
  
  cout <<(n+=5)<<' '<<n++<<' '<<--n<<endl; 
 
  system("PAUSE");
  return 0;
}
D.E.S.P.E.R.O.
 Аватар для D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 14:15  [ТС]     Вывод в поток и операция инкремента / декремента #8
Цитата Сообщение от Croessmah Посмотреть сообщение
Результат: 14 9 15
Использую VS 2008. У меня вывело 15 9 15!

Добавлено через 30 секунд
Цитата Сообщение от Oberok Посмотреть сообщение
Честно не знаю, у меня этот код выводит как и следовало ожидать 10 11 10.
А какой компилятор?
Oberok
 Аватар для Oberok
5 / 5 / 0
Регистрация: 11.03.2011
Сообщений: 40
09.11.2012, 14:20     Вывод в поток и операция инкремента / декремента #9
Dev C++, QtCreator
Вот небольшая статья на тему инкремента и декремента.
http://cppstudio.com/uchebniki/yazyk...ekrementa-v-s/
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11837 / 6816 / 771
Регистрация: 27.09.2012
Сообщений: 16,908
Записей в блоге: 2
Завершенные тесты: 1
09.11.2012, 14:21     Вывод в поток и операция инкремента / декремента #10
Цитата Сообщение от D.E.S.P.E.R.O. Посмотреть сообщение
Использую VS 2008. У меня вывело 15 9 15!
у меня 2012 вывел 14 9 15.
mingw - 15 9 15
I.M.
 Аватар для I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
09.11.2012, 14:32     Вывод в поток и операция инкремента / декремента #11
Собственно, если заранее было известно, что это UB, то в чем суть топика? Объяснить, как конкретный компилятор разрулил это UB?
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
09.11.2012, 14:37     Вывод в поток и операция инкремента / декремента #12
Цитата Сообщение от D.E.S.P.E.R.O. Посмотреть сообщение
А какой компилятор?
А в данном случае это без разницы. Undefined behavior оно такое undefined..... :-) Не только на разных компиляторах, но даже на сборках Debug и Release одного и того же компилятора могут получаться совершенно разные результаты. Ибо undefined.....
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.11.2012, 15:26     Вывод в поток и операция инкремента / декремента #13
Что нибудь про точки следования слыхали? :http://alenacpp.blogspot.com/2005/11...ce-points.html
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2012, 15:39     Вывод в поток и операция инкремента / декремента
Еще ссылки по теме:

C++ Перегрузка оператора инкремента/декремента через friend
C++ Задача на перестановку операция сложегия, вычитания. инкремента и т.д.
Ассоциативность инкремента декремента C++

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

Или воспользуйтесь поиском по форуму:
D.E.S.P.E.R.O.
 Аватар для D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 15:39  [ТС]     Вывод в поток и операция инкремента / декремента #14
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что нибудь про точки следования слыхали?
Ценная информация! Спасибо! В принципе, тему можно закрывать!
Yandex
Объявления
09.11.2012, 15:39     Вывод в поток и операция инкремента / декремента
Ответ Создать тему
Опции темы

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