Programování v C++ David Bednárek. www.ksi.mff.cuni.cz/~bednarek



Podobné dokumenty
PROGRAMOVACÍ JAZYKY A PŘEKLADAČE STRUKTURA PŘEKLADAČE

Šablony, kontejnery a iterátory

Šablony, kontejnery a iterátory

PROGRAMOVÁNÍ V C++ CVIČENÍ

přetížení operátorů (o)

PB161 Programování v jazyce C++ Přednáška 3

Jazyk C++ II. STL knihovna kontejnery část 1

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v C++ NPRG041 Programování v C /2016 David Bednárek

PB161 Programování v jazyce C++ Přednáška 3

map, multimap - Asociativní pole v C++.

Jazyk C++ II. STL knihovna kontejnery část 2

Programování v C++ 1, 5. cvičení

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

přetížení operátorů (o)

Programování v C++ 2, 4. cvičení

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Více o konstruktorech a destruktorech

Programování v jazyce C a C++

PB161 Programování v jazyce C++ Přednáška 10

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Množina v C++ (set, multiset).

PROGRAMOVÁNÍ V C++ CVIČENÍ. Michal Brabec

Abstraktní datové typy

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Úvod do programovacích jazyků (Java)

Generické programování

PREPROCESOR POKRAČOVÁNÍ

PB161 Programování v jazyce C++ Přednáška 10

Mělká a hluboká kopie

IUJCE 07/08 Přednáška č. 1

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

PB161 Programování v jazyce C++ Přednáška 4

Matematika v programovacích

Jazyk C++ I. Šablony

Programování v C++ 3, 3. cvičení

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Jazyk C++ I. Šablony 2

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

PB přednáška (26. října 2015)

Stručný obsah První týden Druhý týden 211 Třetí týden 451 Rejstřík 787

Standardní algoritmy vyhledávací.

PB161 Programování v jazyce C++ Přednáška 9

PŘETĚŽOVÁNÍ OPERÁTORŮ

Jazyk C++, některá rozšíření oproti C

8 Třídy, objekty, metody, předávání argumentů metod

Programování v C++ 1, 1. cvičení

DTP Základy programování Úvod do předmětu

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Vector datový kontejner v C++.

Předměty. Algoritmizace a programování Seminář z programování. Verze pro akademický rok 2012/2013. Verze pro akademický rok 2012/2013

Základní datové struktury

Objektově orientované programování

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Kolekce, cyklus foreach

Úvod do programovacích jazyků (Java)

PB161 Programování v jazyce C++ Přednáška 8

Dědění, polymorfismus

Konstruktory a destruktory

Funkční objekty v C++.

Jazyk C++ II. Šablony a implementace

Abstraktní třídy, polymorfní struktury

konstruktory a destruktory (o)

Odvozené a strukturované typy dat

Teoretické minimum z PJV

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Struktura programu v době běhu

Programování v C++, 2. cvičení

Programovací jazyk C++ Hodina 1

ADT/ADS = abstraktní datové typy / struktury

Výrazy, operace, příkazy

Šablony funkcí a tříd (Templates) Genericita

PB161 Programování v jazyce C++ Přednáška 1

PB161 Programování v jazyce C++ Přednáška 7

PB161 Programování v jazyce C++ Přednáška 7

11. Přehled prog. jazyků

PB161 Programování v jazyce C++ Přednáška 6

Algoritmizace a programování

Programovací jazyk C(++) C++ area->vm_mm->locked_vm -= len >> PAGE_SHIFT;

OBJEKTOVÉ PROGRAMOVÁNÍ V C++ V PŘÍKLADECH 8 Proudová knihovna 8.1 Hierarchie proudů Standardně zavedené proudy

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Koncepce (větších) programů. Základy programování 2 Tomáš Kühr

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 /

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v C++ 1, 6. cvičení

PB161 Programování v jazyce C++ Přednáška 4

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Lineární datové struktury

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Programování v C++ Úplnej úvod. Peta (maj@arcig.cz, SPR AG )

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

Paměť počítače. alg2 1

Konec a tak. PB173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 15.

PB161 Programování v jazyce C++ Přednáška 1

Transkript:

Programování v C++ David Bednárek www.ksi.mff.cuni.cz/~bednarek

Pravidla studia NPRG041 2/2 Z,Zk

Zápis na cvičení Elektronický zápis do jednotlivých skupin is.cuni.cz/studium Zápis předmětů a rozvrhu - zápis Grupíček - výsledky Zapsáni musejí být všichni Do 18.10. Kapacita laboratoře je omezena, skupiny nelze přeplňovat Zvláštní skupina pro repetenty Repetenti kontaktují cvičícího do 18.10. Udělit zápočet může jen cvičící, ke kterému je student zapsán Kdo nebude do 18.10. zapsán, zápočet v tomto šk. roce nedostane

Udělení zápočtu Základní podmínky společné všem skupinám Úspěšné složení zápočtového testu 1. a 2. pokusy ve zkouškovém období... 3. pokusy v dubnu 2-3 hodiny v laboratoři, společně pro všechny skupiny Vypracování zápočtového programu Dohoda o tématu - do listopadu Předvedení cvičícímu do 31.3.2014 Doladění a odevzdání do 23.5.2014 Další podmínky udělení zápočtu určuje cvičící Cvičící může podmínky individuálně upravit, pokud se s ním student na začátku semestru dohodne Přiměřená účast na cvičeních Úspěšné odevzdání domácího úkolu

Zkouška Zkouška bude provedena formou abc-testu Vlastnosti a pravidla jazyka C++ Používání knihoven C++ (kontejnery, algoritmy, iostream) Typické konstrukce objektového programování Run-time/static polymorphism Termíny Ve zkouškovém období ZS Během výuky v LS

Pravidla pro budoucí neúspěšné Zkouška Pokud letos složíte zkoušku se známkou výborně nebo velmi dobře a nedostanete zápočet, bude vám příští rok uznána Zápočet Tento mechanismus je implementován zkoušejícími, nikoliv studijním oddělěním Pokud nedostanete zápočet, budete příští rok opakovat ty části, které jste letos nesplnili Podmínky splněné letos se automaticky uznávají V příštím roce se musíte na začátku semestru přihlásit v SISu k některému z cvičících a dohodnout se s ním na konkrétních podmínkách

Historie C++

Historie C++ BCPL (Cambridge 1966) B (Bell Labs. 1969) C (Bell Labs. 1971) K&R C (Kernigan & Ritchie 1978) inspirace nadmnožina C with classes (Stroustrup 1979) téměř nadmnožina významná změna The C++ programming language (Stroustrup 1985) C++98 (ISO/IEC 14882 1998) šablony C++03 (ISO/IEC 14882 2003) C++TR1 (ISO/IEC 19768 2007) paralelismus C++11 (ISO/IEC 14882 2011) C++14 (2014+)

