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

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

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

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

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

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

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

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

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

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Croessmah
Эксперт CЭксперт С++
13237 / 7509 / 847
Регистрация: 27.09.2012
Сообщений: 18,448
Записей в блоге: 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;
0
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;
У Вас здесь точно все так? Ведь вывод совсем другой?
0
Oberok
5 / 5 / 0
Регистрация: 11.03.2011
Сообщений: 40
09.11.2012, 14:00 #4
По моему тут дело не в приоритете операций а в использовании префиксного постфиксного инкремента.
Я думаю что объяснить такое поведение можно так:
Вы просто используете в первом вызове постфиксную версию инкремента i++, а в конце префиксную версию декремента --i.
Постфиксная версия работает следующим образом:
сначала возвращается старое значение, а затем прибавляется единица(вывели 10 прибавили единицу).
Далее выводится уже увеличенное на единицу значение(11).
И в конце используется префиксная форма декремента, которая сначала инкрементирует значение, а потом возвращает его( отняли единицу вывели значение 10).
А вывод как положено производится слева направо.
0
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;
0
Croessmah
Эксперт CЭксперт С++
13237 / 7509 / 847
Регистрация: 27.09.2012
Сообщений: 18,448
Записей в блоге: 3
Завершенные тесты: 1
09.11.2012, 14:08 #6
Вот Вам интересный пример =)
C++
1
cout <<(n+=5)<<' '<<n++<<' '<<--n<<endl;
Результат: 14 9 15
0
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;
}
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.
А какой компилятор?
0
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/
0
Croessmah
Эксперт CЭксперт С++
13237 / 7509 / 847
Регистрация: 27.09.2012
Сообщений: 18,448
Записей в блоге: 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
0
I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
09.11.2012, 14:32 #11
Собственно, если заранее было известно, что это UB, то в чем суть топика? Объяснить, как конкретный компилятор разрулил это UB?
0
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
09.11.2012, 14:37 #12
Цитата Сообщение от D.E.S.P.E.R.O. Посмотреть сообщение
А какой компилятор?
А в данном случае это без разницы. Undefined behavior оно такое undefined..... :-) Не только на разных компиляторах, но даже на сборках Debug и Release одного и того же компилятора могут получаться совершенно разные результаты. Ибо undefined.....
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.11.2012, 15:26 #13
Что нибудь про точки следования слыхали? :http://alenacpp.blogspot.com/2005/11...ce-points.html
1
D.E.S.P.E.R.O.
9 / 9 / 0
Регистрация: 12.03.2009
Сообщений: 110
Завершенные тесты: 1
09.11.2012, 15:39  [ТС] #14
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что нибудь про точки следования слыхали?
Ценная информация! Спасибо! В принципе, тему можно закрывать!
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2012, 15:39
Привет! Вот еще темы с ответами:

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

Операция инкремента и декримента на С++ - 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--)


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

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

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