NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
IT rekvalifikace s podporou uplatnění. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Avatar
Homo
Člen
Avatar
Homo:16.6.2013 0:49
int i = 1;
int j = 5;
i += i++ + ++j + ++i + j++;

C# a Java rikaji ze i je 17.
PHP a C++ rikaji ze i je 19.

Me vyslo ze je to 17.

Tak kdo ma teda pravdu?

Odpovědět
16.6.2013 0:49
1010011 1000101 1011000
Avatar
Maxfx
Tvůrce
Avatar
Odpovídá na Homo
Maxfx:16.6.2013 4:09

a k čemu je to dobré ?

Nahoru Odpovědět
16.6.2013 4:09
Být ovládán znamená být sledován, pod dohledem, špehován, veden, uzákoněn, reglementován, ohrazen, indoktrinován, pře...
Avatar
Kit
Tvůrce
Avatar
Kit:16.6.2013 8:08

Nikdo. Takové divočárny se nedělají :)

Nahoru Odpovědět
16.6.2013 8:08
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hynek
Tvůrce
Avatar
David Hynek:16.6.2013 9:14

Správně je 19.

i = 1
j = 5

i += i++ + ++j + ++i + j++
tedy
I sečtení pro (x++) i += 2 + 5 + 1 + 6 = 14 (i++ a j++ se provedly před výpočtem)
II sečtení pro (++x) i += 14 + 2 = 16 (++i a ++j se provedly po výpočtu)
III sečtení pro (i +=) i = 16 + 3 = 19 (a samo i se z 1 se přičtením i++ a ++i změnilo na 3)
Editováno 16.6.2013 9:19
Nahoru Odpovědět
16.6.2013 9:14
Čím víc vím, tím víc věcí nevím.
Avatar
Homo
Člen
Avatar
Odpovídá na David Hynek
Homo:16.6.2013 9:31

Tim padem jazyky s virtualnim strojem to pekne sidi :-D

Nahoru Odpovědět
16.6.2013 9:31
1010011 1000101 1011000
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Homo
David Hartinger:16.6.2013 9:38

A i += i++; funguje všude stejně?

Nahoru Odpovědět
16.6.2013 9:38
New kid back on the block with a R.I.P
Avatar
Homo
Člen
Avatar
Odpovídá na David Hartinger
Homo:16.6.2013 9:45

C++ rika 3, Java rika 2.
PHP a C# testoval Winitrix takze to ted nevim.

Nahoru Odpovědět
16.6.2013 9:45
1010011 1000101 1011000
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Homo
David Hartinger:16.6.2013 9:49

No tak v tom je ten problém :) Ono záleží jak si to vyložíš. Má se změna proměnné vpravo projevit v hodnotě vlevo? Ani jeden výsledek není špatně.

Nahoru Odpovědět
16.6.2013 9:49
New kid back on the block with a R.I.P
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:16.6.2013 11:20

Pravdu mají asi všichni, pokud v překladači/in­terpretu některého z testovaných jazyků není chyba. Aby se tohle dalo více řešit, bylo by třeba přečíst normy všech těch jazyků, jinak to podle mě nemá smysl.

Nahoru Odpovědět
16.6.2013 11:20
2 + 2 = 5 for extremely large values of 2
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Homo
Lukáš Hruda:16.6.2013 11:33

Mě vyšlo 18 a 2 kompilátory na C a na C++ mi to potvrdily, tvůj kompilátor C++ pravděpodobně nedodržuje standard, Java a C# mají očividně jiné priority operátorů.

Editováno 16.6.2013 11:34
 
Nahoru Odpovědět
16.6.2013 11:33
Avatar
Homo
Člen
Avatar
Odpovídá na Lukáš Hruda
Homo:16.6.2013 11:41

Ja to rikam furt ze MS je sra*ka :-D
Pouzivam kompilator co je ve VS2012.

Nahoru Odpovědět
16.6.2013 11:41
1010011 1000101 1011000
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Homo
Lukáš Hruda:16.6.2013 11:44

VS má dobré vývojové prostředí, ale nepřekvapuje mě, že nedodržuje standardy, sám jsem se o tom přesvědčil kdysi ve VS 2010 (už nevím co to bylo, ale také v něčem nedodržovalo standard). Nejlépe je na tom s dodržováním standardů údajně gcc, čemuž i věřím.

 
Nahoru Odpovědět
16.6.2013 11:44
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Homo
Lukáš Hruda:16.6.2013 12:04

V Javě mi vyšlo 17, ale absolutně netuším jak k tomu ten kompilátor došel :D

 
Nahoru Odpovědět
16.6.2013 12:04
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na David Hynek
Lukáš Hruda:16.6.2013 16:21

