Pouze tento týden sleva až 80 % na e-learning týkající se Javy. A zároveň využij akce až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme koordinátorku kurzů a programátora, 100% home office, 100% flexibilní. Prozkoumej aktuální pozice
discount week 30 - hiring

Diskuze: Použití inkrementů/dekrementů v C

Aktivity
Avatar
Neaktivní uživatel:25.1.2016 17:22

Zdravím,
dneska jsem začal s céčkem a musím říct, že mě trochu překvapilo použití inkremetů/dekre­mentů. V Javě/PHP a dalších podobných jazycích to funguje na podobném principu:

/* Jiný programovací jazyk */
int a = 1;
int b = 2;
a = b++;

Pro proměnnou "a" tady čekám hodnotu o jedno větší než "b", tedy 3. Ale v céčku je to jinak - vrátí se původní hodnota (2) a teprve poté se zvýší hodnota samotné proměnné. Takže mám pár otázek. Zvýší se hodnota proměnné "b" na trvalo nebo jen v daném výrazu? Tedy když si později zavolám "b", bude mít hodnotu 2, nebo 3? A jestli to dobře chápu, je to vlastně zkrácenina:

/* Jiný programovací jazyk */
int a = 1, b = 2;
a = b;
b++;

V čem je tedy výhoda? Proč existuje prefixní i sufixní inkrementant (dekrementant)?

Odpovědět
25.1.2016 17:22
Neaktivní uživatelský účet
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
tomisoka:25.1.2016 17:29

Prefix je pro zvýšení/zmenšení o jedna před vyhodnocením výrazu(přiřazení k a), zatímco sufix se vykoná až po vyhodnocení výrazu. Do teď jsem myslel, že to v Javě funguje stejně.

 
Nahoru Odpovědět
25.1.2016 17:29
Avatar
Odpovídá na tomisoka
Neaktivní uživatel:25.1.2016 17:36

V Javě nejsem moc zběhlý, ale v PHP by to mělo fungovat promenna++ (ihned se zvýší o jedno, ale nikam se neukládá). V C se ukládá zpátky do původní proměnné, že?

Nahoru Odpovědět
25.1.2016 17:36
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:25.1.2016 17:46

To samé se děje i v PHP :)

Nahoru Odpovědět
25.1.2016 17:46
Neaktivní uživatelský účet
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
tomisoka:25.1.2016 17:51

Ano, inkrementace/de­krementace mění přímo tu proměnnou, přičemž prefix/sufix rozhoduje jestli se započítá do výrazu nebo ne. Jinak nějak nedokážu pochopit, k čemu je ta PHP verze inkrementace/de­krementace, proč rovnou nepoužít "a+1"?

 
Nahoru Odpovědět
25.1.2016 17:51
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:25.1.2016 17:52

Máš pravdu, teď jsem to zkoušel, toho jsem si nikdy nevšiml. :)

Nahoru Odpovědět
25.1.2016 17:52
Neaktivní uživatelský účet
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
Martin Dráb:25.1.2016 17:52

V čem je tedy výhoda? Proč existuje prefixní i sufixní inkrementant (dekrementant)?

V kratším zápisu. Takté to teoreticky může pomoci překladači vygenerovat lepší/rychlejší kód.

Na druhou stranu, divoké používání těchto zkrácenin může vést k znepřehlednění zdrojáku, takže je třeba být opatrný.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět
25.1.2016 17:52
2 + 2 = 5 for extremely large values of 2
Avatar
coells
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
coells:25.1.2016 18:06

V čem je tedy výhoda? Proč existuje prefixní i sufixní inkrementant (dekrementant)?

Je to pozůstatek z dob dávno minulých.
Kód for(int i = 0; i < n; ++i) býval v C rychlejší než for(int i = 0; i < n; i++)
Také samotný výraz ++a býval rychlejší než a++ díky ušetřené instrukci.
Dneska se optimalizace o všechno postarají a doporučuje se podobným trikům vyhýbat.

 
Nahoru Odpovědět
25.1.2016 18:06
Avatar
Patrik Valkovič
Člen IT Redactor Gang
Avatar
Odpovídá na tomisoka
Patrik Valkovič:25.1.2016 18:21

proč rovnou nepoužít "a+1"?

To je záležitostí hardwarovou. Když se podíváš na instrukce, tyto dvě operace jsou rozdílné.

;a++
INC [a]

Inkrementuje proměnnou a. Jeden příkaz, jeden takt procesoru. (doufám že to mám správně, v ASM moc zběhlý nejsem)

; a = a + 1
MOV eax,[a]
ADD eax,0x1
MOV [a],eax

Zde nejprve musíš proměnou nejprve načíst do registru, potom přičíst jedničku, a hodnotu zpět uložit. Dva příkaz MOV navíc, a myslím taky není na jeden tik (tedy je pomalejší jako INC).

Nicméně překladače by to měli zvládnout optimalizovat.

Nahoru Odpovědět
25.1.2016 18:21
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Patrik Valkovič
tomisoka:25.1.2016 18:28

Jo, já vím. Já komentoval:

V Javě nejsem moc zběhlý, ale v PHP by to mělo fungovat promenna++ (ihned se zvýší o jedno, ale nikam se neukládá).

 
Nahoru Odpovědět
25.1.2016 18:28
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 10 zpráv z 10.