Historie C++ a C BCPL (Cambridge 1966) B (Bell Labs. 1969) C (Bell Labs. 1971) K&R C (Kernigan & Ritchie 1978) inspirace nadmnožina C with classes (Stroustrup 1979) téměř nadmnožina významná změna ANSI C (ANSI X3J11 1989) The C++ programming language (Stroustrup 1985) C99 (ISO/IEC 9899 1999) C++98 (ISO/IEC 14882 1998) šablony C++03 (ISO/IEC 14882 2003) C++TR1 (ISO/IEC 19768 2007) C11 (ISO/IEC 9899 2011) paralelismus C++11 (ISO/IEC 14882 2011) C++14 (2014+)

Historie C++ - Objective-C BCPL (Cambridge 1966) B (Bell Labs. 1969) C (Bell Labs. 1971) inspirace nadmnožina téměř nadmnožina významná změna Objective-C (Cox & Love 1981) Object-Oriented Programing (Cox 1986) K&R C (Kernigan & Ritchie 1978) ANSI C (ANSI X3J11 1989) C with classes (Stroustrup 1979) The C++ programming language (Stroustrup 1985) C99 (ISO/IEC 9899 1999) C++98 (ISO/IEC 14882 1998) šablony Objective-C 2.0 (Apple 2006) C++03 (ISO/IEC 14882 2003) C++TR1 (ISO/IEC 19768 2007) Objective-C++ (Apple 2010) C11 (ISO/IEC 9899 2011) paralelismus C++11 (ISO/IEC 14882 2011) C++14 (2014+)

Historie C++ - významné příbuzné jazyky BCPL (Cambridge 1966) B (Bell Labs. 1969) C (Bell Labs. 1971) inspirace nadmnožina téměř nadmnožina významná změna Objective-C (Cox & Love 1981) Object-Oriented Programing (Cox 1986) K&R C (Kernigan & Ritchie 1978) ANSI C (ANSI X3J11 1989) C with classes (Stroustrup 1979) The C++ programming language (Stroustrup 1985) Java (Sun 1995) Objective-C 2.0 (Apple 2006) Objective-C++ (Apple 2010) C99 (ISO/IEC 9899 1999) C11 (ISO/IEC 9899 2011) C# (Microsoft 2002) C++/CLI (Microsoft 2005) paralelismus C++98 (ISO/IEC 14882 1998) C++03 (ISO/IEC 14882 2003) C++TR1 (ISO/IEC 19768 2007) C++11 (ISO/IEC 14882 2011) šablony C++14 (2014+)

Historie C++ - použití C v jádrech OS BCPL (Cambridge 1966) B (Bell Labs. 1969) C (Bell Labs. 1971) Unix 1973 inspirace nadmnožina téměř nadmnožina významná změna Objective-C (Cox & Love 1981) Object-Oriented Programing (Cox 1986) OS-X 2000 Objective-C 2.0 (Apple 2006) Objective-C++ (Apple 2010) Windows NT 1993 K&R C (Kernigan & Ritchie 1978) MacOS 1984 ANSI C (ANSI X3J11 1989) C99 (ISO/IEC 9899 1999) C11 (ISO/IEC 9899 2011) C with classes (Stroustrup 1979) The C++ programming language (Stroustrup 1985) Linux 1991 C# (Microsoft 2002) C++/CLI (Microsoft 2005) paralelismus C++98 (ISO/IEC 14882 1998) C++03 (ISO/IEC 14882 2003) C++TR1 (ISO/IEC 19768 2007) C++11 (ISO/IEC 14882 2011) Java (Sun 1995) šablony C++14 (2014+)

Literatura

Literatura Pro začátečníky - před C++11 Bruce Eckel: Thinking in C++ (2000) Myslíme v jazyku C++ (Grada 2000) Miroslav Virius: Pasti a propasti jazyka C++ (Computer Press 2005) Programování v C++ (ČVUT 2001) Andrew Koenig, Barbara E. Moo: Accelerated C++ (2000) Stanley B. Lippman: Essential C++ (2000)

Literatura Pro středně pokročilé - před C++11 Andrei Alexandrescu, Herb Sutter: C++ Coding Standards (2005) Scott Meyers: Effective C++ (1998) More Effective C++ (1996) Effective STL (2001) Herb Sutter: Exceptional C++ (2000) More Exceptional C++ (2002) Exceptional C++ Style (2004) Nicolai M. Josuttis: Object-Oriented Programming in C++ (2002) The C++ Standard Library (1999)

Literatura Až si budete myslet, že všechno umíte - před C++11 Andrei Alexandrescu: Modern C++ Design (2001) Moderní programování v C++ (Computer Press 2004) David Vandevoorde, Nicolai M. Josuttis: C++ Templates (2003)

Literatura C++11 Scott Meyers: Overview of the New C++ (C++11) 360 slajdů z přednášek Vysvětluje motivaci k novým vlastnostem Bjarne Stroustrup: The C++ Programming Language - Fourth Edition Addison-Wesley. ISBN 978-0321563842. May 2013 Učebnice celého C++ Zatím jediná učebnice obsahující C++11

Je lepší C++ nebo Java/C#?

Je lepší C++ nebo Java/C#? Špatná otázka

Co programovat v C++ Pro které oblasti je C++ lepší než Java/C#? Důraz na výkon C++ umožňuje programovat způsobem, který neubírá na výkonu Když budete programovat v C++ stejným stylem jako v Java/C#, dostanete přibližně stejný výkon Spolupráce s hardware C++ nechystá na programátora nepříjemná překvapení (GC etc.) Embedded assembler, spojování s jinými jazyky Spolupráce s OS Všechny významné OS mají v C jádro a tudíž i rozhraní OS Většina systémových aplikací je v C nebo C++ Nativní knihovny jazyků Java/C# jsou implementovány v C/C++ Generické programování Mechanismus šablon v C++ je silnější než v C/C++ Způsob implementace šablon v C++ neubírá na výkonu

Co programovat v C++ Programování orientované na výkon Numerické výpočty Převládající jazyky: FORTRAN, C Pomalý posun směrem k C++ Databázové systémy Převládající jazyky: C/C++ Existují i databázové systémy v Javě Spolehlivé srovnání výkonu neexistuje Proč je Java/C# pomalejší? Garbage collection GC způsobuje mj. problémy s využitím cache Programování bez GC je pracnější, ale dává lepší výsledky Chybí pokročilé metody optimalizace v překladačích Vektorizace, transformace cyklů,... Existují i situace, kdy je Java/C# rychlejší Překladače Javy/C# mají jednodušší úlohu

Co programovat v C++ Proč C++ a ne C Stávající aplikace/knihovny/os jsou často v C Programování v C++ je pohodlnější než v C Menší pravděpodobnost chyb Šablony, operátory, zapouzdření,... Při troše šikovnosti stejný výkon jako v C Moduly psané v C++ a C lze spojovat extern "C" void do_something_in_c( int x); void my_cplusplus_function( int x) do_something_in_c( x); extern "C" void call_me_from_c( int y) /* C++ code here */

