C++: wynik działania +++

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

C++: wynik działania +++

Post autor: Enkidu »

Dlaczego kompilator po kodzie:

Kod: Zaznacz cały

#include <iostream>
 
using namespace std;
 
int main() {
        int a = 0;
         int b = 4;
         int c = 9;
         a = b+++c;
         cout << a;
        return 0;
}
wyrzuca mi sumę, czyli w tym wypadku 13? Myślałem, że inkrementacja ma większy priorytet.
And you know the thing about chaos, Harvey?
It's fair!
VGT
Piegowaty Guziec
Piegowaty Guziec
Posty: 21
Rejestracja: 20 lut 2011, 21:47
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Iława
Kontakt:

Odp: C++: wynik działania +++

Post autor: VGT »

Obstawiam, ze sumowanie wykonało się w ten sposób:

Kod: Zaznacz cały

a = b++ + c;
Post inkrementacja odbywa się po pobraniu wartosci b do sumowania.

Jeśli wpiszesz to tak:

Kod: Zaznacz cały

a = b + ++c;
Wtedy pre inkrementacja zwiększy c przed sumowaniem.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Ha! ale tutaj w ogóle nie było inkremetacji, ani post ani pre, doszło do zwykłego zsumowania zmiennych.
And you know the thing about chaos, Harvey?
It's fair!
VGT
Piegowaty Guziec
Piegowaty Guziec
Posty: 21
Rejestracja: 20 lut 2011, 21:47
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Iława
Kontakt:

Odp: C++: wynik działania +++

Post autor: VGT »

Enkidu pisze:Ha! ale tutaj w ogóle nie było inkremetacji[..]

A założymy się? ;)

Kod: Zaznacz cały

#include <iostream>

using namespace std;

int main() {
        int a = 0;
         int b = 4;
         int c = 9;
         a = b+++c;
         cout << a << endl << b;
        return 0;
}
Skompiluj i zobacz co się stało ze zmienną b.
Chyba nie do końca rozumiesz, jak działa inkrementacja i spodziewasz się jej gdzie indziej, niż wystąpiła.

PS. Ewentualnie może wprowadzasz siebie w błąd korzystając z działania +++?
Działanie inkrementacji, to ++, który można umieścić przed lub za zmienną, czyli ++a lub a++
To co ty stworzyłeś, to połączenie inkrementacji z sumowaniem, którego nawet nigdy nie robiłem i zaskoczyło mnie, że kompilator to wykonał.
Ale skoro wykonał to właśnie nie masz kontroli, czy jest to post inkrementacja zmiennej b, czy pre inkrementacja zmiennej c.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Ja z tego nie korzystam, tylko miałem na teście.

A rzeczywiście, postinkrementacja zaszła :D Ale ja cały czas pytam o wynik działania - czemu najpierw sumuje a potem dopiero inkrementuje?

Kod: Zaznacz cały

a=++b+a;
W tym wypadku też wyjdzie 13.
And you know the thing about chaos, Harvey?
It's fair!
VGT
Piegowaty Guziec
Piegowaty Guziec
Posty: 21
Rejestracja: 20 lut 2011, 21:47
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Iława
Kontakt:

Odp: C++: wynik działania +++

Post autor: VGT »

Enkidu pisze:

Kod: Zaznacz cały

a=++b+a;
W tym wypadku też wyjdzie 13.
Właśnie, że nie. Sprawdziłeś? Tutaj najpierw jest preinkrementacja, a potem sumowanie składników.
Enkidu pisze:Ale ja cały czas pytam o wynik działania - czemu najpierw sumuje a potem dopiero inkrementuje?
Bo w takiej kolejności działa postinkrementacja (w odróżnieniu od pre), a czym pisałem w pierwszym poście.
Wydaje mi się, że nie odróżniasz postinkrementacji od preinkrementacji uznając obydwie za to samo, a różnica jest zasadnicza.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Uuu, racja - wyjdzie to samo. Wcześniej w pracy sprawdzałem, ale musiałem coś w kodzie namieszać.

W każdym razie zastanawiam się jak widzi to wyrażenie "a+++b" kompilator, postinkrementacje a, czy preinkrementację b? Z tego, co wyrzuca na wyjście, wynika, że widzi najpierw + przy b, a potem postinkrementację przy a.

Ale dlaczego nie widzi preinkrementacji przy b i potem sumy?
And you know the thing about chaos, Harvey?
It's fair!
VGT
Piegowaty Guziec
Piegowaty Guziec
Posty: 21
Rejestracja: 20 lut 2011, 21:47
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Iława
Kontakt:

