Post i pre (de/in)krementacja

0

Mogłby mi ktoś wytłumaczyć dlaczego to tak dziwnie działa? Dlaczego dodaje/odejmuje dwa zamiast normalnie jeden, a w następnej próbie wszystko jest już normalnie? Poniżej kod, a tutaj obrazek wyników jakie otrzymuje, gdyby komuś nie chciało się kompilować u siebie:
9e9c3bdc6e.png

		int liczba;
		cout << "Podaj liczbe: ";
		cin >> liczba;

		cout << "Predekrementacja  (--liczba): " << --liczba << "\nPostdekrementacja (liczba--): " << liczba-- << "\nLiczba koncowa: " << liczba << endl << endl;
		cout << "Preinkrementacja  (++liczba): " << ++liczba << "\nPostinkrementacja (liczba++): " << liczba++ << "\nLiczba koncowa: " << liczba << endl << endl;

		cout << "Postdekrementacja (liczba--): " << liczba-- << "\nPredekrementacja  (--liczba): " << --liczba << "\nLiczba koncowa: " << liczba << endl << endl;
		cout << "Postinkrementacja (liczba++): " << liczba++ << "\nPreinkrementacja  (++liczba): " << ++liczba << "\nLiczba koncowa: " << liczba << endl << endl; 
0

tak dziala obiekt cout.
z tego co pamietam (nie jestem tego pewien) operacje najpierw sa wykonywane a pozniej masz wyswietlanie. robilem kiedys eksperymenty z funkcjami ktore cos wyswietlaly i wyszly jakies bzdury

2

Może ci wyświetlić różne rzeczy.
Masz w jednej instrukcji kilkokrotną zmianę jednej liczby.
Zachowanie się programu w takim przypadku to UB.
Podziel każdy wiersz na dwa cout.

1

<< to operator, będący tak naprawdę metodą. Jej argumentem jest string. Na ten string składa się kilka sklejanych ze sobą elementów. Zanim zostanie wywołana metoda (funkcja, procedura), musi być znana wartość jej argumentów. Z tego powodu - a nie z tego powodu, który wymienił fasadin - najpierw robiona jest ewaluacja, a potem wyświetlanie. Ewaluacja jest robiona od lewej do prawej z zachowaniem reguł kolejności działań znanych z matematyki. U Ciebie wychodzi dokładnie odwrotnie, czyli od prawej do lewej, ale to dlatego, że tak naprawdę wywołanie wygląda tak:

Concat(
	Concat(
		"Predekrementacja  (--liczba): ",
		Concat(
			Concat(
				"\nPostdekrementacja (liczba--): ",
				liczba--  // 1) najpierw pobranie wartości (100), potem dekrementacja (99)
			),
			--liczba // 2) najpierw dekrementacja (98), potem pobranie wartości (98)
		)
	),
	Concat(
		"\nLiczba koncowa: " ,
		liczba // 3) wypisanie po dwóch dekrementacjach (98)
	)
);

Concat oznacza umowną funkcję sklejającą argumenty.
Przy czym należy jeszcze założyć, że Twoja wersja kompilatora najpierw ewaluuje argumenty od lewego do prawego, oraz że kompilator rozbił wiele wywołań operatora >> w tej samej linijce w taki, a nie w inny sposób - bo mógł to zrobić na kilka innych (ale na pewno masz to opisane w specyfikacji Twojej wersji kompilatora; inny kompilator może to zrobić inaczej). Z tego powodu unikaj takich operacji zgodnie z tym, co napisał _13th_Dragon.

1 użytkowników online, w tym zalogowanych: 0, gości: 1