Co neprogramovat v C++ Co raději neprogramovat v C++ Interaktivní aplikace s GUI C++ nemá standardizované rozhraní na GUI Nativní rozhraní GUI v OS je většinou archaické C Knihovny pro GUI jsou archaické, nepřenositelné nebo obojí Qt, GTK+, wxwidgets... Garbage Collection při programování GUI citelně chybí Pokud je zároveň zapotřebí výkon, nic jiného než C++ nezbývá Aplikace skládané z mnoha cizích součástí Standard C++ poskytuje nedostatečné služby OS apod. Cizí knihovny obvykle doplňují chybějící části vlastní tvorbou Různé implementace chybějících částí mohou být v konfliktu

Proč C++ Proč (stále ještě) učíme C++? Většina řadových programátorů v C++ programovat nebude MFF chce vychovávat elitu Programování OS, databází, překladačů Vědecké výpočty vyžadující výkon Hry, robotika,... Údržba rozsáhlých a historických softwarových systémů Porozumíte-li tomu, jak funguje C++, budete lépe rozumět jiným programovacím jazykům architektuře počítačů a operačních systémů překladačům Zvládnutí C++ je odznakem zdatnosti matfyzáka

Hello, World! #include <iostream> int main( int argc, char * * argv) std::cout << "Hello, world!" << std::endl; return 0; Vstupní bod programu Dědictví jazyka C Žádné třídy ani metody Globální funkce main Parametry programu Z příkazové řádky Děleno na kousky Archaické datové typy Ukazatel na ukazatel Logicky pole polí std - namespace knihoven cout - standardní výstup globální proměnná << - výstup do streamu přetížený operátor endl - oddělovač řádek globální proměnná

Hello, World! Dělení do modulů Rozhraní modulů je nutno opsat do zvláštního souboru.hpp - hlavičkový soubor Definující i používající modul tento soubor inkluduje textová direktiva #include // world.hpp #ifndef WORLD_HPP_ #define WORLD_HPP_ void world(); #endif // main.cpp #include "world.hpp" int main( int argc, char * * argv) world(); return 0; // world.cpp #include "world.hpp" #include <iostream> void world() std::cout << "Hello, world!" << std::endl;

Hello, World! // world.hpp #ifndef WORLD_HPP_ #define WORLD_HPP_ #include <vector> #include <string> typedef std::vector< std::string> t_arg; void world( const t_arg & arg); #endif // main.cpp #include "world.hpp" int main( int argc, char * * argv) world( t_arg( argv + 1, argv + argc)); return 0; // world.cpp #include "world.hpp" #include <iostream> void world( const t_arg & arg) if ( arg.empty() ) std::cout << "Hello, world!" << std::endl;

Architektura Překladače / interpretry

CPU C P U

CPU rozumí pouze binárním kódu C P U 01010000 01110100 11010111 10010110 00100010 10110001

1940... programování ve strojovém kódu C P U 01010000 01110100 11010111 10010110 00100010 10110001

1940... programování ve strojovém kódu 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001

1940... programování ve strojovém kódu 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X

1950... assembler 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC X'40202120' DBL DC D'0' END BEGIN C P U assembler

1950... operační systém 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC X'40202120' DBL DC D'0' END BEGIN C P U assembler

1950... operační systém 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC X'40202120' DBL DC D'0' END BEGIN C P U assembler myprog.exe

1950... překladač 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader X X X X X X X X X XXXX X X X X X X X X X X X XX X X X X XX X X XX X X X XXX X X X X X XX XXXX X XXXX X XX X XXX X X X XX X X X X X X X X XX X X X X X X X X X X X X X X XX X X X X X X X X X X X X READ INPUT TAPE 5, 501, IA, IB, IC 501 FORMAT (3I5) IF (IA) 777, 777, 701 701 IF (IB) 777, 777, 702 702 IF (IC) 777, 777, 703 703 IF (IA+IB-IC) 777,777,704 704 IF (IA+IC-IB) 777,777,705 705 IF (IB+IC-IA) 777,777,799 777 STOP 1 799 S = FLOATF (IA + IB + IC) / 2.0 AREA = SQRT( S * (S - FLOATF(IA)) * (S - FLOATF(IB)) * + (S - FLOATF(IC))) WRITE OUTPUT TAPE 6, 601, IA, IB, IC, AREA STOP END C P U překladač Fortran myprog.exe

1970... překladač C 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader Hello, world! #include <stdio.h> int main(int,char**) printf( "Hello, world!\n"); C P U překladač C myprog.exe

1980... překladač C++ 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader Hello, world! #include <iostream> int main(int,char**) std::cout << "Hello, world!\n"; C P U překladač C++ myprog.exe

1960... interpret(er) 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 10 INPUT "What is your name: ", U$ 20 PRINT "Hello "; U$ 30 INPUT "How do you want: ", N 40 S$ = "" 50 FOR I = 1 TO N 60 S$ = S$ + "*" 70 NEXT I 80 PRINT S$ 90 INPUT "Do you want? ", A$ 100 IF LEN(A$) = 0 THEN 90 110 A$ = LEFT$(A$, 1) 120 IF A$ = "Y" THEN 30 130 PRINT "Goodbye ";U$ 140 END C P U interpret operační systém X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X

Interpretace s mezikódem 10 INPUT "What is your name: ", U$ 20 PRINT "Hello "; U$ 30 INPUT "How do you want: ", N 40 S$ = "" 50 FOR I = 1 TO N 60 S$ = S$ + "*" 70 NEXT I 80 PRINT S$ 90 INPUT "Do you want? ", A$ 100 IF LEN(A$) = 0 THEN 90 110 A$ = LEFT$(A$, 1) 120 IF A$ = "Y" THEN 30 130 PRINT "Goodbye ";U$ 140 END 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U překladač 04FBC41E 77AB2000 1AE04E33 operační systém interpret X X X X X X X X X XX X XX XX XX X XX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X XX X XXX X X X X X X X

interpretovaný mezikód (bytecode) public class HelloWorld public static void main(string[] args) System.out.println( "Hello, world!"); C P U překladač myprog.class 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U 04FBC41E 77AB2000 1AE04E33 interpret operační systém Hello, world!

JIT překladač public class HelloWorld public static void main(string[] args) System.out.println( "Hello, world!"); C P U překladač myprog.class 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 C P U JIT překladač 01010000 01110100 11010111 10010110 00100010 10110001 operační systém Hello, world!

Srovnání JIT/non-JIT public class HelloWorld public static void main(string[] args) System.out.println( "Hello, world!"); C P U překladač myprog.class C P U JIT překladač 01010000 01110100 11010111 10010110 00100010 10110001 operační systém #include <iostream> int main(int,char**) std::cout << "Hello, world!\n"; C P U překladač myprog.exe C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader

Srovnání JIT/non-JIT JIT (Java, C#, C++/CLI) non-jit (C++) Distribuuje se bytecode (.class,.exe) Distribuce závislá na jazyku a překladači Distribuuje se (někdy) jako binární instrukce (.exe) Distribuce závislá na procesoru a OS Překladač zná přesně cílovou architekturu, může pozorovat chování programu Překladač má dost času na překlad

Dynamické spojování? public class HelloWorld public static void main(string[] args) mylib.doit(); překladač překladač myprog.class mylib.class C P U JIT překladač 01010000 01110100 11010111 10010110 00100010 10110001 operační systém #include <iostream> int main() int main() doit(); std::cout << "Hello, world!\n"; překladač myprog.exe C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader překladač mylib.dll

Dynamické spojování import acme.mylib; public publiclass class HelloWorld HelloWorld public public static static void void main(string[] main(string[] args) args) mylib.doit(); System.out.println( "Hello, world!"); překladač překladač myprog.class mylib.class C P U JIT překladač 01010000 01110100 11010111 10010110 00100010 10110001 operační systém #include "mylib.hpp" #include <iostream> int main() int main() doit(); std::cout << "Hello, world!\n"; // mylib.hpp void doit(); překladač myprog.exe C P U 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader překladač mylib.dll

Překlad jednoduchého programu - statické spojování // iostream // iostream #include <fstream> #include <fstream> namespace std namespace std extern ofstream extern ofstream cout, cerr; cout, cerr; ; ; iostream.obj msvcrt.lib // myprog.cpp Kompilátor myprog.obj Linker myprog.exe #include <iostream> int main() std::cout << "Hello, world!\n";

Oddělený překlad a spojování modulů Standardní Standardní.obj Uživatelské.hpp Standardní.lib Uživatelské.cpp Kompilátor Přeložené.obj Linker Spustitelný soubor.exe

Spojování modulů myprog.cpp #include "bee.hpp" int main(int,char**) return B( 7); Kompilátor myprog.obj 0000: 01010000???????? 11010111 export main(int,argv**) import B(int) bee.hpp #ifndef bee_hpp #define bee_hpp int B( int q); #endif Linker myprog.exe 0000: 01010000 00001100 11010111 1100: 10010110 00100010 10110001 bee.cpp #include "bee.hpp" int B( int q) return q+1; Kompilátor bee.obj 0000: 10010110 00100010 10110001 export B(int)

make Standardní Standardní.obj Uživatelské.hpp Standardní.lib Uživatelské.cpp Kompilátor Přeložené.obj Linker Spustitelný soubor.exe Make makefile

Integrované prostředí Standardní Standardní.obj Uživatelské.hpp Standardní.lib Uživatelské.cpp Kompilátor Přeložené.obj Linker Spustitelný soubor.exe Editor Debugger projekt

Statické knihovny Standardní Standardní.obj Uživatelské.hpp Standardní.lib Uživatelské.cpp Kompilátor Přeložené.obj Linker Spustitelný soubor.exe Knihovní.hpp Knihovna.lib Knihovní.cpp Kompilátor Přeložené.obj Librarian

Dynamické knihovny (Microsoft) Standardní Standardní.obj Uživatelské.hpp Standardní.lib Uživatelské.cpp Kompilátor Přeložené.obj Linker Spustitelný soubor.exe Knihovní.hpp Knihovna.lib Knihovní.cpp Kompilátor Přeložené.obj Linker Knihovna.dll

Dynamické knihovny (GNU) Standardní Standardní.o Uživatelské.hpp Standardní.a Uživatelské.cpp Kompilátor Přeložené.o Linker Spustitelný soubor Knihovní.hpp Knihovní.cpp Kompilátor Přeložené.o Librarian Knihovna.so

Deklarace a definice

Deklarace a definice Deklarace Zápis sdělující, že věc (typ/proměnná/funkce/...) existuje Identifikátor Základní vlastnosti věci Umožňuje překladači přeložit kód, který na věc odkazuje V některých případech je k tomu zapotřebí i definice Definice Zápis, který určuje všechny vlastnosti věci Obsah třídy, inicializace proměnné, kód funkce Umožňuje překladači vygenerovat kód a data, která věc reprezentují za běhu Každá definice je i deklarace Deklarace umožňují (některá) použití věci bez definice Oddělený překlad modulů Vyřešení cyklických závislostí Zmenšení objemu překládaného zdrojového kódu

Deklarace a definice One-definition rule #1: Jedna překladová jednotka... (modul, tj. jedno.cpp včetně inkludovaných hpp)... smí obsahovat nejvýše jednu definici věci One-definition rule #2: Program... (tj..exe včetně připojených.dll)... smí obsahovat nejvýše jednu definici proměnné nebo non-inline funkce Definice třídy, typu či inline funkce se v různých modulech opakovat smějí (typicky vložením téhož.hpp souboru) Nejsou-li opakované definice totožné, nebo nesouhlasí-li definice s deklarací, program je nekorektní Diagnostika na úrovni programu není normou požadována a překladače/linkery ji dělají jen v jednoduchých případech

Deklarace a definice tříd a typů Deklarace Definice Třída class A; class A... ; Struktura struct A; struct A... ; Unie (v C++ prakticky nepoužitelné) Pojmenovaný typ union A; union A... ; typedef A A2; typedef A * AP; typedef std::shared_ptr< A> AS; typedef A AA[ 10]; typedef A AF(); typedef AF * AFP1; typedef A (* AFP2)(); typedef std::vector< A> AV; typedef AV::iterator AVI;

Deklarace a definice proměnných Globální proměnná Statická položka třídy Statická konstantní položka třídy Statická lokální proměnná Nestatická položka třídy Nestatická lokální proměnná Deklarace Definice extern int x, y, z; int x; int y = 729; int z( 729); class A static int x, y, z; ; int A::x; int A::y = 729; int A::z( 729); class A static const int x = 729; ; void f() static int x; static int y = 7, z( 7); class A int x, y; ; void f() int x; int y = 7, z( 7); ;

Deklarace a definice funkcí non-inline Deklarace (.hpp nebo.cpp) Definice (.cpp) Globální funkce int f( int, int); int f( int p, int q) return p + q; Statická metoda class A static int f( int p); ; Nestatická metoda class A int f( int p); ; Virtuální metoda class A virtual int f( int p); ; int A::f( int p) return p + 1; int A::f( int p) return p + 1; int A::f( int) return 0; inline Deklarace (.hpp nebo.cpp) Definice (.hpp nebo.cpp) Globální inline funkce Nestatická inline metoda (a) Nestatická inline metoda (b) class A int f( int p); ; inline int f( int p, int q) return p + q; inline int A::f( int p) return p + 1; class A int f( int p) return p+1; ;

Umístění dat

Umístění dat Statická alokace = 1 instance na proces Globální proměnná Statická položka třídy Statická lokální proměnná [C++11] thread_local objekty = 1 instance na vlákno Zásobníková alokace = 1 instance na každé vyvolání Lokální proměnná Parametr předávaný hodnotou Návratová hodnota funkce Pomocná proměnná při výpočtu výrazu Dynamická alokace = řízeno programem Dynamicky alokovaná data (new/delete)

Inicializace Číselné typy, ukazatele Statická alokace Inicializováno nulou Zásobníková nebo dynamická alokace Neinicializováno! Třídy / struktury Inicializováno konstruktorem Lze určit parametry pro konstruktor Není-li konstruktor, platí tato pravidla pro jednotlivé části Parametr předávaný hodnotou / návratová hodnota funkce Inicializován copy-constructorem Není-li definován, je generován překladačem

Okamžik inicializace a destrukce Inicializace Destrukce Globální proměnná Před vstupem do main Po výstupu z main Statická položka třídy Před vstupem do main Po výstupu z main Statická lokální proměnná Lokální proměnná Při prvním průchodu řízení deklarací V okamžiku průchodu řízení deklarací Po výstupu z main Při výstupu z bloku Parametr předávaný hodnotou Návratová hodnota funkce Pomocná proměnná při výpočtu výrazu Před voláním funkce V příkazu return Když je vypočtena její hodnota Před návratem z funkce Po návratu z funkce Na konci příkazu (v deklaraci: na konci bloku) Dynamicky alokovaná data Při volání new Při volání delete

Nejdůležitější datové typy

Vybrané číselné typy bool char std::wchar_t int unsigned long long unsigned long long std::size_t double long double std::complex<double> false, true znak základní sady (např. ASCII, 8 bit) znak rozšířené sady (např. Unicode, 16/32 bit) celé číslo se znaménkem (obvykle 32 bit) celé číslo bez znaménka (obvykle 32 bit) extra velké celé číslo se znaménkem (64 bit) extra velké celé číslo bez znaménka (64 bit) dostatečně velké číslo pro velikost čehokoliv (32/64 bit) reálné číslo (Intel: 64 bit) přesnější reálné číslo (Intel: 80 bit) komplexní číslo dané přesnosti

Další důležité typy std::string std::wstring std::istream std::wistream std::ostream std::wostream struct T std::pair<t1,t2> std::vector<t> std::list<t> std::map<k,t> std::multimap<k,t> řetězec (nad char) řetězec (nad std::wchar_t) vstupní proud (nad char) vstupní proud (nad std::wchar_t) výstupní proud (nad char) výstupní proud (nad std::wchar_t) struktura uspořádaná dvojice s prvky typu T1 a T2 pole prvků typu T seznam prvků typu T asociativní pole prvků typu T indexované typem K asociativní pole s opakováním

Složené typy v C++ Složené typy jsou iluze poskytovaná překladačem Souvislý úsek paměti dělený na elementární typy sizeof(t) = velikost tohoto úseku Zarovnání může vynutit nevyužití některých míst Veškerá manipulace je překladačem rozložena na manipulaci s elementárními typy V jednoduchých případech (POD) lze kopírovat jako blok bajtů Pole: T a[n] N-tice stejných typů N musí být překladači známá konstanta Třída (class nebo struct) Pojmenované položky různých typů Ve složitějších případech režijní informace Dědičnost implementována vložením předka Virtuální dědičnost vyžaduje nepřímé odkazy na předky

Ukazatel vs. hodnota

Reference, ukazatelé, iterátory T & const T & T * const T * Reference Konstrukce jazyka C++ Použití syntakticky shodné s hodnotou (r.a) Ukazatel Konstrukce jazyka C/C++ Zvláštní operátory pro přístup k hodnotě (*p, p->a) Ukazatelová aritmetika pro přístup k sousedům v polích Manuální alokace/dealokace objektů Chytré ukazatele Třída ve standardních knihovnách C++ Zvláštní operátory pro přístup k hodnotě (*p, p->a) Automatická dealokace při zániku odkazů std::shared_ptr< T> std::unique_ptr< T> Iterátory Třídy reprezentující odkazy na prvky kontejneru typu K Zvláštní operátory pro přístup k hodnotě (*p, p->a) Napodobenina ukazatelové aritmetiky K::iterator K::const_iterator

Referenční semantika C#/Java vs. C++ Referenční typy (C#,Java) Ukazatele na objekty (C++) class T public int a; class test static void f( T z) z.a = 3; static void g() T x = new T(); //vznik x.a = 1; T y = x; //druhý odkaz y.a = 2; // x.a == 2 f( x); // x.a == 3 class T public: int a; ; void f( T * z) z->a = 3; void g() T * x = new T; //vznik x->a = 1; T * y = x; //druhý odkaz y->a = 2; // x->a == 2 f( x); // x->a == 3 //zrušení zařídí garbage collector delete x; //zánik je nutno vyvolat ručně

Referenční semantika C#/Java vs. C++ Referenční typy (C#,Java) Chytré ukazatele na objekty (C++) class T public int a; class test static void f( T z) z.a = 3; static void g() T x = new T(); //vznik x.a = 1; T y = x; //druhý odkaz y.a = 2; // x.a == 2 f( x); // x.a == 3 class T public: int a; ; void f( T * z) z->a = 3; void g() std::shared_ptr< T> x = new T; //vznik x->a = 1; std::shared_ptr< T> y = x; //druhý odkaz y->a = 2; // x->a == 2 f( x); // x->a == 3 //zrušení zařídí garbage collector //zrušení při zániku posledního odkazu

Hodnotová semantika C#/Java vs. C++ Hodnotové typy (C#) Objekty (C++) struct T int a; class test static void f( T z) z.a = 3; static void g() T x; //vznik x.a = 1; T y = x; //kopie y.a = 2; // x.a == 1 f( x); // x.a == 1 class T public: int a; ; void f( T z) z.a = 3; void g() T x; //vznik x.a = 1; T y = x; //kopie y.a = 2; // x.a == 1 f( x); // x.a == 1 //zrušení v okamžiku zániku proměnné //zrušení v okamžiku zániku proměnné

Hodnotová semantika C#/Java vs. C++ Předání odkazem (C#) (hodnotové typy) struct T int a; class test static void f( ref T z) z.a = 3; Předání odkazem (C++) class T public: int a; ; void f( T & z) z.a = 3; static void g() T x; //vznik x.a = 1; f( ref x); // x.a == 3 void g() T x; x.a = 1; f( x); // x.a == 3

Referenční semantika C#/Java vs. C++ Předání odkazem (C#) Referenční typy class T public int a; class test static void f( ref T z) z = new T(); //vznik static void g() T x = new T(); //vznik f( ref x); // x je nyní jiný objekt //zrušení zařídí garbage collector Předání odkazem (C++) Reference na ukazatel Užíváno řídce nebezpečí chyb class T public: int a; ; void f( T * & z) delete z; //zánik je nutno vyvolat ručně z = new T; //vznik void g() T * x = new T; //vznik f( x); // *x je nyní jiný objekt delete x; //zánik je nutno vyvolat ručně

Dynamická alokace my_class * p = 0; void f1() p = new my_class( 20, 30); void f2() delete p; Dynamická alokace pole std::vector je lepší void f2( std::size_t n) int * q = new int[ n]; q[ n-1] = p->m(); //... Dynamickou alokaci je nutné použít, pokud Rozsah života objektu se nekryje s vyvoláním funkce, nebo Alokovaný objekt je třída s dědičností zařazená do datové struktury Ostatní případy lze většinou nahradit použitím kontejnerů Kontejnery skrývají dynamickou alokaci uvnitř delete[] q;

Chytré ukazatele void f1() std::unique_ptr< my_class> p = new my_class( 20, 30); std::unique_ptr< my_class> q = std::move( p); // nuluje p q.reset( new my_class( 10, 20)); // dealokuje původní objekt // dealokuje druhý objekt void f2() std::shared_ptr< my_class> p = new my_class( 20, 30); std::shared_ptr< my_class> q = p; q.reset( new my_class( 10, 20)); Chytré ukazatele řeší dealokaci samy C++11 unique_ptr vždy jen jediný odkaz zajistí překladač shared_ptr počítání odkazů režie za běhu Slabší a pomalejší než Garbage Collection problém: cyklické struktury // dealokuje oba objekty

Reference

Reference Hodnotové typy (C++,C#,...) Referenční typy (C#,Java) Lokálně existující objekty (C++) Reference na objekty (C++) Ukazatele na objekty (C++) f(int y); class T... class T... class T... class T... void g() int x; //vznik void g() T x = new T; //vznik void g() T x; //vznik void g() T x; //vznik void g() T * x = new T; //vznik int y = z; //kopie //zrušení při //výstupu z bloku T y = x; //druhý odkaz y.f(); //zrušení zařídí //garbage //collector T y = x; //kopie y.f(); //zánik při //výstupu z bloku T & y = x; //odkaz y.f(); //zánik při //výstupu z bloku T * y = x; //druhý odkaz y->f(); delete y; //zánik x->f(); //chyba

Reference a ukazatelé Ukazatel (*) a reference (&) Z hlediska implementace ekvivalentní - ukazatel i reference na objekt jsou reprezentovány adresou tohoto objektu Ukazatel umí navíc: Přesměrování jinam Speciální hodnotu nulový ukazatel Ukazatelovou aritmetiku posouvání na sousední objekty v poli Dealokaci operator delete Referenci je možno použít jenom jedním z následujících způsobů: Typ proměnné Typ položky třídy Typ parametru funkce Typ návratové hodnoty funkce Odlišná syntaxe použití: Objekt a reference na objekt se syntakticky neliší Ukazatel se dereferencuje operátorem * Ukazatel na objekt se získá operátorem &

Reference a ukazatelé Pravidla pro začátečníky Kdy použít referenci: T & Výstupní parametr Návratová hodnota funkce zpřístupňující objekt T & vector<t>::at(size_t i) Kdy použít konstantní referenci: const T & Obvykle pouze kvůli rychlosti Parametr typu struktura/třída Návratová hodnota funkce zpřístupňující objekt ke čtení const T & vector<t>::at(size_t i) const Kdy použít ukazatel (T *) Je-li objekt dynamicky alokován Je-li nutná schopnost přesměrování, null, nebo aritmetika Nelze-li referenci správně namířit v okamžiku inicializace Kdy použít konstantní ukazatel (const T *) Sekundární odkaz na objekt, schopný pouze čtení

Reference a ukazatelé Pravidla pro pokročilejší Vlastník dynamicky alokovaného objektu je zodpovědný za jeho zrušení - musí použít ukazatel T * nelze-li jednoznačně určit vlastníka, použijte shared_ptr<t> Uživatel objektu Pokud je životnost pozorovatele kratší než životnost objektu lze použít referenci T & nebo const T & Pokud je životnost delší než životnost objektu nebo jinak komplikovaná je nutné použít ukazatel T * nebo const T *

Reference Novinky související s existencí reference Inicializaci reference nelze nahradit přiřazením Třídy obsahující referenci musí mít konstruktor Nelze rozlišit skutečné parametry předávané hodnotou a odkazem Návratová hodnota funkce může být l-hodnota a.at( i) = x; Zvýšené nebezpečí nekorektních konstrukcí int & f() int x; return x; // funkce vrátí referenci na neexistující objekt

Vracení odkazem Funkce jako add nemůže vracet referenci add vrací hodnotu různou od všech svých parametrů hodnotu parametrů nesmí měnit reference nemá na co ukazovat Špatné řešení č. 1: Lokální proměnná Complex & add( const Complex & a, const Complex & b) Complex r( a.re + b.re, a.im + b.im); return r; BĚHOVÁ CHYBA: r zaniká při návratu z funkce

Vracení odkazem Funkce jako add nemůže vracet referenci add vrací hodnotu různou od všech svých parametrů hodnotu parametrů nesmí měnit reference nemá na co ukazovat Špatné řešení č. 2: Dynamická alokace Complex & add( const Complex & a, const Complex & b) Complex * r = new Complex( a.re + b.re, a.im + b.im); return * r; PROBLÉM: kdo to odalokuje?

Vracení odkazem Funkce jako add nemůže vracet referenci add vrací hodnotu různou od všech svých parametrů hodnotu parametrů nesmí měnit reference nemá na co ukazovat Špatné řešení č. 3: Globální proměnná Complex g; Complex & add( const Complex & a, const Complex & b) g = Complex( a.re + b.re, a.im + b.im); return g; CHYBA: globální proměnná je sdílená Complex a, b, c, d, e = add( add( a, b), add( c, d));

Vracení odkazem Funkce jako add musí vracet hodnotou add vrací hodnotu různou od všech svých parametrů hodnotu parametrů nesmí měnit reference nemá na co ukazovat Správné řešení Complex add( const Complex & a, const Complex & b) Complex r( a.re + b.re, a.im + b.im); return r; Zkrácený (ekvivalentní) zápis return Complex( a.re + b.re, a.im + b.im);

Vracení odkazem Funkce jako add musí vracet hodnotou Complex add( const Complex & a, const Complex & b) Complex r( a.re + b.re, a.im + b.im); return r; Data se při vracení z funkce (několikrát) kopírují z = add( x, y); plnění proměnné r [constructor] kopie ven z funkce [copy-constructor] přiřazení [operator=] [C++11] rvalue reference mohou některá kopírování usnadnit Řešení bez kopírování existuje za cenu dynamické alokace u malých dat (Complex, string) se nevyplatí

Vracení odkazem Řešení bez kopírování class ComplexBody public: ComplexBody( double r, double i) : re( r), im( i) double re, im; ; Complex add( const Complex & a, const Complex & b) return Complex( a.re() + b.re(), a.im() + b.im()); return r; class Complex public: Complex( double r, double i) : b( new ComplexBody( r, i)) double re() const return b->re; double im() const return b->im; private: std::shared_ptr< ComplexBody> b; ; Ekvivalent garbage-collection ComplexBody je sdíleno několika instancemi Complex a zaniká s posledním z nich Garbage-collection metodou markand-sweep bývá rychlejší než počítání odkazů (shared_ptr) Pro malé třídy (Complex) je kopírování levnější než dynamická alokace

Reference a ukazatelé Pravidla pro vracení hodnot odkazem Pokud hodnota, kterou funkce vrací, existuje v nějakém objektu i po návratu z funkce, lze vrátit odkaz na tento objekt (konstantní) referencí T & vector<t>::back(); const T & vector<t>::back() const; T & T::operator+=(const T & b); T & T::operator++();// prefixová verze ++ vrací novou hodnotu Pokud se hodnota, kterou funkce vrací, nově spočítala a není nikde uložena, funkce musí vracet hodnotou T operator+( const T & a, const T & b); T T::operator++(int);// postfixová verze ++ vrací starou hodnotu

STL Standard Template Library

STL Kontejnery Prefabrikáty základních datových struktur Šablony parametrizované typem ukládaného objektu Všechny kontejnery pracují s kopiemi vkládaných hodnot Typ hodnot musí mít alespoň copy-constructor a destruktor Některé druhy kontejnerů či operací s nimi vyžadují i operator= nebo konstruktor bez parametrů Hodnoty se přidávají a odebírají metodami odpovídajícími druhu kontejneru K hodnotám je možno přistupovat pomocí iterátoru, který reprezentuje inteligentní ukazatel dovnitř kontejneru Prostřednictvím iterátoru je možno měnit uložené hodnoty

STL Příklad #include <deque> typedef std::deque< int> my_deque; my_deque the_deque; the_deque.push_back( 1); the_deque.push_back( 2); the_deque.push_back( 3); int x = the_deque.front(); // 1 the_deque.pop_front(); my_deque::iterator ib = the_deque.begin(); my_deque::iterator ie = the_deque.end(); for ( my_deque::iterator it = ib; it!= ie; ++it) *it = *it + 3; int y = the_deque.back(); // 6 the_deque.pop_back() int z = the_deque.back(); // 5

STL Kontejnery Sekvenční kontejnery Seřazeny podle vzrůstající režie [C++11] array< T, N> - pole se staticky danou velikostí vector< T> - pole prvků s přidáváním zprava basic_string< T> - vektor s terminátorem string = basic_string< char> - řetězec (ASCII) wstring = basic_string< wchar_t> - řetězec (Unicode) deque< T> - fronta s přidáváním a odebíráním z obou stran [C++11] forward_list< T> - jednosměrně vázaný seznam list< T> - obousměrně vázaný seznam Odvozené kontejnery queue< T> - fronta (maskovaná deque) priority_queue< T> - prioritní fronta (vylepšený vector) stack< T> - zásobník (maskovaný vector)

STL Kontejnery Pomocné metody kontejneru Test prázdnosti bool empty() const Počet prvků size_t size() const nepoužívat pro testy prázdnosti

STL Kontejnery Metody kontejneru, vracející iterátory Odkaz na začátek kontejneru - první platný prvek iterator begin() const_iterator begin() const Odkaz za konec kontejneru - za poslední platný prvek iterator end() const_iterator end() const iterator a const_iterator jsou typy definované uvnitř kontejneru, zvané iterátory přístupné konstrukcemi jako vector< int>::iterator vlastnosti iterátorů jsou mírně závislé na druhu kontejneru Iterátor kontejneru obsahujícího typ T je třída s operátory definovanými tak, aby se chovala podobně jako "T *" "(ukazatel na typ T) resp. "const T *" Vytváří se tak iluze, že kontejner je pole

Kategorie iterátorů Norma C++ definuje 5 kategorií iterátorů random_access bidirectional forward output input Kategorie určuje, které syntaktické konstrukce musí iterátor umožňovat vector, basic_string a deque list random_access bidirectional forward_list forward Pro iterátor I jsou definovány tyto operace: output *I = x input *I /* pouze pro čtení */ random_access, bidirectional, forward *I /* čtení i zápis */ všechny kategorie ++I, I++ random_access, bidirectional, forward, input I1 == I2, I1!= I2 random_access, bidirectional --I, I-- random_access I += n, I + n, n + I I -= n, I - n, I1 - I2 I[ n] I1 < I2, I1 > I2, I1 <= I2, I1 >= I2

STL Iterátory Operátory definované na iterátorech přístup k prvku, na který iterátor ukazuje T & iterator::operator *() const const T & const_iterator::operator *() const posouvání iterátoru směrem ke konci jednosměrný iterátor iterator & iterator::operator++() posouvání iterátoru směrem k začátku obousměrný iterátor iterator & iterator::operator--() libovolný posun iterátor s přímým přístupem iterator operator+( iterator, int) iterator operator-( iterator, int)

STL Kontejnery Metody kontejneru pro vkládání iterator insert( iterator p, T x) vsune (kopii) x před prvek, na který ukazuje iterátor p vrací iterátor ukazující na vložený prvek void insert( iterator p, int n, T x) vsune n kopií x před prvek, na který ukazuje iterátor p template< typename other_iterator> void insert( iterator p, other_iterator b, other_iterator e) před prvek, na který ukazuje iterátor p, vsune kopii posloupnosti prvků ohraničené iterátory b a e Tato posloupnost nesmí být uvnitř téhož kontejneru Tato posloupnost může být součástí jiného druhu kontejneru je-li p == end(), vkládání připojuje na konec kontejneru všechny dříve existující iterátory odkazující na tento kontejner jsou po použití insert neplatné, včetně p výjimka: kontejnery list a forward_list iterátory mířící na původní prvky nebo end() zachovávají

STL Kontejnery Konstruktory kontejneru K() Vytvoří prázdný kontejner (array: kontejner dané velikosti) K( int n, T x = T()) Vytvoří kontejner s n kopiemi hodnoty x Má-li typ T konstruktor bez parametrů, není třeba udávat x template< typename other_iterator> K( other_iterator b, other_iterator e) Vytvoří kontejner naplněný kopií posloupnosti prvků ohraničené iterátory b a e Tato posloupnost může být součástí jiného druhu kontejneru

STL Kontejnery Původní vkládací metody kopírují vkládané prvky Zbytečná práce, nemožnost použití některých typů (unique_ptr) [C++11] move Metody insert a push_back/front mají move varianty iterator insert( iterator p, T && x) Překladač ji použije, je-li parametrem pomocná proměnná... k.insert( it, a + b); // operator nebo funkce vracejici hodnotou k.insert( it, T( x, y, z)); // bezejmenny objekt... nebo pokud je použito std::move k.insert( it, std::move( a)); Move-semantika: Proměnná a bude (může být) vyprázdněna Move-semantika poskytuje úsporu času (a prostoru), pokud typ T obsahuje dynamicky alokovaná data je na move semantiku připraven (má move-konstruktory) std::vector< std::string> k; std::string a = "..."; k.push_back( a + ".kzr");

STL Kontejnery Původní vkládací metody kopírují vkládané prvky Zbytečná práce, nemožnost použití některých typů (unique_ptr) [C++11] emplace Metody insert a push_back/front mají emplace varianty iterator emplace( iterator p, T1 && x1,..., Tn && xn); void emplace_back( T1 && x1,..., Tn && xn); void emplace_front( T1 && x1,..., Tn && xn); Do kontejneru je přidán nový prvek inicializovaný konstruktorem s parametry x1,..., xn std::vector< std::vector< int> > k; k.emplace_back( 100, 0); Šetří kopírování vkládaného prvku oproti původnímu zápisu k.push_back( std::vector< int>( 100, 0)); Šetří i v případě nepřipraveného typu bez move-semantiky V případě vector< int> by to kopírování ušetřila sama move-semantika Poznámka: rvalue reference v hlavičce emplace funkcí dovolují i lvalue operandy pomocí skládání referencí a funkce std::forward

STL Kontejnery Metody kontejneru pro odebírání iterator erase( iterator p) vyjme prvek, na který ukazuje iterátor p p nesmí být rovno end() vrací iterátor ukazující na prvek za vyjmutým prvkem (nebo end()) iterator erase( iterator p, iterator e) vyjme všechny prvky mezi p a e, včetně p a vyjma e p nesmí být rovno end() vrací iterátor odkazující na prvek e (původní iterátor e nebude platný) všechny iterátory odkazující na tento kontejner jsou po použití erase neplatné, včetně p a e výjimka: kontejnery list a forward_list iterátory mířící na nesmazané prvky zachovávají void clear() erase( begin(), end());

STL Kontejnery Odvozené funkce manipulace s konci kontejneru Přidání jednotlivého prvku void push_front( T x) return insert( begin(), x); list, deque void push_back( T x) return insert( end(), x); list, deque, vector Odebrání jednotlivého prvku void pop_front() return erase( begin()); list, deque void pop_back() return erase( --end()); list, deque, vector

STL Kontejnery Odvozené funkce kontejneru pro přístup k prvkům Prvky na koncích list, deque, vector podmínka:! empty() T & front() const T & front() const obě provádějí return * begin(); T & back() const T & back() const obě provádějí auto it = end(); --it; return * it; [C++11] auto umožňuje deklaraci proměnné bez uvedení typu typ si odvodí překladač z inicializace, v tomto případě K::[const_]iterator

STL Kontejnery Odvozené funkce kontejneru pro přístup k prvkům Prvky uprostřed deque, vector, string podmínka: n < size() at: porušení podmínky vyvolá výjimku operator[]: porušení podmínky způsobí nedefinované chování T & at( int n) T & operator[]( int n) const T & at( int n) const const T & operator[]( int n) const všechny provádějí return * ( begin() + n);

STL - Kontejnery složitost operace na kontejneru s n prvky list deque vector basic_string přídání / odebrání jednoho prvku na začátku push_front pop_front konstantní konstantní funkce neexistuje funkce neexistuje přídání / odebrání jednoho prvku na i-té pozici insert erase konstantní min( i, n - i) n - i n - i přídání / odebrání m prvků na i-té pozici insert erase m přesuny mezi seznamy (splice) jsou konstantní m +min( i, n - i) m + n - i m + n - i přídání / odebrání jednoho prvku na konci push_back pop_back konstantní konstantní konstantní funkce neexistuje nalezení i-tého prvku begin() + i funkce neexistuje konstantní konstantní konstantní paměťová náročnost kontejneru s prvky velikosti s (s + K) * n K řádově 16 B q * s * n q kolem 1.2 q * s * n q kolem 1.2 q * s * n q kolem 1.2

Asociativní kontejnery

STL - Kontejnery Asociativní kontejnery Uspořádané (samovyvažující se stromy) set<t> - množina multiset<t> - množina s opakováním map<k,t> - asociativní pole, tj. parciální zobrazení K -> T multimap<k,t> - relace s rychlým vyhledáváním podle klíče K [C++11] Hashované [C++11] unordered_set<t> - množina [C++11] unordered_multiset<t> - množina s opakováním [C++11] unordered_map<k,t> - asociativní pole, tj. parciální zobrazení K -> T [C++11] unordered_multimap<k,t> - relace s rychlým vyhledáváním podle klíče K pair<a,b> - pomocná šablona uspořádané dvojice s položkami first, second

STL - Kontejnery Uspořádané kontejnery vyžadují uspořádání na klíčích Klíčem se rozumí první parametr šablony kontejneru Uspořádání se obvykle definuje operátorem < definovaným na typu klíče Pozor na konstrukce typu set< char *> Uspořádání lze rovněž zadat přídavným parametrem šablony Definované uspořádání nemusí být antisymetrická relace pokud platí! (x < y) &&! (y < x) pak jsou prvky x a y považovány za ekvivalentní

STL - Kontejnery Uspořádané kontejnery vyžadují uspořádání na klíčích Vystačí si s operací < V nejjednodušším případě to funguje samo std::map< std::string, int> mapa; Pokud typ uspořádání nemá, lze jej definovat obecně bool operator<( const Klic & a, const Klic & b) return...; std::map< Klic, int> mapa; Pokud obecná definice uspořádání nevyhovuje, lze definovat uspořádání funktorem pouze pro daný typ kontejneru struct Usporadani bool operator()( const Klic & a, const Klic & b) const return...; ; std::map< Klic, int, Usporadani> mapa; Pokud různé instance kontejneru mají mít různé uspořádání, lze do funktoru doplnit datové položky struct Usporadani Usporadani( bool a); /*...*/ bool ascending; ; std::map< Klic, int, Usporadani> mapa( Usporadani( true));

STL - Kontejnery Uspořádání na klíčích implementace Knihovny definují funktor std::less< K> template< typename K> class less public: bool operator()( const K & a, const K & b) const return a < b; ; Šablona kontejneru má typový parametr - typ funktoru template< typename K, typename T, typename L = std::less< K> > class map public: Konstruktor kontejneru dostává hodnotu funktoru explicit map( const L & c = L()) : cmp_( c) /*...*/ /*...*/ private: ; L cmp_; Kontejner drží jednu instanci funktoru Metody kontejneru volají operátor () na instanci funktoru iterator find_( /*...*/) /*...*/ if ( cmp_( x, y) ) /*...*/

STL - Kontejnery Uspořádání na klíčích hashující kontejnery Kontejner vyžaduje funktory pro hashování a pro porovnání template< typename K> class hash public: std::size_t operator()( const K & a) const /*...*/ ; template< typename K> class equal_to public: bool operator()( const K & a, const K & b) const return a == b; ; Šablona kontejneru má dva další parametry template< typename K, typename T, typename H = std::hash< K>, typename E = std::equal_to< K> > class unordered_map; Konstruktor kontejneru dostává hodnoty funktorů explicit unordered_map( std::size_t initial_bucket_count = /*...*/, const H & h = L(), const E & e = E());

STL - Kontejnery Asociativní kontejnery procházení Kontejnery lze procházet iterátory Uspořádané kontejnery jsou prezentovány v uspořádání podle klíčů Iterátor je bidirectional Hashující kontejnery jsou prezentovány v implementačnědefinovaném pořadí Iterátor je forward Metody begin() a end() a operátory iterátorů mají stejný význam, jako u sekvenčních kontejnerů Kontejnery [unordered_][multi]map< K, T> obsahují uspořádané dvojice - typ std::pair< const K, T> Klíč (it->first) nelze modifikovat, hodnotu (it->second) ano Procházení celého asociativního kontejneru se užívá málokdy Iterátory se častěji získávají vyhledáváním

STL - Kontejnery Asociativní kontejnery vyhledávání iterator set::find( T x) iterator multiset::find( T x) iterator map::find( K x) iterator multimap::find( K x) iterator unordered_set::find( T x) iterator unordered_multiset::find( T x) iterator unordered_map::find( K x) iterator unordered_multimap::find( K x) pokud v kontejneru existuje prvek s klíčem ekvivalentním x: vrací iterátor ukazující na první takový prvek multiset, multimap: další takové prvky jsou dostupné operací ++ jinak vrací end() složitost operace uspořadné kontejnery: O( log( size())) hashující kontejnery: průměrně O(1), nejhůře O( size())