• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C++ std::cout

Object Storage Arubacloud
+3 głosów
1,488 wizyt
pytanie zadane 2 marca 2018 w C i C++ przez Mihost Nowicjusz (240 p.)

Witam,

mam problem/zagwozdkę związaną z obiektem cout.

Dlaczego taki kod:

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()
{
	
	int i = 0;
	cout << i << " " << i << " " << i++ << " " << i << " " << i << endl;

	system("pause");
    return 0;
}

daje na wyjściu: 1 1 0 1 1 ?

Próbowałem używać różnych wariancji (przestawiania tych inkrementatorów) i wtedy wszystko robi się jeszcze dziwniejsze. Nie jestem w stanie zrozumieć dlaczego tak się dzieje.

(Wiem, że takie użycie obiektu cout jest karygodne jednak jestem zmuszony opanować posługiwanie się coutem także w ten sposób)

4 odpowiedzi

+3 głosów
odpowiedź 2 marca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
Kolejność ewaluacji wyrażeń w takim zapisie jest nieokreślona. Więc po prostu nie stosuj takiego zapisu i rozbij tą linijkę na dwa lub więcej (zależnie od tego, co chcesz osiągnąć).
komentarz 2 marca 2018 przez Patrycjerz Mędrzec (192,320 p.)
Mógłbym prosić o jakieś źródła potwierdzające to, co piszesz?
1
komentarz 2 marca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)

Dość podobne zagadnienie na stackoverflow:

https://stackoverflow.com/questions/7718508/order-of-evaluation-of-arguments-using-stdcout

Bardziej szczegółowo ten temat jest opisany tutaj:

http://en.cppreference.com/w/cpp/language/eval_order

Choć według tego, co napisała @Monika90 C++17 definiuje kolejność dla operatora <<, o czym szczerze mówiąc nie wiedziałem. Potwierdzenie tego można znaleźć w linku do cppreference, który podesłałem:

19) In a shift operator expression E1<<E2 and E1>>E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2

komentarz 2 marca 2018 przez Patrycjerz Mędrzec (192,320 p.)
Dzięki.
komentarz 9 czerwca 2018 przez Hiskiel Pasjonat (22,830 p.)
Wiem, że to stary wątek, ale czy na wyjściu nie powinno być  0 0 0 0 1?

Jest to post inkrementacja, a nie pre
komentarz 26 czerwca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
Postinkrementacja jest w trzecim wyrażeniu, więc wynikiem tego wyrażenia będzie 0 (na trzecim miejscu) a efektem ubocznym inkrementacja i. Przy czwartym wyrażeniu i będzie już miało wartość 1.
+3 głosów
odpowiedź 2 marca 2018 przez monika90 Pasjonat (22,940 p.)
edycja 2 marca 2018 przez monika90
Pewnie masz stary kompilator.

Według obowiązującego obecnie standardu, czyli C++17, wynikiem powinno być

0 0 0 1 1

ponieważ, dla operatorów << i >> podwyrażenia są wartościowane od lewej do prawej, dla innych operatorów kolejność może być inna, lub być w ogóle nieokreślona.

Przed C++17 zachowanie tego programu było niezdefiniowane.
+1 głos
odpowiedź 2 marca 2018 przez Eryk Andrzejewski Mędrzec (164,260 p.)
Nie używaj std::system, brr.

U mnie daje wynik 0 0 0 1 1. Przy dwóch pierwszych "wypisaniach" używasz wartości pierwotnej i, czyli 0. Przy kolejnym odwołaniu się do i, wykonujesz na tej zmiennej postinkrementację (czyli najpierw użyj, później zwiększ wartość o 1). Więc przy tym użyciu znowu uzyskujemy wartość zero, ale już przy następnym jest to 1.
komentarz 2 marca 2018 przez Kamil Łydka Stary wyjadacz (13,600 p.)

Dodam, że autor pytania może zaznajomić się z hasłem undefined behaviour. :)

komentarz 2 marca 2018 przez Mihost Nowicjusz (240 p.)
Dokładnie taki sam wynik mam gdy rozdziele sobie tego cout'a na 5 osobnych ( i wiem, że tak powinno się to robić).
Problem polega na tym właśnie, że nie rozumiem dlaczego ja ostrzymuje wynik 1 1 0 1 1.
Wciąż o tym czytam i znalazłem informację, że może być to zachowanie niezdefiniowane przez standard, dlatego daje różne wyniki w różnych kompilatorach. Byłoby świetnie gdyby ktoś mógł to potwierdzić.

 

EDIT: Termin jest mi znany, myślałem jednak, że obiekt cout ma po prostu jakąś magiczną kolejność wykonywania tych wypisań :)
komentarz 2 marca 2018 przez Eryk Andrzejewski Mędrzec (164,260 p.)
Heh, o tym nie pomyślałem ;)
komentarz 26 czerwca 2018 przez MsMaciek123 Pasjonat (24,760 p.)
  komentarz 2 marca przez Mihost Nowicjusz (230 p.)

Dokładnie taki sam wynik mam gdy rozdziele sobie tego cout'a na 5 osobnych ( i wiem, że tak powinno się to robić).
Problem polega na tym właśnie, że nie rozumiem dlaczego ja ostrzymuje wynik 1 1 0 1 1.
Wciąż o tym czytam i znalazłem informację, że może być to zachowanie niezdefiniowane przez standard, dlatego daje różne wyniki w różnych kompilatorach. Byłoby świetnie gdyby ktoś mógł to potwierdzić.

 

EDIT: Termin jest mi znany, myślałem jednak, że obiekt cout ma po prostu jakąś magiczną kolejność wykonywania tych wypisań :)

jakąś na pewno wink

to pewnego rodzaju bug

–4 głosów
odpowiedź 2 marca 2018 przez Beginer Pasjonat (22,110 p.)
A skąd masz pewność, że to musi się udać?  Może nie powinno.

Spróbuj jeszcze opcję: std::cout

Podobne pytania

0 głosów
1 odpowiedź 430 wizyt
pytanie zadane 30 lipca 2022 w C i C++ przez RufinB Obywatel (1,830 p.)
0 głosów
1 odpowiedź 2,601 wizyt
pytanie zadane 25 października 2018 w C i C++ przez XezolPL Obywatel (1,530 p.)

92,568 zapytań

141,424 odpowiedzi

319,632 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...