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

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

Войти
Регистрация
Восстановить пароль
 
D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
#1

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

09.11.2012, 13:33. Просмотров 644. Ответов 13
Метки нет (Все метки)

При использовании следующего оператора вывода в поток:
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);
А это вообще функция с неопределенным количеством аргументов, которые тоже должны вычислятся слева на право по смещению указателя на размер типа следующего аргумента...
Может кто-нибудь все-таки объяснит как это все реализовано?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2012, 13:33     Вывод в поток и операция инкремента / декремента
Посмотрите здесь:

Ассоциативность инкремента декремента - C++
Всем привет. Вот такую табличку недавно нашел - http://ru.cppreference.com/w/cpp/language/operator_precedence Почему префиксный...

Использование инкремента(Декремента) - C++
Есть три кнопки и три индикатора(лампочки). Если нажимаю кнопку-1 тогда включается лампочка нажимаю еще раз выключается. Если по одному...

Операторы инкремента и декремента - C++
Создайте в классе Circle префиксный и постфиксный операторы инкремента и декремента, воздействующие только на член-данное радиус itsRadius.

Постфиксная и префиксная форма инкремента и декремента. - C++
Само задание: Написать программу с примерами постфиксной и префиксной формами инкремента и декремента. Число вводится с клавиатуры. ...

Префиксные и постфиксные операции инкремента и декремента + наследование - C++
Дано: Два класса(Counter и CountDn), следует при помощи наследования добавить функцию постфиксных операций. На то, что я набросал выдает...

Перегрузка оператора инкремента/декремента через friend - C++
Нужно реализовать перегрузку унарного оператора через friend. Что я пытаюсь сделать: friend void operator -- ();//prototype void...

Операции инкремента и декремента (префиксная и постфиксная версия). Подскажите. - C++
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; int main () { setlocale(LC_ALL,...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 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.
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
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.
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
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
09.11.2012, 14:08     Вывод в поток и операция инкремента / декремента #6
Вот Вам интересный пример =)
C++
1
cout <<(n+=5)<<' '<<n++<<' '<<--n<<endl;
Результат: 14 9 15
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.
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
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
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 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.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
09.11.2012, 14:32     Вывод в поток и операция инкремента / декремента #11
Собственно, если заранее было известно, что это UB, то в чем суть топика? Объяснить, как конкретный компилятор разрулил это UB?
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,363
09.11.2012, 14:37     Вывод в поток и операция инкремента / декремента #12
Цитата Сообщение от D.E.S.P.E.R.O. Посмотреть сообщение
А какой компилятор?
А в данном случае это без разницы. Undefined behavior оно такое undefined..... :-) Не только на разных компиляторах, но даже на сборках Debug и Release одного и того же компилятора могут получаться совершенно разные результаты. Ибо undefined.....
DiffEreD
1429 / 766 / 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++
Смотрите, написал я прогаммку в Ц++, вот отрывок от неё: ...int main () { int a,b,c,k; a=100;b=2;c=4; cout &lt;&lt; &quot;Operand 2=2&quot;; for...

Операция Инкремента. Объясните пожалуйста - C++
Здравствуйте, кто может Объясните как ведет себя операция &quot;Инкремента&quot; внутри выражения. Ниже представлен простейший пример. Вопрос...

Задача на перестановку операция сложегия, вычитания. инкремента и т.д. - C++
Есть код: #include&lt;iostream&gt; using namespace std; int main() { int a,b=20; for(a=0,a&lt;b;a--)

Вывод в файловый поток - C++
проверьте код // ooooo.cpp: определяет точку входа для консольного приложения. // #include &quot;stdafx.h&quot; #include &lt;iostream.h&gt; ...

Объясните пожалуйста вывод в поток - C++
#include &lt;iostream&gt; using namespace std; int main(int argc, char** argv) { int x = 0; int y = 0; if (x++ &amp;&amp; y++)...


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

Или воспользуйтесь поиском по форуму:
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     Вывод в поток и операция инкремента / декремента
Ответ Создать тему
Опции темы

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