Odp: C++: wynik działania +++

Post autor: VGT »

Zapewne to kwestia podejścia kompilatora. Po prostu taka jest kolejność zapisana gdzieś w specyfikacji języka. Tak jak wcześniej pisałem, byłem zaskoczony, że coś takiego przechodzi. Dla pewności lepiej rozdzielać to spacjami. Sytuacja jest podobna, jak używanie wielu różnych operatorów bez grupowania w nawiasy. Jak wiesz, co robisz i znasz kolejność ich wykonywania, to można, ale bardzo łatwo o pomyłkę, którą potem ciężko namierzyć.

Nie zdziwiłbym się także, gdyby działanie tego "a+++b" mogło być różne w zależności od kompilatora. Na blogu Gynvael'a był ciekawy wpis o inkrementacji pokazujący, że takie sytuacje są możliwe: http://gynvael.coldwind.pl/?id=369

PS. Ogólnie to ja nie koduję w C / C++. Mogę mieć tutaj braki w wiedzy, więc jestem nieco zawiedziony, że jako jedyny odpowiadam w tym wątku. Przydałaby się jeszcze opinia kogoś, kto jest bardziej na bieżąco ;)

PS2. Z ciekawości przetestowałem w językach, których używam regularnie (PHP, Java) i w obydwu taki zapis jest możliwy i działa tak samo jak w C++.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Myślę, że to wynika z faktu, że inkrementacja ma wyższy priorytet od znaku sumy ;) Ale zagadką pozostaje fakt jak w takim wypadku rozróżnia post i pre inkrementację kompilator.

Dodam, że w czystym C wynik jest ten sam.
And you know the thing about chaos, Harvey?
It's fair!
Awatar użytkownika
pax0r
Sędziwy Jeż
Sędziwy Jeż
Posty: 70
Rejestracja: 10 lut 2011, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: C++: wynik działania +++

Post autor: pax0r »

C i C++ mialem juz jakis czas temu ale wydaje mi sie ze zapis a+++b to czy kompilator potraktuje to jako (a++)+b czy jako a+(++b) to jest undefined behaviour.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Z tego co się orientuję undefined behaviour oznacza w praktyce jakiego kompilatora się używa ;)
And you know the thing about chaos, Harvey?
It's fair!
kklimonda
Zakręcona Traszka
Zakręcona Traszka
Posty: 585
Rejestracja: 20 kwie 2008, 04:21
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME

Odp: C++: wynik działania +++

Post autor: kklimonda »

Ale to chyba nie jest niezdefiniowane, w tym przypadku interpretacja jest w miare prosta.
Kompilator rozbija b+++c na zmienną b, postinkrementację, sumę, zmienną b - w kolejności, w jakiej występują w kodzie bo parser czyta kod praktycznie znak po znaku.
Kiedy już ma wszystko wczytane to najpierw wykonuje b + c, a następnie b++, znów według zasad.
Awatar użytkownika
Enkidu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 139
Rejestracja: 10 wrz 2008, 12:10
Płeć: Mężczyzna
Wersja Ubuntu: 13.04
Środowisko graficzne: Unity
Architektura: x86_64

Odp: C++: wynik działania +++

Post autor: Enkidu »

Tzn. że ów parser czyta znaki od lewej do prawej, ale działania wykonuje od prawej do lewej i dlatego przypisanie wygląda tak jak na przykładzie.:
a=8+c
?
And you know the thing about chaos, Harvey?
It's fair!
maciejewski
Piegowaty Guziec
Piegowaty Guziec
Posty: 12
Rejestracja: 16 sie 2008, 02:23
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME

Odp: C++: wynik działania +++

Post autor: maciejewski »

zgadza sie.
jest dokladnie tak jak napisales.
Kokosek
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 108
Rejestracja: 04 mar 2009, 20:44
Płeć: Mężczyzna
Wersja Ubuntu: 10.04
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: C++: wynik działania +++

Post autor: Kokosek »

kklimonda pisze:Ale to chyba nie jest niezdefiniowane, w tym przypadku interpretacja jest w miare prosta.
Kompilator rozbija b+++c na zmienną b, postinkrementację, sumę, zmienną b - w kolejności, w jakiej występują w kodzie bo parser czyta kod praktycznie znak po znaku.
Kiedy już ma wszystko wczytane to najpierw wykonuje b + c, a następnie b++, znów według zasad.
Dokładnie. Parser jest zachłanny (greedy), czyli dopasowuje jak największe kawałki od razu.
Kokos - po prostu, nie zdrabniaj ;)
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 37 gości