Tuším, že to máš obráceně. i++ a j++ se provádí po výpočtu (po výpočtu pravé strany, operátor += má nejmenší prioritu z vyskytujících se operátorů), ++i a ++j se provádí před výpočtem (nebo spíše přímo při výpočtu). Celkový výsledek očividně závisí na jazyce, ale mám pocit, že všechny C-like jazyky by teoreticky měli dodržovat priority operátorů jazyka C, pak je správný výsledek 18.

 
Nahoru Odpovědět
16.6.2013 16:21
Avatar
Luboš Běhounek Satik:17.6.2013 0:09

C++ na tohle ani standard nemá (má jen standard samotný postfix/prefix ++ a --).
Čekal bych, že ostatní jazyky asi také tohle ve standardu neřeší.
Takže dokonce i různé C++ kompilátory můžou produkovat různý výsledek a není to chyba, prostě to jen implementují jinak.

int i = 1;
int j = 5;
i += i++ + ++j + ++i + j++;

U MSVS kompilátorů výpočet probíha následovně, ++ přičítá hned za (resp. před) každým členem výpočtu:
i += 1 (i=2) + (j=6) 6 + (i=3) 3 + 6 (j=7)
z čehož nám vyjde
i += 16

Rozdíl teď může být v tom, jestli se za to počáteční i dosadí hodnota i před výpočtem (1+16, výsledek 17) nebo hodnota i po výpočtu (3+16, výsledek 19).

MSVS C++ mi vrací 19 a MSVS C# 17 (pro jistotu jsem to ozávorkoval, abych vyloučil různé priority operátorů).

Luckinův kompilátor to počítá ještě jinak, odhaduji, že jeho kompilátor bere jako výraz celý řádek a ne jednotlivé prvky, takže se ten kód

i += i++ + ++j + ++i + j++;

přeloží zhruba na tohle:
++i;
++j;
i += i + j + i + j;
i++;
j++;
z čehož nám vyjde, když do výpočtu dosadíme aktuální hodnoty:
i += 2 + 6 + 2 + 6
tedy
i += 16
(v tu chvíli je i 2, tedy výsledek je 2+16 = 18)

Editováno 17.6.2013 0:09
Nahoru Odpovědět
17.6.2013 0:09
https://www.facebook.com/peasantsandcastles/
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Luboš Běhounek Satik
Lukáš Hruda:17.6.2013 2:13

Ne tak docela.
Kompilátor nejdříve spočítá pravou stranu tedy:
i++ + ++j + ++i + j++
Kompilátor postupuje zleva doprava, tudíž vezme nejdříve i jako 1, pak j ke kterému rovnou přičte 1 tedy bere ho jako 6 a j je zvýšeno na 6, pak i ke kterému rovnou přičte 1 tedy bere ho jako 2 a i je zvýšeno na 2, následuje j které je bráno jako 6.
Na levé straně tedy dojde k výrazu:
1+6+2+6 = 15
Následně se spočítají výrazy j++ a i++, tedy i je zvýšeno na 3 a j na 7.
i += 15 tedy přiřadí do i hodnotu 3 + 15 tedy 18.
Standard C++ říká, že prefix (++i/++j), má vracet hodnotu prvku již zvýšeného a postfix (i++/j++) hodnotu prvku před zvýšením.
i++ + ++j + ++i + j++ by totiž kompilátor měl brát jako jeden výraz a postfixy spočítat až nakonec. VS přičte k i jedničku hned po prvním + tedy hned po vykonání i++ + ++j, bere to jako volání funkcí:

i++.operator+(++j.operator+(++i.operator+(j++)))

Je pravda, že na tohle standard asi není. Pak tedy i výsledek 19 je teoreticky správně.
Ovšem to, že kompilátor při přiřazení postupuje zprava doleva a že operátor += má menší prioritu než + a ++ by standardem dáno být mělo. Tedy nejdříve se provede výraz na pravé straně a pak samotné přiřazení, na levé straně tedy podle mě musí vždy být hodnota 3.

 
Nahoru Odpovědět
17.6.2013 2:13
Avatar
Odpovídá na Lukáš Hruda
Luboš Běhounek Satik:17.6.2013 8:01

"Ovšem to, že kompilátor při přiřazení postupuje zprava doleva a že operátor += má menší prioritu než + a ++ by standardem dáno být mělo."
Však tak je to i v C++ i v C# i od MS, na tomhle se nic nemění, to je všude stejné.

Ono jde o to, že pod

i += i++ + ++j + ++i + j++;

si třeba já (a C#) představím to samé, jako je

i = i + (i++ + ++j + ++i + j++);

tedy že jako to i, ke kterému se přičítá, se bere ta počátační hodnota i .

V normě právě není specifikováno, jestli se za ten výraz má považovat samotné i++ nebo celý "řádek".

Nahoru Odpovědět
17.6.2013 8:01
https://www.facebook.com/peasantsandcastles/
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Luboš Běhounek Satik
Lukáš Hruda:17.6.2013 11:24

Asi máš pravdu, ale dost bylo keců, takovouhle prasárnu stejně v životě nepoužiju... :)

 
Nahoru Odpovědět
17.6.2013 11:24
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 18 zpráv z 18.