Stručný obsah
K1784.indd 3
Úvod
41
Překlad a sestavení programu: základní dovednosti
43
Překlad a sestavení programu: další možnosti
57
Implementační a hlavičkové soubory
73
Ladění v integrovaném vývojovém prostředí
83
Ladění pomocí programových konstrukcí
97
Program, jeho běh a prostředí
103
Deklarace a proměnné
113
Ukazatele a pole
123
Správa paměti
135
Reference
145
Práce se znaky
149
Znakové řetězce (pole znaků)
159
Znakové řetězce (typ basic_string<>)
175
Funkce a ukazatele na ně
187
Preprocesor a makra
205
Celá čísla
215
Reálná čísla
225
Příkazy
237
Výrazy a operátory
249
Výčtové typy
259
22.7.2010 7:34:22
4
Stručný obsah
Struktury a unie
265
Objektový typ a jeho deklarace
273
Vytvoření instance
289
Kopírování instancí
299
Zánik instance
309
Dědění a polymorfizmus
315
Objektový návrh
331
Přetěžování operátorů
341
Zpracování chybových stavů
361
Jmenné prostory
375
Šablony
383
Práce s datovými typy
403
Vstupní a výstupní operace v jazyce C
413
Vstupní a výstupní operace v jazyce C++
435
Na přiloženém CD naleznete
K1784.indd 4
Kontejnery ve standardní knihovně
453
Algoritmy ve standardní knihovně
467
Lokální nastavení v C a v C++
487
Komplexní čísla
503
C++0x
511
Několik tipů na závěr
521
22.7.2010 7:34:22
Obsah Úvod
41
Komu je kniha určena Doprovodné CD
41 42
Překlad a sestavení programu: základní dovednosti 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
K1784.indd 5
43
Překládáme program složený z jediného souboru Překládáme program a určujeme jméno výsledného souboru (bcc32, cl) Překládáme program a určujeme jméno výsledného souboru (g++) Jak přeložit soubor bez sestavování Sestavujeme spustitelný program z objektového souboru (bcc32, cl) Sestavujeme spustitelný program z objektového souboru (g++) Překládáme program složený z několika souborů Překládáme program složený z několika souborů a určujeme jméno výsledného souboru (bcc32) Překládáme program složený z několika souborů a určujeme jméno výsledného souboru (cl, g++) Připojujeme nestandardní knihovnu (bcc32) Připojujeme nestandardní knihovnu (C++Builder 2009) Připojujeme nestandardní knihovnu (cl) Připojujeme nestandardní knihovnu (Visual C++ 2008) Určujeme adresář s knihovnami (g++) Připojujeme konkrétní standardní knihovnu (g++) Připojujeme konkrétní nestandardní knihovnu (g++) Jak ušetřit práci: Program MAKE Jak na soubor Makefile Pozor na mezeru před pravidlem v souboru makefile Když se příkaz v souboru makefile nevejde na jeden řádek Odkazujeme na jméno cíle v souboru makefile (mingw32-make) Odkaz na předpoklady v souboru makefile (mingw32-make) Odkaz na všechny soubory daného typu v souboru makefile (mingw32-make) Odkaz na první předpoklad v souboru makefile (mingw32-make) Jak na úklid pomocí souboru makefile (mingw32-make) Jak na všechny úpravy souboru makefile z předchozích tipů Jaký jazyk překládáme? (bcc) Jaký jazyk překládáme? (C++Builder) Jaký jazyk překládáme? (cl) Jaký jazyk překládáme? (Visual Studio 2008)
43 43 44 44 44 44 45 45 46 46 46 47 48 48 49 49 49 50 50 50 51 51 51 51 52 52 52 53 54 54
22.7.2010 7:34:22
6
Obsah
31 32 33 34 35
Jaký jazyk překládáme? (g++) Překlad zdrojového souboru v C99 (g++) Jak získat základní nápovědu k překladači (bcc32) Jak na jména standardních hlavičkových souborů Jak využít hlavičkové soubory z jazyka C v C++
Překlad a sestavení programu: další možnosti 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
K1784.indd 6
Jak na optimalizaci Optimalizujeme velikost výsledného programu Optimalizujeme velikost výsledného programu (C++Builder 2009) Optimalizujeme velikost výsledného programu (Visual Studio 2008) Optimalizujeme rychlost výsledného programu Optimalizujeme rychlost výsledného programu v g++ Optimalizujeme rychlost výsledného programu (C++Builder 2009) Optimalizace rychlosti výsledného programu (Visual Studio 2008) Proč definovat podmínková jména Definujeme podmínkové jméno Jak na definici podmínkového jména (C++Builder 2009) Jak na definici podmínkového jména (Visual C++ 2008) Jak na další adresář pro hlavičkové soubory Jak na další adresář pro hlavičkové soubory (C++Builder 2009) Jak na další adresář pro hlavičkové soubory (Visual C++ 2008) Vytvoření statické knihovny (bcc32, cl) Vytvoření statické knihovny (g++) Vytvoření statické knihovny (C++Builder 2009) Vytvoření statické knihovny (Visual Studio 2008) Co je výstupem preprocesoru Co je výstupem preprocesoru (cl) Co je výstupem preprocesoru (g++) Co je výstupem preprocesoru (Visual Studio 2008) Překlad vybraného zdrojového souboru do asembleru (bcc32) Překlad vybraného zdrojového souboru do asembleru (cl) Překlad vybraného zdrojového souboru do asembleru (g++) Překlad vybraného zdrojového souboru do asembleru (C++Builder 2009) Překlad vybraného zdrojového souboru do asembleru (Visual Studio 2008) Překlad všech souborů projektu do asembleru (C++Builder 2009) Překlad všech zdrojových souborů do asembleru (Visual Studio 2008)
55 55 55 55 56
57 57 57 58 59 60 60 60 61 61 61 62 63 63 64 65 66 66 67 67 68 68 68 68 69 69 70 70 70 71 72
22.7.2010 7:34:22
Obsah
Implementační a hlavičkové soubory 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
K1784.indd 7
Co je modul a jeho rozhraní Použití hlavičkového souboru Kde překladač hledá hlavičkový soubor Kam lze vložit hlavičkový soubor Jak zabránit opakovanému čtení hlavičkového souboru Jak zabránit opakovanému čtení hlavičkového souboru ve Visual C++ Jak exportovat globální proměnnou z modulu Jak na globální proměnnou, kterou nechceme exportovat Jak na globální proměnnou, kterou nechceme exportovat (jen C++) Jek exportovat konstanty (const) z modulů Jak exportovat konstanty (const) z modulů – společné řešení pro C a C++ Jak na konstanty, které z modulu nechceme exportovat Jak exportovat funkci z modulu Jak na funkci, kterou nechceme exportovat Jak na funkci, kterou nechceme exportovat (jen C++) Jak na funkci s modifikátorem inline v hlavičkových souborech (C++ a C99) Makra v hlavičkových souborech Neobjektový datový typ exportovaný z modulu Objektový typ exportovaný z modulu Vložené (inline) metody Datový typ, který nechceme exportovat z modulu Šablona funkce exportovaná z modulu – typické řešení Šablona funkce exportovaná z modulu – jiná možnost (jen některé nejnovější překladače) Šablona třídy exportovaná z modulu – typické řešení Šablona třídy exportovaná z modulu – jiná možnost (jen některé nejnovější překladače)
7
73 73 73 73 74 74 74 74 75 75 75 76 76 76 77 77 77 78 78 78 79 79 80 80 80 81
Ladění v integrovaném vývojovém prostředí
83
Překlad pro ladění (C++Builder) Překlad pro ladění (Visual C++) Jak spustit program z IDE (C++Builder) Jak spustit program z IDE (Visual Studio 2008) Chceme vidět výsledky konzolové aplikace (C++Builder 2009) Chceme vidět výsledky konzolové aplikace (Visual Studio 2008) Jak krokovat program Krokování s překročením podprogramu Krokování se vstupem do podprogramu Zjištění hodnoty proměnné
83 83 84 84 84 85 85 85 87 87
22.7.2010 7:34:23
8
Obsah
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
K1784.indd 8
Zjištění hodnoty proměnné (C++Builder) Zjištění hodnoty proměnné (Visual Studio 2008) Sledované výrazy (C++Builder 2009) Sledované výrazy (Visual Studio 2008) Měníme hodnotu proměnné (C++Builder 2009) Měníme hodnotu proměnné (Visual Studio 2009) Krokování od zvoleného místa: doběhni ke kurzoru Krokování od zvoleného místa: zarážka Podmíněné zarážky (C++Builder 2009) Podmíněné zarážky (Visual Studio 2008) Jak ukončit krokování Jak krokovat v asembleru Posloupnost volání funkcí (C++Builder 2009) Posloupnost volání funkcí (Visual Studio 2008) Jak zjistit obsah registrů (C++Builder 2009) Jak zjistit obsah registrů (Visual C++ 2008) Jak zjistit obsah paměti (C++Builder 2009) Jak zjistit obsah paměti (Visual C++ 2009) Zakomentování vybraných řádků zdrojového kódu Parametry programu zadávané v příkazovém řádku Parametry programu při spouštění v IDE (C++Builder 2009) Parametry programu při spouštění v IDE (Visual Studio 2008)
87 87 87 88 88 89 89 89 89 90 90 91 92 92 93 93 93 93 94 94 94 94
Ladění pomocí programových konstrukcí
97
Potřebujeme dočasně odstranit několik řádků z programu Potřebujeme odstranit větší počet řádků Definice podmínkového jména pro ladění Co je ladicí kód Jednoduchý ladicí tisk (C) Makro pro ladicí tisk Podmíněné makro Kam umístit direktivu #define, je-li makro v hlavičkovém souboru? Ve které funkci jsme? (C99) Ve kterém zdrojovém souboru jsme? Na kterém řádku zdrojového souboru jsme? Při ladění prověřujeme kontrakt Test vstupních podmínek při ladění: aserce Odstranění asercí z programu Aserce, nebo výjimky?
97 97 97 98 98 98 98 99 99 99 100 100 100 101 101
22.7.2010 7:34:23
Obsah
138 139 140 141
Test výstupních podmínek Je test dostatečný? Test invariantů Proč nerandomizovat
Program, jeho běh a prostředí 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
K1784.indd 9
Funkce main(), wmain() a jiné Abychom nemuseli volit: _tmain() Formální parametry funkce main() a wmain() Formální parametry „funkce“ _tmain() Tradiční jména parametrů funkce main() Typ funkce main() Omezení kladená na funkci main() v C++ Co je startovací kód Parametry příkazové řádky programu S kolika parametry v příkazové řádce byl náš program spuštěn? Jak se jmenuje náš program? Výpis všech parametrů programu Jak na proměnné prostředí Výpis všech proměnných prostředí (nestandardní řešení) Zjištění hodnoty proměnné prostředí Zjištění hodnoty proměnné prostředí v Unicode (nestandardní řešení) Nastavení hodnoty proměnné prostředí (nestandardní řešení) Spouštíme z programu jiný program Kód ukončení programu Předdefinované konstanty pro kód ukončení Když program končí Řádné ukončení programu Spořádané ukončení programu jinde než ve funkci main() Ukončení bez úklidu: _Exit() (C99) Abnormální ukončení programu Abnormální ukončení programu v C++ Měníme funkci, kterou volá terminate() Vlastní úklid při ukončení programu: funkce registrované voláním atexit() Pořadí volání funkcí registrovaných pomocí atexit() Podařila se registrace funkce pomocí atexit()? Kdy se inicializují globální proměnné Jak zajistit včasnou inicializaci objektu?
9
101 102 102 102
103 103 103 103 104 104 104 104 104 105 105 105 105 105 106 106 107 107 107 108 108 108 108 109 109 109 109 110 110 110 110 110 111
22.7.2010 7:34:23
10
Obsah
Deklarace a proměnné 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
Jaký je rozdíl mezi deklarací a definicí Pravidlo jediné definice pro proměnné Informativní deklarace proměnné Definiční deklarace globální proměnné Deklarace lokální automatické proměnné Lokální proměnná, která si pamatuje hodnotu Počítáme, kolikrát byla funkce volána Jak se inicializuje lokální statická proměnná? Co je to registrová proměnná? K čemu je registrová proměnná? Jak deklarovat ukazatel Ukazatel na cokoli Jak deklarovat konstantu Konstanta v jazyce C Konstanta v jazyce C++ Ukazatel na konstantu Konstantní ukazatel Konstantní ukazatel na konstantu Inicializace proměnné v deklaraci Nové jméno pro typ Deklarace ukazatele pomocí jména zavedeného deklarací typedef Deklarace jednorozměrného pole pojmenovaného typu Deklarace vícerozměrného pole Deklarace jednorozměrného pole ukazatelů Deklarace ukazatele na jednorozměrné pole Deklarace proměnné objektového typu s konstruktorem bez parametrů Deklarace proměnné objektového typu s konstruktorem s parametry Co je implicitní int Proměnné, které se mohou měnit „z pozadí“ Označení typu
Ukazatele a pole 204 205 206 207 208 209
K1784.indd 10
Deklarace jednorozměrného pole s inicializací Jaké prvky má pole? Inicializace pole nulami Čárka na konci seznamu inicializátorů Známe inicializátory, neznáme počet prvků Kolik prvků má pole?
113 113 113 113 113 114 114 114 115 115 115 115 116 116 116 116 117 117 117 117 118 118 118 119 119 119 119 120 120 120 121
123 123 123 123 123 124 124
22.7.2010 7:34:23
Obsah
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
Inicializujeme jen některé prvky (jen C99) Pole s nekonstantním počtem prvků Pole objektového typu Pole objektového typu inicializované skalárními hodnotami Pole objektového typu inicializované instancemi Explicitní volání konstruktoru v inicializaci pole objektového typu Pole s nekonstantním počtem prvků (jen C99) Inicializace vícerozměrného pole První index v deklaraci vícerozměrného pole můžeme někdy vynechat Literál typu pole (jen C99) Přístup k prvkům pole Indexování je symetrické Pole se skoro vždy konvertuje na ukazatel Pole lze přiřadit ukazateli Používáme proměnnou, na kterou ukazuje ukazatel Ukazatel indexujeme jako pole Jak vytvořit ukazatel nikam Adresová aritmetika (aritmetika ukazatelů) Co znamená rovnost nebo nerovnost ukazatelů? Který prvek má vyšší index? Která složka struktury je definována dříve? Chceme s ukazatelem přejít na následující prvek pole Chceme s ukazatelem přejít na předcházející prvek pole Chceme s ukazatelem přejít o m prvků dál O kolik se liší indexy daných prvků? Překopírování obsahu jednorozměrného pole Překopírování obsahu jednorozměrného pole pomocí adresové aritmetiky Kopírování obsahu pole, když se zdrojové a cílové pole nepřekrývá Kopírování obsahu pole, když se zdrojové a cílové pole překrývá První nulový prvek v jednorozměrném poli pomocí adresové aritmetiky První nulový prvek v jednorozměrném poli pomocí indexování První záporný prvek ve dvourozměrném poli pomocí indexování Výpis všech záporných prvků ve dvourozměrném poli pomocí adresové aritmetiky Omezené (restringované) ukazatele v C99
Správa paměti 244 245 246
K1784.indd 11
Alokace jednoduché proměnné základního typu Alokace jednorozměrného pole pomocí funkce malloc() Alokace jednorozměrného pole s vynulováním
11
124 124 125 125 125 126 126 126 126 127 127 127 127 128 128 128 129 129 129 129 129 130 130 130 130 131 131 131 132 132 132 133 133 134
135 135 135 135
22.7.2010 7:34:23
12
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
Obsah
Když malloc() nebo calloc() neuspěje Uvolnění paměti alokované pomocí malloc() nebo calloc() Zvětšení dynamicky alokovaného pole Zmenšení dynamicky alokovaného pole Když funkci realloc() předáme NULL Když realloc() neuspěje Alokace jednoduché proměnné základního typu v C++ Alokace jednoduché proměnné základního typu s inicializací Alokace instance objektového typu Alokace instance objektového typu inicializovaná konstruktorem s parametry Alokace instance objektového typu pomocí malloc() Uvolnění paměti jednoduché proměnné základního typu alokované pomocí new Uvolnění paměti instance objektového typu Alokace hrubé paměti pomocí new Uvolnění paměti alokované pomocí new bez volání destruktoru Když operátor new neuspěje Když nechceme, aby operátor new vyvolával výjimku Alokace instance objektového typu s přetíženým operátorem new Překladač nenašel globální new. Co se děje? Alokace instance objektového typu s přetíženým operátorem new pomocí globálního new Zrušení instance objektového typu s přetíženým operátorem delete globálním delete Alokace jednorozměrného pole základního typu pomocí new Alokace jednorozměrného pole objektového typu pomocí new Alokace pole objektového typu s přetíženým operátorem new Překladač nenašel při alokaci pole globální new. Co se děje? Alokace pole objektového typu s přetíženým operátorem new[] globálním new Zrušení pole objektového typu s přetíženým operátorem delete[] globálním delete[] Vyvolá-li konstruktor alokované instance výjimku Nemíchejme malloc() a new Alokace dvourozměrného pole v jazyce C Alokace dvourozměrného pole neobjektového typu pomocí new Uvolnění pole alokovaného pomocí new Zapomeneme-li hranaté závorky za delete
Reference 280 281 282 283
K1784.indd 12
Co je to reference? Deklarace reference Jak jsou reference implementovány? Hlavní omezení kladená na reference
135 136 136 136 137 137 137 137 137 138 138 138 139 139 139 139 140 140 140 140 141 141 141 142 142 142 143 143 143 143 144 144 144
145 145 145 145 145
22.7.2010 7:34:23
Obsah
284 285 286 287 288 289 290 291 292 293 294
Inicializace nekonstantní reference neobjektového typu Inicializace reference objektového typu Lze změnit odkazovanou proměnnou? Měníme hodnotu proměnné prostřednictvím reference Získáváme adresu odkazované proměnné Zjednodušení zápisu pomocí reference Chceme referenci inicializovat výrazem Reference na pole Reference na funkci Voláme odkazovanou funkci Reference jako složka objektového typu
Práce se znaky 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
K1784.indd 13
Znakové typy: v čem se liší C90, C99 a C++ Jakého typu je znakový literál Literál představující úzký netisknutelný znak Přehled řídicích posloupností Literál představující široký znak Co je to Unicode Co jsou vícebajtové znaky Převod širokého znaku na úzký Převod úzkého znaku na široký Lze široký znak reprezentovat jednobajtovým znakem? Máme znak. Je to číslice? (C) Máme znak. Je to číslice? (C++) Máme úzký znak. Je to písmeno? (C) Máme široký znak. Je to písmeno? (C) Máme znak. Je to písmeno? (C++) Jde o malé písmeno? (C) Jde o malé písmeno? (C++) Klasifikace úzkých znaků – přehled Klasifikace znaků při jiném lokálním nastavení (C++) Převod znaků na malá písmena Převod znaků na malá písmena při jiném lokálním nastavení (C++) Převod znaků na velká písmena Převod znaků na velká písmena při jiném lokálním nastavení (C++) Převod mezi malými a velkými písmeny nemusí být jednoznačný Co jsou to trigrafy
13
145 146 146 146 146 147 147 147 147 148 148
149 149 149 149 149 150 151 151 151 152 152 152 153 153 154 154 154 155 155 156 156 156 157 157 158 158
22.7.2010 7:34:23
14
Obsah
Znakové řetězce (pole znaků) 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
K1784.indd 14
Hlavičkové soubory pro široké znaky Řetězcová konstanta Co je to řetězcová konstanta? Inicializace znakového pole řetězcem Když vynecháme počet prvků Spojování řetězcových konstant (všechny verze C a C++) Spojování řetězcových konstant (od C90 dále) Spojování řetězcových konstant vytvořených makry Speciální znaky v řetězcové konstantě Jak deklarovat ukazatel na řetězec Pozor na neinicializované ukazatele Inicializace pole řetězců Jak zjistit délku řetězce Jak přistupovat ke znakům řetězce Kopírování řetězců Kopírujeme nejvýše n znaků Kopírujeme pole znaků, která se překrývají Spojování řetězců První výskyt znaku v řetězci První výskyt znaku ze zadané množiny První výskyt podřetězce Rozklad řetězce na slova Kolik musíme projít znaků, než narazíme na zadaný znak? Lexikografické porovnávání řetězců Abecední porovnávání řetězců podle lokálních zvyklostí Čtení celého čísla z řetězce úzkých znaků Čtení celého čísla z řetězce širokých znaků Čtení reálného čísla z řetězce Převod řetězce na celočíselnou hodnotu Převod řetězce na číselnou hodnotu jiného typu než int Chceme vědět, kde převod na int skončil Chceme vědět, kde skončil převod na jiný celočíselný typ Chceme vědět, kde skončil převod na reálný typ Převod řetězce širokých znaků na číslo Převod z jiných číselných soustav Převedení čísla na řetězec úzkých znaků Převedení čísla na řetězec širokých znaků
159 159 159 159 159 160 160 160 160 161 161 161 162 162 162 162 163 163 163 164 164 165 165 166 166 166 167 167 167 168 168 168 168 169 169 169 170 170
22.7.2010 7:34:23
Obsah
357 358 359 360 361 362 363 364 365
Převod celého čísla na řetězec – nestandardní řešení Další nestandardní funkce pro převod čísel na řetězec Zápis celého čísla v zadané soustavě (nestandardní řešení) Caesarova šifra (jednoduchá transformace řetězce) Převod úzkého řetězce na široký Převod širokého řetězce na úzký Převod znaků v řetězci na velká písmena Převod znaků v řetězci na malá písmena Transformace řetězce na místě
Znakové řetězce (typ basic_string<>) 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
K1784.indd 15
Třídy std::string a std::wstring a dokumentace k nim (C++) Třída string je kontejner ze STL Zápis řetězce do proudu Prázdná instance třídy string Inicializace instance typu string polem znaků Kolik znaků řetězec pojme? Zvětšujeme kapacitu řetězce Inicializace instance typu string opakovaným znakem Převod instance typu string na pole typu char Inicializace pole řetězců typu string Délka řetězce typu string Je řetězec prázdný? Přístup ke znakům řetězce Nový obsah instance typu string Nový obsah instance typu string: opakovaný znak Spojování řetězců typu string nebo wstring Spojujeme řetězce, aniž bychom je měnili Zkracujeme řetězec Prodlužujeme řetězec Kopírujeme řetězec do pole První výskyt znaku v řetězci První výskyt podřetězce První výskyt znaku z dané množiny První výskyt znaku, který nepatří do dané množiny Poslední výskyt znaku v řetězci Poslední výskyt znaku, který nepatří do dané množiny Bylo hledání úspěšné? Vložení nového znaku nebo podřetězce do řetězce
15
170 171 171 171 172 172 173 173 174
175 175 175 175 176 176 176 176 176 177 177 177 177 178 178 178 178 179 179 179 180 180 180 181 181 181 182 182 182
22.7.2010 7:34:23
16
394 395 396 397 398 399 400 401 402
Obsah
Připojení znaku na konec řetězce Jak získat podřetězec Převod typu string na wstring Převod typu wstring na string Převod řetězce na velká nebo pouze malá písmena Kopie řetězce obsahující pouze velká nebo pouze malá písmena Lexikografické porovnávání řetězců Abecední porovnání řetězců Prohození obsahu dvou řetězců
Funkce a ukazatele na ně 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
K1784.indd 16
Co je to funkce? Parametry funkce Co může funkce vracet Co je kontrakt funkce Příklad kontraktu Princip jediné odpovědnosti Příklad příliš široké zodpovědnosti: funkce realloc() Definice a deklarace Prototyp funkce bez parametrů – C vs. C++ Statické a externí funkce Vložené funkce (inline) Vložené funkce nejsou statické (C++) Vložené funkce v jazyce C Pravidlo jediné definice Předávání parametrů funkcím hodnotou Chceme změnit parametr: předávání ukazatele Chceme změnit parametr: předávání odkazem (jen C++) Ukazatelem, nebo odkazem? Předávání pole jako parametru funkce Funkce svůj parametr nemění: ukazatel na konstantu Konstantní reference jako parametr Ukazatel na funkci Konstanta typu ukazatele na funkci Volání funkce zadané ukazatelem Funkce jako parametr funkce Funkce vracející ukazatel Funkce vracející referenci (pouze C++) Na co si dát pozor při deklaraci referenční funkce
183 183 183 184 184 185 185 185 186
187 187 187 187 187 188 188 188 188 189 189 189 190 190 190 190 190 191 191 191 192 192 193 193 193 194 194 194 194
22.7.2010 7:34:24
Obsah
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
Funkce vracející řetězec Co by funkce neměla vracet Když má funkce příliš mnoho parametrů Když překladač nezná typy parametrů Funkce s proměnným počtem parametrů: výpustka Jak se předávají parametry na místě výpustky Jak pracujeme s parametry předanými výpustkou Příklad funkce s výpustkou Nepoužitý parametr (jen C++) Přetěžování funkcí (jen C++) Kdy přetěžovat funkce? Implicitní hodnoty parametrů Volání funkce s implicitními hodnotami parametrů Pravidla pro implicitní hodnoty parametrů Funkce podle Kernighana a Ritchieho Příklad funkce podle Kernighana a Ritchieho Co je implicitní int Funkce z jazyka C v C++ Funkce v C++ se jménem podle pravidel jazyka C Zacházení se jmény funkcí v C a v C++: pohled pod pokličku Příklad zdobení jmen v C++ Volací konvence (není součástí standardu) Standardní volací konvence jazyka C Další volací konvence Funkce zná své jméno (jen C99)
Preprocesor a makra 456 457 458 459 460 461 462 463 464 465 466 467
K1784.indd 17
Podmíněný překlad #elif místo #else #if Co může být v podmínce v direktivě #if? Test, zda je definováno podmínkové jméno Zkratky pro #if defined Kód překládaný jen v C++ Zdrojový soubor, který vyžaduje C++ Varování: direktiva #warn (C99) Platnost podmínkového jména Zrušení podmínkového jména Direktiva pro ozdobu: # Manifestační konstanta (makro bez parametrů)
17
195 195 195 196 196 196 197 197 197 198 198 199 199 199 200 200 200 200 201 201 201 202 202 202 203
205 205 205 205 206 206 206 207 207 207 207 208 208
22.7.2010 7:34:24
18
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
Obsah
Proč používat manifestační konstanty Proč nepoužívat manifestační konstanty (v C++) Jak definovat makro s parametry Když se definice makra nevejde na jeden řádek Makro jako náhrada funkce Proč používat makra Proč nepoužívat makra, ale funkce inline Makra je třeba pečlivě závorkovat Parametr makra by se měl vyhodnocovat jen jednou Vytvoření řetězce v makru Makro by nemělo končit středníkem Spojování symbolů v makru Makra s proměnným počtem parametrů (jen C99) Jak zjistit verzi Unicode (C99) Datum a čas překladu Konvence pro pojmenování maker
Celá čísla 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
K1784.indd 18
Co všechno je celé číslo Celočíselné typy v C90 a v C++ Alternativní jména celočíselných typů Základní celočíselné typy v C99 Osmibajtová celá čísla v C90 a v C++ Zobrazení celých čísel bez znaménka v paměti Zobrazení celého čísla se znaménkem v paměti Malý nebo velký endián Rozsahy celočíselných typů Minimální rozsah celočíselných typů Je jeden celočíselný typ int a ty ostatní jsou od něj odvozeny… Různé pohledy na celá čísla (C99) Celočíselné typy s přesně danou šířkou (C99) Celočíselné typy, které mají alespoň udanou šířku (C99) Nejrychlejší celočíselné typy, které mají alespoň udanou šířku (C99) Celočíselné typy, do nichž lze uložit ukazatel (C99) Celočíselné typy s největší možnou šířkou (C99) Jak zapsat celočíselný literál Přípony celočíselných literálů Jakého typu je desítková celočíselná konstanta?
208 208 208 209 209 209 210 210 210 211 211 211 212 212 213 213
215 215 215 215 215 216 216 216 216 217 217 217 218 218 218 218 219 219 219 219 220
22.7.2010 7:34:24
Obsah
504 505 506 507 508 509 510 511 512 513 514 515 516
Jakého typu je osmičková nebo šestnáctková celočíselná konstanta? Konstanta typu short nebo unsigned short Meze základních celočíselných typů v C Meze dalších celočíselných typů Meze celočíselných typů v C++ Co je to celočíselné přetečení Absolutní hodnota celého čísla Je číslo liché? Je k-tý bit proměnné nastaven? Nastavení k-tého bitu proměnné Počet nastavených bitů v proměnné Jak bezpečně sečíst dvě nezáporná čísla Nemíchejme typy se znaménkem a bez něj
Reálná čísla 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
K1784.indd 19
Datové typy pro reálná čísla Reprezentace a aritmetika reálných čísel Vyhovuje daný datový typ standardu IEEE 754? Reálný literál Typ reálného literálu Zjišťujeme rozsah reálných typů Zjišťujeme rozsah reálných typů v C++ Kolik platných desítkových cifer má daný typ? Kolik bitů mantisy má daný typ? Jaký je rozsah exponentu daného typu? Když k číslu a přičtu b, změní se číslo a? Jaké nejmenší číslo mohu přičíst k 1, abych dostal číslo jiné než 1? Jaké nejmenší číslo mohu přičíst k x, abych dostal číslo jiné než x? Když sečtu deset desetin, dostanu 1? Komutativní a asociativní zákon nemusí platit Porovnávání reálných čísel Rozumnější porovnání Odložená volba typu reálných čísel Známe strany a počítáme úhly v pravoúhlém trojúhelníku Když známe obě odvěsny, je lepší atan2() Jak pracovat s logaritmy Logaritmus o libovolném základu Mocnina a exponenciální funkce
19
220 221 221 221 222 222 222 223 223 223 223 224 224
225 225 225 225 225 226 226 226 226 227 227 227 228 228 228 228 229 229 230 230 230 230 231 231
22.7.2010 7:34:24
20
540 541 542 543 544 545 546 547 548 549 550 551 552 553
Obsah
Goniometrické a hyperbolické funkce pro typ double Zaokrouhlování a absolutní hodnota pro typ double Běžné matematické funkce pro ostatní reálné typy Co je to strojové nekonečno Obsahuje tato implementace strojové nekonečno? Jak získat strojové nekonečno Když je výsledek matematické funkce nekonečný Co jsou to denormální čísla Podporuje tento typ denormální čísla? (C++) Je daný výsledek denormální, tedy méně přesný? Co je to NaN NaN mohou vracet i naše vlastní funkce Je to NaN? Klasifikace reálných čísel (C99)
Příkazy 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
K1784.indd 20
Potřebujeme několik příkazů na místě, kde smí být jeden Nechceme žádný příkaz na místě, kde má nějaký být Deklarace a příkazy v bloku v C90 a starších Deklarace a příkazy v bloku v C99 a v C++ Výraz jako příkaz Deklarace je v C++ příkaz Chceme provést akci, jen když je splněna podmínka Rozhodování mezi dvěma alternativami (příkaz if) Příkaz vnořený do if tvoří vždy blok Ke kterému if patří to else? V podmínce můžeme deklarovat proměnnou (jen C++) Větvení programu podle většího počtu hodnot (příkaz switch) Rozdělení příkazu switch na alternativy (příkaz break) Příkaz switch nebývá přehledný Náhrada příkazu switch polem Náhrada příkazu switch polymorfizmem Opakujeme skupinu příkazů: cyklus Tělo cyklu je blok Testujeme podmínku před vstupem do těla cyklu Zjišťujeme počet nenulových prvků pole (cyklus while) V podmínce příkazu while můžeme deklarovat proměnnou (jen C++) Čteme znaky z klávesnice až po zadaný znak (cyklus do-while) Jak funguje příkaz for
231 231 232 232 232 233 233 233 234 234 234 234 234 235
237 237 237 237 237 238 238 238 239 239 239 240 240 240 241 241 242 242 242 242 243 243 243 244
22.7.2010 7:34:24
Obsah
577 578 579 580 581 582 583 584 585 586 587 588
V inicializaci příkazu for můžeme deklarovat proměnnou (C99 a C++) Řetězec pozpátku (deklarace několika proměnných v inicializaci) Co můžeme použít jako podmínku Nekonečný cyklus Cyklus s podmínkou uprostřed (jak předčasně opustit cyklus) Nedokončený průchod cyklem (příkaz continue) Příkaz skoku (goto) Proč nepoužívat příkaz goto Tolerované použití příkazu goto Návrat z funkce (příkaz return) Příkaz asm (jen C++) Příkaz asm ve Visual C++ a v C++Builderu
Výrazy a operátory 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
K1784.indd 21
Každý operátor má svou prioritu Jaké existují úrovně priority Operátor má také asociativitu Neváhejme používat závorky Priorita a asociativita neurčuje pořadí vyhodnocování operandů Kdy je pořadí vyhodnocování pevně dáno Když použijeme operátor ++ nebo -- dvakrát na stejnou proměnnou Co jsou to sekvenční body Přiřazení je výraz Složené přiřazovací operátory Přiřazení vs. porovnání Přístup k zastíněné globální proměnné (C++) Zjišťujeme velikost proměnné nebo typu Operátor sizeof vyhodnocuje zpravidla překladač Volání funkce Nejdřív si připravíme data, pak vyhodnotíme podmínku (operátor čárka) Unární aritmetické operátory a typ výsledku Binární aritmetické operátory a typ výsledku v C++ a v C90 Binární aritmetické operátory a typ výsledku v C99 Jak se určí typ aritmetického výrazu Výsledky nás mohou překvapit Někdy neplatí asociativní ani komutativní zákon Jak na přetypování v jazyce C Jak na přetypování v C++
21
244 245 245 245 246 246 246 247 247 247 247 248
249 249 249 249 250 250 250 251 251 251 252 252 253 253 253 254 254 255 255 256 256 256 257 257 257
22.7.2010 7:34:24
22
Obsah
Výčtové typy 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
Výčtový typ pro dny v týdnu – nejjednodušší deklarace Deklarace proměnné výčtového typu Proměnnou lze deklarovat v deklaraci typu Když nechceme v jazyce C psát enum Co jsou to výčtové konstanty Když nám implicitně přidělené hodnoty konstant nevyhovují Výčtovou konstantu můžeme definovat pomocí předchozí konstanty Výčtový typ pro příznaky Jména výčtových typů Čárka na konci seznamu konstant Výčtový typ v programu Výčtový typ v C a v C++: Hlavní rozdíl Jaké hodnoty může obsahovat proměnná výčtového typu Anonymní výčtový typ Výčtový typ jako náhrada konstanty
Struktury a unie 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
K1784.indd 22
Skupina proměnných jako jeden celek (struktura) Proměnné sdílejí místo v paměti Deklarace struktury Deklarace unie Jméno struktury nebo unie v C a v C++ Když nechceme v jazyce C psát struct nebo union Když použijeme typedef, můžeme jmenovku vynechat V deklaraci typu můžeme deklarovat proměnnou Když dvě struktury odkazují na sebe navzájem Přístup ke složkám struktur a unií Ukazatel na strukturu nebo unii Inicializace struktury Inicializace unie Inicializace struktury v C99 Inicializace unie v C99 Literál typu struktura nebo unie (jen C99) Uložení struktury v paměti, velikost struktury Jak zjistit velikost unie Práce s jednotlivými bity (bitová pole) Uložení bitových polí v paměti
259 259 259 259 259 260 260 260 260 261 261 261 262 262 262 263
265 265 265 265 266 266 266 267 267 267 268 268 268 268 269 269 269 270 270 270 271
22.7.2010 7:34:24
Obsah
648 649 650 651 652
K čemu je bitové pole Bitové pole nemusí mít jméno Bitové pole nulové šířky Co nelze s bitovými poli dělat Proměnné, které sdílejí místo v paměti (anonymní unie, jen C++)
Objektový typ a jeho deklarace 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
K1784.indd 23
Co je to třída Obecné a speciální pojmy a jejich model v programu Objektově orientovaný program S daty pracujeme zásadně pomocí metod Deklarace třídy bez předků V deklaraci typu lze deklarovat instance Příklad: třída cplx Vytvoření instance Použití složek Jak vyjádřit délku pole, které je složkou třídy Právo na přístup ke složkám Význam specifikací přístupu Výjimka z přístupových práv: přátelé Co je to rozhraní třídy Přístupové metody a jejich jména K čemu jsou dobré přístupové metody Datové složky instancí Metody instancí Jak metoda ví, se kterou instancí pracuje? Metody, které lze použít pro konstantní instance Datové složky třídy Deklarace datové složky třídy jako celku (statické datové složky) Použití statické datové složky mimo její třídu Statické konstantní složky Význačné hodnoty jako statické datové složky Metody třídy jako celku (statické metody) Statické metody nemají this Volání statické metody Také konstruktor je metoda třídy jako celku Metoda definovaná v těle je inline V metodě používáme složky i metody téže instance bez kvalifikace
23
271 271 271 271 272
273 273 273 273 274 274 274 275 275 276 276 277 277 277 278 278 278 279 279 279 280 280 281 281 282 282 282 283 283 283 284 284
22.7.2010 7:34:24
24
684 685 686 687 688 689 690 691 692 693 694 695 696 697
Obsah
Ve statické metodě nelze používat datové složky instancí bez kvalifikace Typ jako složka třídy Vnořené a obklopující třídy jsou si cizí Třída je obor viditelnosti Vnořená třída je v oboru obklopující třídy Šablona jako složka třídy Některé metody vytvoří překladač sám Předběžná deklarace třídy Struktura jako objektový typ Unie jako objektový typ Třída definovaná v těle metody nebo funkce (lokální třída) Velikost instance Měnitelné složky konstant Deklarovaná, ale nedefinovaná metoda
Vytvoření instance 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
K1784.indd 24
Deklarace konstruktoru Omezení kladená na konstruktor Lze instanci inicializovat jako neobjektovou strukturu? Inicializační část konstruktoru Inicializační část konstruktoru není povinná V jakém pořadí inicializace probíhají Volání konstruktoru složky Konstantní a referenční složky Deklarace instance znamená volání konstruktoru Konstruktor nelze volat jako ostatní metody Překladač si může vytvořit konstruktor sám Kdy si překladač konstruktor nevytvoří Konstruktor bez parametrů, konstruktor s jedním parametrem Automatické konverze pomocí konstruktoru Konverzní konstruktor Explicitní konverze pomocí konstruktoru Když nechceme, aby konstruktor sloužil k implicitním konverzím Parametrem konstruktoru je délka pole Kopírovací konstruktor Explicitní vytvoření instance Optimalizace vracené hodnoty Konstruktor nemůže volat jiný konstruktor
284 284 285 285 285 286 286 286 286 287 287 287 288 288
289 289 289 289 290 290 290 291 291 291 292 292 292 293 293 293 293 294 294 294 295 295 295
22.7.2010 7:34:24
Obsah
720 721 722 723 724 725 726 727 728
Dva konstruktory sdílí část kódu: jak se neopakovat V několika metodách se opakují stejné úvodní a závěrečné operace (hlídka) Dynamická instance Explicitní volání konstruktoru pro dané místo Jak zakázat vytváření instancí všem Jak zakázat vytváření instancí klientskému programátorovi Co je to tovární metoda Konstruktor a výjimky „Konstruktory“ základních typů (pseudokonstruktory)
Kopírování instancí 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
K1784.indd 25
Mělká a hluboká kopie Instance třídy obsahující dynamické pole Vytvoření nové instance, která je kopií existující instance Volání kopírovacího konstruktoru Inicializace instance výrazem jiného typu Když do hry s konstruktory vstoupí přístupová práva Překladač může optimalizovat Implicitní kopírovací konstruktor Kdy překladač nevytvoří kopírovací konstruktor Kopírovací přiřazovací operátor Typický problém, když instance obsahuje ukazatel na pole Implicitní přiřazovací operátor Kdy překladač nevytvoří přiřazovací operátor Přiřazovací operátor by měl vracet *this Třída vektor: příklad deklarace přiřazovacího operátoru Pole proměnné délky, chybná implementace Rovnost při přiřazování Ochrana proti přiřazení sebe sobě Jaké problémy mohou nastat, když kopírování hodnot může vyvolat výjimku Jak zvládnout možné výjimky při kopírování dat Příklad transakčního kopírování: vektor Jak zabránit kopírování Předávání parametrů objektových typů hodnotou Vracení výsledku funkce
25
296 296 297 297 297 298 298 298 298
299 299 299 299 299 300 300 301 301 301 301 302 303 303 303 303 304 304 305 305 306 306 306 307 307
Zánik instance
309
Co je to destruktor
309
22.7.2010 7:34:25
26
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
Obsah
Deklarace destruktoru Implicitní destruktor Kdy překladač nedokáže implicitně definovat destruktor Implicitní volání destruktoru Explicitní volání destruktoru Destruktor může být virtuální Omezení kladená na destruktor Proč by se z destruktoru neměly šířit výjimky Jak dlouho žije lokální automatická instance Jak dlouho žije globální instance Jak dlouho žije lokální statická instance Jak dlouho žije dynamická instance Jak dlouho žijí pomocné instance Jak dlouho žijí pomocné instance, které slouží k inicializaci referencí Jak dlouho žije pomocná proměnná vytvořená v inicializační části konstruktoru V jakém pořadí se volají destruktory složek „Destruktory“ vestavěných typů (pseudodestruktory) Je destruktor volán v době hledání obsluhy výjimky?
Dědění a polymorfizmus 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
K1784.indd 26
Dědění neboli specializace Potomek může zastoupit předka Instance má několik typů Vícenásobné dědění Deklarace třídy s předky Kdo může být předkem Které metody se nedědí Volání konstruktoru předka Specifikátor přístupu ve specifikaci předků Třída je obor viditelnosti Zastínění zděděné metody Jak se dovoláme zastíněné metody Jak zabráníme zastínění metody předka Zveřejnění chráněné metody předka Přiřazení potomka předkovi („ořezání dat“) Přiřazení ukazatele na potomka ukazateli na předka Časná a pozdní vazba Jak deklarovat metodu s pozdní vazbou
309 309 309 310 310 310 310 310 311 311 311 311 311 312 312 313 313 313
315 315 315 315 315 316 316 316 317 317 318 318 318 319 319 320 320 321 321
22.7.2010 7:34:25
Obsah
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
Jak překrýt virtuální metodu předka Kdy se uplatňuje pozdní vazba Volání virtuální metody předka Polymorfní třída Potřebujeme, aby třída byla polymorfní Kreslení grafického objektu: abstraktní metoda, abstraktní třída Deklarace abstraktní metody Omezení kladená na abstraktní třídy Čistě virtuální funkce může mít definici Potřebujeme, aby třída byla abstraktní Různé druhy metod ve společném předkovi Přetypování ukazatele na potomka na ukazatel na předka Konflikty jmen v odvozených třídách Pozdní vazba: pohled pod pokličku Volání virtuálních metod z konstruktorů a destruktorů Co se děje při konstrukci a destrukci instance polymorfní třídy Virtuální dědění Volání konstruktoru virtuálního předka Pořadí volání konstruktorů předků při virtuálním dědění Přetypování na potomka
Objektový návrh 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
K1784.indd 27
Třídy a jejich vztahy Co jsou to návrhové vzory Proč využívat skládání Co je to rozhraní Rozhraní v C++ Úsečka jako potomek bodu? Technické dědění Je dědění v tomto případě vhodné? Třídy vyhovují testu JE – MÁ. Stačí to? Substituční princip Barbary Liskovové Přetížená třída Princip jediné zodpovědnosti Příliš mnoho tříd Když nechceme zveřejnit konstruktory (tovární metoda) Když nechceme, aby od naší třídy bylo možno odvodit potomka Chceme jedinou instanci
27
321 322 322 322 323 323 323 324 324 324 325 325 326 326 327 328 328 329 330 330
331 331 331 331 331 332 332 332 333 333 333 334 334 334 335 335 336
22.7.2010 7:34:25
28
826 827 828 829 830 831 832
Obsah
Zásobník jako potomek seznamu? Jak použít adaptér Oddělujeme rozhraní od implementace Implementace stromu: schematický příklad mostu Nechceme být vázáni na jedinou implementaci Kontejner a alokace paměti Oddělujeme kontejner od algoritmu
Přetěžování operátorů 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
K1784.indd 28
Co je to přetěžování operátorů Které operátory nelze přetěžovat Operátory, které lze přetěžovat jen jako metody Operátory new a delete a ostatní operátory Přetěžování operátorů a srozumitelnost programu Přetěžování operátorů: základní vodítka Jak přetěžujeme binární operátory Jak přetěžujeme unární operátory Když překladač uvidí operátor Použití operátoru Třída cplx pro příklady Sčítání komplexních čísel Operátor jako metoda: Operandy nejsou rovnocenné Chceme, aby operandy byly rovnocenné Sčítání komplexních čísel bez deklarace friend Když je rychlost důležitá, definujeme další verzi operátoru Operátory ++ a -Co je „prefixovost“ a „postfixovost“ operátorů ++ a -Prefixový operátor ++ pro výčtový typ Postfixový operátor ++ pro výčtový typ Unární minus pro komplexní čísla Unární plus pro komplexní čísla Chovají se přetížené operátory stejně jako standardní operátory? Přiřazovací operátor nemusí jen kopírovat Jak je to s operátory @= Někdy je lepší definovat nejprve @= a teprve pak operátor @ Chceme indexovat instanci Přístup ke složkám komplexního čísla pomocí indexů Přístup ke složkám komplexní konstanty pomocí indexů
336 336 337 337 338 338 339
341 341 341 341 341 341 342 342 343 343 343 343 344 344 344 345 345 346 346 347 347 347 347 348 348 349 349 350 350 350
22.7.2010 7:34:25
Obsah
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
Operátor volání funkce Přístup k prvkům matice: volání funkce místo indexování Konverzní operátor (konverzní funkce) Konverze komplexního čísla na reálné Operátor -> Chytrý ukazatel Jak přetížit operátor new pro alokaci jedné instance Jak přetížit operátor new pro alokaci pole Globální new lze nahradit Jak přetížit operátor delete pro uvolnění jedné instance Jak přetížit operátor delete pro uvolnění pole instancí Globální delete lze nahradit Rozdíl mezi použitím operátoru a voláním operátorové funkce Alokace instance Alokace pole Použití třídního new a delete Použití globálního new a delete Když opravdu chceme nahradit globální new Náhrada globálního delete Operátor new s dodatečnými parametry Operátor delete s dodatečnými parametry
Zpracování chybových stavů 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897
K1784.indd 29
Dlouhý skok v jazyce C Proměnná pro záznam stavu prostředí v místě návratu Místo, kam se chceme vrátit Vlastní dlouhý skok Co dlouhý skok umí a co ne Návratové hodnoty indikující chybu Jak používat proměnnou errno Samotná kontrola errno nestačí Co se vlastně stalo Co je to výjimka v C++ Pouze synchronní výjimky Třídy pro přenos informací o výjimce Terminologické zmatky Logické a běhové chyby Další třídy výjimek
29
351 351 352 352 352 353 353 353 354 354 355 355 356 356 356 357 357 357 358 358 359
361 361 361 361 362 362 362 363 363 363 363 364 364 365 365 365
22.7.2010 7:34:25
30
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
Obsah
Vyvolání výjimky Šíření výjimky Úklid zásobníku Zachycení a ošetření výjimky Rozdělení kódu na normální běh a obsluhu chyb Pořadí obsluh Chceme zachytit všechny výjimky Obsluha se hledá podle typu, ale bez konverzí Bližší informace o výjimce Částečné ošetření výjimky Specifikace výjimek v hlavičce funkce Když se z funkce rozšíří neočekávaná výjimka Funkce, kterou volá unexpected() Když je celé tělo funkce jeden příkaz try Inicializační část konstruktoru a výjimky Výjimky, konstruktory a destruktory Specifikace výjimek a šablony Výjimka v konstruktoru složky Výjimka při alokaci dynamické instance Úniky paměti při výjimkách Automatické ukazatele Automatický ukazatel a výjimky
Jmenné prostory 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
K1784.indd 30
Deklarace jmenného prostoru Knihovny umísťujeme do jmenných prostorů Deklaraci jmenného prostoru můžeme rozdělit Přístup k součástem jmenných prostorů Uvnitř jmenného prostoru nemusíme kvalifikaci používat Jak se dovoláme proměnné, která neleží v prostoru jmen Uvnitř jmenného prostoru stačí deklarace Jiné jméno jmenného prostoru Když nechceme psát zdlouhavé kvalifikace (deklarace using) Zpřístupňujeme celý jmenný prostor Direktiva using je tranzitivní Také jména zpřístupněná deklarací using se direktivou using „pošlou dál“ Anonymní jmenné prostory Skrýváme jméno a nechceme použít klíčové slovo static Jak překladač hledá volanou funkci nebo operátor
366 366 366 367 367 368 368 368 369 369 369 370 370 371 371 371 372 372 372 373 373 374
375 375 375 375 375 376 376 377 377 377 378 378 379 380 380 380
22.7.2010 7:34:25
Obsah
935
Princip rozhraní
Šablony 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
K1784.indd 31
Šablony jako lepší makra Definice šablony volné funkce Deklarace šablony volné funkce Formální parametry šablony Šablonové parametry šablony funkce Skutečné parametry šablony Implicitní vytvoření instance šablony funkce Šablona nenahrazuje prototyp Jak zavolat šablonovou funkci s parametry jiného typu Explicitní vytvoření instance šablony funkce Přetěžování šablon funkcí Specializace šablony volné funkce Ukazatel na instanci šablony Šablona objektového typu Použití šablonových parametrů šablony objektového typu Instance šablony objektového typu Implicitní hodnoty parametrů šablony Jeden parametr lze použít jako implicitní hodnotu dalšího Instance šablony jako parametr jiné šablony Šablony metod Šablona konstruktoru Statická datová složka Které součásti se vytvoří, když se vytvoří instance šablony třídy Slučování instancí Šablona jako složka třídy Šablona jako složka šablony třídy Co se podle vnořené šablony nevytvoří Dvojí čtení Jak napovědět, že jde o vnořený typ Jak napovědět, že jde o šablonu Různé instance šablony objektového typu jsou různé třídy Spřátelené funkce a šablony Šablony jako přátelé: příklad s lomenými závorkami Šablony jako přátelé: příklad (kvalifikovaná jména) Zvláštní případy šablony objektového typu Příklad primární šablony: obecná dvojice
31
381
383 383 383 383 384 384 384 385 385 386 386 386 387 387 387 388 388 388 389 389 390 390 391 391 391 392 392 393 393 393 393 394 394 395 395 396 396
22.7.2010 7:34:25
32
972 973 974 975 976 977 978 979
Obsah
Příklad částečné specializace: dvojice ukazatelů Příklad explicitní specializace: dvojice ukazatelů typu void* Různé počáteční hodnoty statických složek pro různé parametry Nepodařené dosazení není chyba Šablona jako aserce Šablona jako nástroj pro zobrazení čísla na typ Šablona jako nástroj pro zobrazení typu na typ Překladač vypočte faktoriál
Práce s datovými typy 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
K čemu je dynamická identifikace typů Jak použít operátor typeid Pro nepolymorfní typy určí operátor typeid statický typ Chceme-li dynamický typ, musí být třídy polymorfní Použití operátoru typeid k určení typu Kdy (ne)používat operátor typeid Nové přetypované operátory Jak se nové přetypované operátory používají Běžná přetypování Modifikátory const a volatile Podivná přetypování Jak funguje operátor dynamic_cast Přetypování ukazatele na předka na ukazatel potomka Přetypování reference na předka na referenci na potomka Patří skutečný typ instance mezi potomky jisté třídy? Adresa celého objektu Přetypování na „sousední třídu“ Co když předáme ukazatel s hodnotou 0 Přetypování na virtuálního potomka Co je to přístupný předek Co je to jednoznačný předek
Vstupní a výstupní operace v jazyce C 1001 1002 1003 1004 1005 1006
K1784.indd 32
Co je to datový proud Struktura FILE Standardní datové proudy v jazyce C Otevření datového proudu Binární a textový soubor, binární a textový režim Čtení a zápis v textovém režimu
397 398 398 399 399 400 400 400
403 403 403 403 404 404 405 405 405 406 406 406 407 407 408 408 409 409 410 410 411 411
413 413 413 414 414 415 415
22.7.2010 7:34:25
Obsah
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
K1784.indd 33
Když se operace nepodaří (EOF, WEOF a wint_t) Uzavření proudu Orientace datového proudu na široké a úzké znaky Změna orientace proudu Neformátovaný zápis do souboru Neformátované čtení ze souboru Aktuální pozice v proudu Aktualizace souboru Přečtení jednoho bajtu (znaku) Zápis jednoho bajtu (znaku) Zápis znakového řetězce Čtení jednoho znaku ze standardního vstupu Zápis jednoho znaku do standardního výstupu Vrácení jednoho znaku do proudu Čtení přímo z klávesnice (nestandardní řešení) Čtení funkčních kláves Formátovaný zápis Formátovací řetězec funkce fprintf() Specifikace konverze pro funkci fprintf() Určení typu ve specifikaci konverze pro funkci fprintf() Specifikace konverze pro další celočíselné typy z C99 Specifikace velikosti pro funkci fprintf() Příznak pro funkci fprintf() Alternativní tvar výstupu (příznak #) Šířka vystupující hodnoty Přesnost ve specifikaci konverze pro funkci fprintf() Tisk tabulky funkce Formátovaný výstup na konzolu Zápis do znakového řetězce Výpis parametrů předaných na místě výpustky Když pracujeme se širokými znaky Formátované čtení Formátovací řetězec Specifikace konverze pro funkci fscanf() Specifikace typu pro funkci fscanf() Specifikace konverze pro další celočíselné typy v C99 Čteme celá čísla Čteme jeden znak pomocí fscanf()
33
415 416 416 416 416 417 418 418 419 419 419 419 420 420 421 421 421 422 422 423 423 424 425 425 426 426 427 427 427 428 428 428 429 429 430 430 431 431
22.7.2010 7:34:25
34
Obsah
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
Čteme řetězec pomocí fscanf() Čteme jen vybrané znaky Čteme reálná čísla Specifikace velikosti Nechceme uložit načtenou hodnotu (potlačené přiřazení) Další funkce pro formátované čtení úzkých znaků Funkce pro formátované čtení širokých znaků Jak zjistit stav proudu Jsme na konci souboru? Spláchnutí vyrovnávací paměti
431 432 432 432 433 433 433 433 434 434
Vstupní a výstupní operace v jazyce C++
435
Třídy objektových datových proudů K čemu jsou tyto třídy dobré Připravené instance proudových tříd Formátované čtení a zápis: první přiblížení Formátované čtení a zápis podrobněji Hlavičkové soubory Proud jako parametr nebo výsledek funkce Otevření datového proudu pro čtení ze souboru Jaké existují režimy otevření Podařilo se otevření? Podařila se poslední operace? Čteme z textového souboru, dokud je co číst Čteme, dokud načtené hodnoty splňují danou podmínku Příznaky chyb v datových proudech Co se stane pri zjištění chyby Odstranění příznaků chyby Výjimka jako reakce na chybu Chceme načíst následující znak Chceme načíst skupinu znaků Chceme při čtení přeskočit bílé znaky Chceme načíst celý řádek a známe délku Chceme načíst soubor po řádcích a neznáme jejich délku Otevření souborového proudu pro výstup Formátování výstupu: manipulátory Tiskneme tabulku funkce Vstup a výstup vlastních datových typů Operátor pro výstup komplexních čísel
435 435 436 436 437 437 437 438 438 439 439 439 440 440 440 441 441 441 442 442 442 443 443 445 446 446
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
K1784.indd 34
22.7.2010 7:34:26
Obsah
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
Operátor <<, který respektuje zadanou šířku Vlastní výstupní manipulátor bez parametrů: vložení 5 mezer Operátor pro vstup komplexních čísel Operátor >> kontrolující formát vstupních dat Uzavření proudu Výstup v šestnáctkové soustavě Čtení v šestnáctkové soustavě Spláchnutí proudu Svázané proudy Neformátovaný výpis jednoho nebo několika znaků Jaký znak je na řadě? Přeskočíme několik znaků Zjištění a změna aktuální pozice v proudu Vyrovnávací paměť proudu Přesměrování objektového datového proudu
35
446 447 447 448 448 448 449 449 449 450 450 450 450 451 451
Na přiloženém CD naleznete Kontejnery ve standardní knihovně 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
K1784.indd 35
Co jsou kontejnery a jak se dělí Jaké posloupnosti máme v STL k dispozici Jaké asociativní kontejnery máme k dispozici Další kontejnery Současná verze STL není úplná Jak používat kontejnery z STL: parametry šablony Jak používat kontejnery z STL: konstruktory Jak používat kontejnery ze STL: metody Jak používat kontejnery z STL: zveřejňované datové typy Typy zveřejňované frontou a zásobníkem Co jsou to iterátory Proč máme různé kategorie iterátorů Rozdělení iterátorů v STL Dereferencování iterátorů Vlastnosti vstupních iterátorů Vlastnosti výstupních iterátorů Vlastnosti dopředných iterátorů Vlastnosti obousměrných iterátorů
453 453 453 454 454 454 455 455 455 456 456 457 457 457 458 458 458 458 459
22.7.2010 7:34:26
36
Obsah
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
Vlastnosti iterátorů pro náhodný přístup Platnost iterátorů Co lze ukládat do kontejnerů z STL Jak se ukládají data do kontejneru Vkládáme data do vektoru Počáteční kapacita vektoru Výpis všech prvků vektoru Přístup k prvkům vektoru Odstranění prvku z vektoru Chceme jen tolik paměti, kolik potřebujeme Tabulka proměnných: mapa Vytvoření nové proměnné: přidání prvku do mapy Přístup k prvkům mapy Výpis obsahu mapy Hodnota na vrcholu zásobníku Prvek v čele fronty Proč dvě metody?
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
K1784.indd 36
459 459 460 460 460 460 461 461 462 462 462 463 463 463 464 464 465
Algoritmy ve standardní knihovně
467
Predikáty a funktory Třídění neboli řazení v jazyce C Třídění neboli řazení v C++ Řazení vektoru Řazení typů, pro které není definována relace < Stabilní řazení Částečné řazení Částečné řazení kopie posloupnosti Řazení seznamu k-tý prvek podle velikosti Otočení obsahu posloupnosti Náhodné promíchání prvků kontejneru První prvek s danou hodnotou První prvek splňující danou podmínku První prvek z dané množiny Počet prvků se zadanou hodnotou Počet prvků vyhovujících dané podmínce Kopírování do jiného kontejneru Odstranění prvků s danou hodnotou
467 467 468 468 468 469 469 470 470 471 471 472 472 472 473 473 474 474 475
22.7.2010 7:34:26
Obsah
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
Kopírování prvků, které splňují danou podmínku Transformace všech prvků v kontejneru po jednom Fibonacciova čísla: transformace prvků po dvou Procházíme postupně permutace prvků Binární vyhledávání Kam vložit nový prvek? Vyplňujeme kontejner zadanou hodnotou Vyplňujeme kontejner generovanými hodnotami Sloučení dvou setříděných úseků Sloučení dvou setříděných úseků na místě Množiny a operace s nimi Je A podmnožinou B? Průnik množin A a B Větší nebo menší ze dvou hodnot Nejmenší nebo největší prvek v daném úseku kontejneru Prohození obsahu dvou proměnných Prohození úseků dvou kontejnerů Prohození obsahu kontejnerů Standardní predikáty Funkční objekt vracející větší ze dvou hodnot Další iterátory Kopírování přímo do proudu
Lokální nastavení v C a v C++ 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185
K1784.indd 37
Čeho všeho se lokální nastavení týká Lokální nastavení v jazyce C Lokální nastavení v C++ Jméno lokálního nastavení Kódové stránky Výpis textu do souboru v daném kódování (jazyk C) Čtení textu ze souboru v daném kódování (jazyk C) Výpis textu do souboru v daném kódování pomocí objektových proudů (C++) Čtení textu ze souboru v daném kódování pomocí objektových datových proudů (C++) Výpis českého textu na konzolu a čtení z ní Abecední řazení: obecné problémy Abecední řazení v češtině Porovnání dvou řetězců podle pravidel abecedního řazení v C Abecední řazení pole řetězců v jazyce C
37
475 475 476 476 477 477 478 478 479 479 480 480 481 481 481 482 482 483 483 484 484 485
487 487 487 488 488 489 489 489 490 490 490 491 491 492 492
22.7.2010 7:34:26
38
Obsah
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
Abecední porovnání dvou instancí typu string v C++ Abecední řazení pole řetězců v C++ Formátování čísel v jazyce C Údaje o nastavených hodnotách pro formátování čísel Formátování čísel při výstupu v C++ Čtení formátovaných čísel v C++ Převody mezi úzkými a širokými znaky Fazety lokálního nastavení Jak použít fazetu lokálního nastavení Zjištění systémového času a data Formátování data a času: funkce strftime nebo wcsftime() Výpis aktuálního data a času Formátovací řetězec pro strftime() [37-26] Význam specifikací konverzí pro funkci strftime() Modifikátory E a O Nestandardní modifikátor # (Visual C++) Počítání týdnů v roce podle ISO 8601 Datum ve formátu ISO 8601 Identifikátory v programech
Komplexní čísla 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
K1784.indd 38
Základní pojmy Datové typy pro komplexní čísla v C99 a odpovídající reálné typy Imaginární čísla (C99) Základní matematické operace s komplexními čísly Imaginární jednotka (C99) Alternativní modifikátory (C99) Deklarace proměnné s inicializací (C99) Reálná a imaginární část (C99) Vstup a výstup komplexních čísel (C99) Komplexně sdružené číslo (C99) Konverze mezi typy komplexních čísel (C99) Konverze mezi komplexními, reálnými a ryze imaginárními čísly (C99) Matematické funkce (C99) Poznámky k inverzním trigonometrickým funkcím pro komplexní čísla (C99) Poznámky k inverzním hyperbolometrickým funkcím pro komplexní čísla (C99) Poznámky k dalším funkcím pro komplexní čísla (C99) Goniometrický tvar komplexního čísla
493 493 494 494 494 495 495 496 496 496 497 497 498 498 500 500 500 501 501
503 503 503 503 503 504 504 504 504 505 505 505 505 506 506 506 507 507
22.7.2010 7:34:26
Obsah
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
Komplexní čísla v C++ Deklarace komplexní proměnné Konverze komplexních čísel (C++) Přiřazování komplexních čísel Aritmetické operace pro komplexní čísla (C++) Relace pro komplexní čísla (C++) Reálná a imaginární část komplexního čísla (C++) Vstup a výstup komplexních čísel pomocí objektových proudů (C++) Matematické funkce pro komplexní čísla (C++) Komplexně sdružené číslo Goniometrická reprezentace komplexního čísla (C++) Vytvoření komplexního čísla na základě goniometrické reprezentace (C++)
C++0x 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
K1784.indd 39
Co je C++0x Podpora C++0x v překladači g++ Nové znakové typy a řetězcové literály Ukazatel nikam Nová podoba příkazu for (foreach) Zapomeňte na klíčové slovo auto pro paměťovou třídu Jsme líní specifikovat typ proměnné Reference na r-hodnotu Aserce v době překladu Inicializace kontejnerů Volání jiného konstruktoru téže třídy Inicializace složek v deklaraci Když nevíme přesně typ Alternativní zápis deklarace funkce Funkce, jejíž typ výsledku závisí na několika parametrech šablony Co je to lambda-výraz Transformace vektoru (nepojmenovaná funkce v C++0x) Lambda-výraz Okolní proměnné Podrobnější specifikace záchytu Jakého typu je lambda-výraz Deklarace šablony s proměnným počtem parametrů Definice šablony s proměnným počtem parametrů Speciální funkce ve standardní knihovně
39
507 508 508 508 508 509 509 509 509 510 510 510
511 511 511 511 511 512 512 512 513 513 513 514 514 514 514 515 515 516 516 517 517 518 518 518 519
22.7.2010 7:34:26
40
Obsah
Několik tipů na závěr 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
K1784.indd 40
Několik slov o optimalizaci Standard popisuje pozorovatelné chování Ukazatele na metody Jak získáme ukazatel na metodu Třídní ukazatel na datové složky Jak získáme hodnotu třídního ukazatele na datovou složku Dereferencování třídního ukazatele na metodu Dereferencování třídního ukazatele na datovou složku A co statické metody a složky? Třídní ukazatele a pozdní vazba Třídní ukazatele: pohled pod pokličku Jak zjistit aktuální čas Jak zjistit čas procesu Přesnější měření času (nestandardní řešení) Typově generická makra V C99 Generování náhodných čísel Randomizace náhodné posloupnosti Generátory náhodných čísel v C++: hudba budoucnosti Náhrada operátorů Co jsou to signály Obsluha signálu Vyvolání signálu Čtení z paměťového proudu Zápis do paměťového proudu Chceme přejmenovat soubor Chceme odstranit soubor Potřebujeme dočasný soubor Jak vytvořit platné jméno dočasného souboru Co zavádí tato deklarace?
521 521 521 522 522 522 523 523 523 524 524 524 524 525 525 525 525 526 526 526 527 527 527 528 528 528 528 529 529 529
22.7.2010 7:34:26
Úvod Začnu velmi osobně: Když jsem poznal jazyk C, začalo se mi programování líbit, ale jeho skutečnou krásu jsem pochopil, až když jsem porozuměl jazyku C++. Něco z tohoto pocitu jsem se pokusil zprostředkovat vám v této knize. Najdete v ní více než 1000 tipů a triků, které můžete využít při programování v těchto dvou jazycích. Najdete tu jak základní obraty, které ocení začátečníci, tak i věci, které se budou hodit pokročilým programátorům při řešení speciálních úloh. Nesnažil jsem se napsat učebnici C nebo C++. Mým cílem bylo ukázat programátorské obraty a známé či méně známé knihovní nástroje, bez nichž se programátor v C++ při seriózním programování neobejde. V případech, kdy to má smysl, ukazuji jak řešení v C, tak i řešení v C++. Při psaní jsem převážně vycházel z platných standardů obou jazyků [ISOC] a [ISOCPP]. Uvádím ovšem i některá běžná nestandardní rozšíření; skutečnost, že nejde o součást standardu a tedy že řešení, které je na tom založeno, nemusí být přenositelné, vždy výslovně zdůrazňuji. V některých případech se také zmiňuji o očekávaných rozšířeních v příští verzi standardu. Při psaní jsem vycházel především ze zkušeností s těmito komerčními vývojovými prostředími a překladači:
CodeGear C++Builder2009 a překladač bcc32, Microsoft Visual C++ 2008 a překladač cl. Vedle toho jsem měl k dispozici nekomerční překladač g++, který je součástí MinGW32 verze 3.4.5 a je šířen pod licencí Lesser GPL. V době korektur jsem měl také již ostrou verzi překladače Microsoft Visual C++ 2010. V celé knize používán označení C90 pro implementaci jazyka C podle standardu ISO 9899 z roku 1990, která je stále široce používána, a označení C99 pro implementaci podle současného standardu ISO 9899 z roku 1999. Na závěr bych chtěl poděkovat všem, kteří svými radami a připomínkami přispěli ke zdárnému dokončení tohoto díla.
Komu je kniha určena Každý tip a trik je v knize označen pomocí jedné ze tří úrovní pokročilosti, které po čtenářích buď vyžadují, nebo nevyžadují určité znalosti C++. Kniha je tak vhodná pro všechny skupiny programátorů. začátečník
Vyžaduje základní orientaci v C++
Předpokládá pokročilé znalosti jazyka C++, které rozšiřuje. pokročilý
Předpokládá velmi dobré znalosti C++, popisuje pokročilé a rafinované postupy. znalec
K1784.indd 41
22.7.2010 7:34:26
42
Úvod
Doprovodné CD Doprovodný disk obsahuje kromě zdrojových kódů také řadu odkazů na užitečné stránky a také několik užitečných nástrojů, jež vám programování v jazyce C++ výrazně usnadní nebo alespoň zpříjemní. Najdete na něm také instalační programy vývojových prostředí, která jsou v knize zmíněna. CD stačí vložit do počítače a rozhraní se spustí automaticky. Pokud nemáte automatické spouštění disků povoleno, vyhledejte na CD kořenový adresář a otevřete soubor spustit_CD.html. Jestliže rozhraní CD otevřete v prohlížeči Internet Explorer, Opera nebo Google Chrome, budete z CD moci instalovat doprovodný software okamžitě. V případě jiných prohlížečů se zobrazí výzva k uložení instalačního souboru na pevný disk. V tomto případě doporučujeme spustit instalaci přímo z CD. Obsah CD najdete ve složce obsah.
K1784.indd 42
22.7.2010 7:34:27