PB161 Programování v jazyce C++ Přednáška 1 Organizace Úvod do C++ Nikola Beneš 18. září 2018 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 1 / 36 Cíle předmětu 1 ukázat možnosti jazyka C++ moderní C++ podle standardu C++14 2 vysvětlit základy OOP jak se realizují v C++ 3 podpořit praktické programátorské schopnosti intenzivním programováním PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 2 / 36 Organizace předmětu http://www.fi.muni.cz/pb161 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 3 / 36 Organizace předmětu Přednášky v 7. týdnu vnitrosemestrální test (20 bodů) zvaná přednáška ke konci semestru Demonstrační cvičení programovací ukázky, časté chyby, řešení miniúkolů program záleží z části na studentech Cvičení krátké úvodní shrnutí probíraného tématu týdenní miniúkoly (celkem 10 po 3 bodech) programování s možností okamžité pomoci poslední týden zápočtový příklad PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 4 / 36 Úkoly Týdenní miniúkoly (10 po 3 bodech) zadání před přednáškou, odevzdání další týden v pátek smysl: procvičit látku probranou na přednášce odevzdávání pomocí fakultního GitLabu, 3 pokusy část testů k dispozici předem Domácí úkoly (4 + 1 navíc) max. 15 bodů za úkol až 7 bodů udělovaných Kontrem (automatické testy) až 3 body udělované člověkem (hodnocení kvality kódu) až 3 body za počet odevzdání až 2 body za včasné odevzdání odevzdávání použitím fakultního GitLabu, šest pokusů pro odevzdání (poslední dva s penalizací) detaily na http://www.fi.muni.cz/pb161 (novinky červeně) PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 5 / 36 Bodování tvrdé a měkké body měkké se nepočítají do limitu pro zápočet a zkoušku domácí úkoly 5 × 15 = 75 miniúkoly 10 × 3 = 30 vnitrosemestrální test 20 celkem (tvrdé body) 125 zkouškový test: 80 bodů měkké body: bonusové části domácích úkolů zvláště pěkná řešení domácích úkolů jiné (upozornění na chyby, aktivita) PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 6 / 36 Hodnocení Zápočet >= 65 tvrdých bodů, 4 nenulové domácí úkoly, zápočtový příklad stačí 3 nenulové domácí úkoly, pokud máte alespoň 70 % bodů z miniúkolů Zkouška >= 95 tvrdých bodů, zápočet známka podle součtu tvrdých a měkkých bodů: >= 175 bodů A >= 155 bodů B >= 135 bodů C >= 115 bodů D >= 95 bodů E PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 7 / 36 Učební materiály http://cppreference.com ukázka: online dokumentace PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 8 / 36 Zpětná vazba, dotazy, komentáře předmětová anketa v ISu (až na konci semestru) dotazníky (obtížnost úloh apod.) osobně, e-mailem anonymní vzkazy: https://web.speakup.info https://kahoot.it PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 9 / 36 Doporučované vývojové nástroje cmake (verze alespoň 3) v současnosti asi nejpopulárnější nástroj pro automatizaci překladu multiplatformní clang (verze alespoň 5) populární multiplatformní překladač součást projektu LLVM Catch2 jednoduchá knihovna pro psaní unit testů PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 10 / 36 Plán semestru Blok 1: Základní programování v C++ základy vstupu a výstupu, řetězce, dynamická pole základy tříd, reference, const standardní knihovna, kontejnery, algoritmy, iterátory Blok 2: Správa paměti a zdrojů, I/O konstruktory a destruktory, kopírování práce s pamětí a zdroji, princip RAII přetěžování operátorů, vstup a výstup podrobněji Blok 3: OOP v C++ principy OOP, časná vs. pozdní vazba, virtuální metody dědičnost, návrhové vzory, static výjimky, jmenné prostory Blok 4: Šablony, ukázky pokročilejšího C++ PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 11 / 36 Programovací jazyk C++ PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 12 / 36 Historie a vývoj 1978 C K&R PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 ISO C++11 2011 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 ISO C++11 2011 ISO C++14 2014 PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 ISO C++11 2011 ISO C++14 2014 ISO C++17 2017 Budoucnost: C++2x Nestandardizovaná rozšíření PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 ISO C++11 2011 ISO C++14 2014 ISO C++17 2017 1989 ISO C89 1999 ISO C99 2011 ISO C11 Budoucnost: C++2x Nestandardizovaná rozšíření PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Historie a vývoj 1978 C K&R C with Classes B. Stroustrup 1979 C++ 1983 ISO C++98 1998 ISO C++03 2003 ISO C++11 2011 ISO C++14 2014 ISO C++17 2017 1989 ISO C89 1999 ISO C99 2011 ISO C11 Budoucnost: C++2x Nestandardizovaná rozšíření PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 13 / 36 Charakteristika C++ imperativní, staticky typovaný jazyk objektově-orientovaný; hodnotová sémantika objektů s funkcionálními prvky (zejména od C++11) podporuje generické programování a metaprogramování (šablony) částečně zpětně kompatibilní s C rozsáhlá standardní knihovna C++11 přineslo významné změny k lepšímu malloc free new delete unique_ptr PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 14 / 36 Proč používat C++? široké rozšíření vysoká rychlost kódu univerzálnost rozsáhlé možnosti metaprogramování jiný pohled na sémantiku objektů ve srovnání s většinou v současnosti populárních jazyků RAII (deterministická správa zdrojů) vhodné pro větší projekty systémové aplikace rychlou grafiku embedded zařízení spíše nevhodné pro webové aplikace rychlé prototypy PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 15 / 36 Hello, world! lecture01_01.cpp // C++ #include int main() { std::cout << "Hello, world!\n"; } // C #include int main() { printf("Hello, world!\n"); } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 16 / 36 Hello, world! 2.0 lecture01_02.cpp // C++ #include #include int main() { std::cout << "What is your name? "; std::string name; std::cin >> name; std::cout << "Hello, " << name << "!\n"; } Jak bychom podobný program napsali v C? PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 17 / 36 Řetězce v C++ lecture01_03.cpp std::string hlavičkový soubor sám si alokuje a dealokuje paměť indexování funguje jako v C std::string s = "Hello!"; s[0] = 'J'; std::cout << s; // Jello! PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 18 / 36 Řetězce v C++ lecture01_03.cpp std::string hlavičkový soubor sám si alokuje a dealokuje paměť indexování funguje jako v C std::string s = "Hello!"; s[0] = 'J'; std::cout << s; // Jello! navíc se umí přiřazovat std::string s = "Hello!"; std::string t; t = s; co se stane, když teď provedeme t[0] = 'J'? PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 18 / 36 Řetězce v C++ (pokr.) lecture01_03.cpp std::string umí se řetězit pomocí operátoru + (a operátoru +=) std::string h = "Hello"; std::string w = "world"; std::string s = h + ", " + "!"; Pozor! tohle nebude fungovat: (proč?) std::string s = "James" + " " + "Bond"; PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 19 / 36 Řetězce v C++ (pokr.) lecture01_03.cpp std::string umí se řetězit pomocí operátoru + (a operátoru +=) std::string h = "Hello"; std::string w = "world"; std::string s = h + ", " + "!"; Pozor! tohle nebude fungovat: (proč?) std::string s = "James" + " " + "Bond"; umí toho ještě mnohem více: http://en.cppreference.com/w/cpp/string PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 19 / 36 Dynamická pole v C++ lecture01_04.cpp std::vector hlavičkový soubor dynamické (rozšiřitelné) pole std::vector v; v.push_back(1); // vložení prvku za konec pole v.push_back(2); v.push_back(3); for (int i = 0; i < v.size(); ++i) { std::cout << v[i]; } for (int x : v) { // od C++11: range-for std::cout << x; } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 20 / 36 Dynamická pole v C++ (pokr.) lecture01_05.cpp std::vector inicializace std::vector v = {1, 2, 7, 17, 42}; // od C++11 std::vector v{1, 2, 7, 17, 42}; // totéž std::vector v(10); // 10 nul std::vector v(10, 17); // 10 sedmnáctek pozor na rozdíl mezi () a {} více na http://en.cppreference.com/w/cpp/container/vector pozor na rozdíl mezi resize a reserve bonus: v C++17 si typ objektů „uvnitř“ vektoru umí kompilátor v některých případech domyslet sám: std::vector v = {1, 2, 3, 4, 5}; PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 21 / 36 Hodnotová sémantika Objekty se chovají stejně jako primitivní typy přiřazení je vytvoření kopie předání do funkce je vytvoření kopie konec bloku znamená zánik objektu void f(int z) { z = 7; } int x = 3; int y = x; f(y); x = 5; // jaké jsou hodnoty x, y? std::string i std::vector se chovají stejně lecture01_06.cpp PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 22 / 36 Volání funkcí void f1(std::string s) { // s je kopie skutečného argumentu // změny s se navenek nijak neprojeví } void f2(std::string& s) { // s je reference na skutečný argument // změny s se navenek projeví } void f3(const std::string& s) { // s je reference na skutečný argument // je zakázáno s měnit } více si o referencích řekneme příště lecture01_07.cpp PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 23 / 36 Range-for funguje podobně jako volání funkcí na předchozím slajdu lecture01_07.cpp std::vector names; // ... for (std::string s : names) { // s je kopie položky vectoru } for (std::string& s : names) { // s se odkazuje na položku vectoru // můžeme jej měnit } for (const std::string& s : names) { // s se odkazuje na položku vectoru // nesmíme jej měnit } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 24 / 36 Základy vstupu a výstupu std::cout standardní výstup, objekt typu std::ostream výpis probíhá pomocí operátoru << přetížený operátor, automatická detekce typu std::cout << "Jmenuji se " << name << " a je mi " << age << " let.\n"; manipulátor std::endl – konec řádku a vyprázdnění bufferu std::cout << "In a galaxy far, far away ..." << std::endl; PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 25 / 36 Základy vstupu a výstupu (pokr.) std::cin standardní vstup, objekt typu std::istream vstup probíhá pomocí operátoru >> vstup je ukončen bílým znakem std::string s; std::cin >> s; // načte jen jedno slovo vstup celého řádku pomocí std::getline(std::cin, s) více o vstupu a výstupu později PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 26 / 36 Co znamená std::? Jmenné prostory umožňují lepší koexistenci různých knihoven více si o nich řekneme později Jmenný prostor standardní knihovny std všechny typy, objekty, funkce standardní knihovny začínají std:: Musíme všude psát std::? PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 27 / 36 Direktiva using namespace a deklarace using using std::cout; // odteď můžeme psát jen cout // ... using namespace std; // odteď můžeme psát všechno bez std:: platnost končí koncem bloku pokud není uvnitř bloku, nekončí nikdy PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 28 / 36 Direktiva using namespace a deklarace using using std::cout; // odteď můžeme psát jen cout // ... using namespace std; // odteď můžeme psát všechno bez std:: platnost končí koncem bloku pokud není uvnitř bloku, nekončí nikdy Doporučení a pravidla preferujte using std::něco; před using namespace std; (proč?) PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 28 / 36 Direktiva using namespace a deklarace using using std::cout; // odteď můžeme psát jen cout // ... using namespace std; // odteď můžeme psát všechno bez std:: platnost končí koncem bloku pokud není uvnitř bloku, nekončí nikdy Doporučení a pravidla preferujte using std::něco; před using namespace std; (proč?) nikdy nepište using namespace std; nebo using std::něco do hlavičkového souboru, pokud to není uvnitř bloku (funkce) Proč? Co strašného se stane? PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 28 / 36 Testování PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 29 / 36 Testování Programy obsahují chyby je to tak Testování programů důležitá součást vývoje různé úrovně testování unit testing – testování malých jednotek kódu Nástroje pro unit testing velká řada různých frameworků my používáme https://github.com/catchorg/Catch2 jeden hlavičkový soubor, bez závislostí testy se dají dělit do sekcí, podpora Behaviour-Driven Development jedno makro pro různé druhy porovnání PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 30 / 36 Použití Catch2 Hlavní soubor by měl obsahovat jen toto: #define CATCH_CONFIG_MAIN #include "catch.hpp" Ostatní soubory s testy – jednotlivé testy uvnitř bloků TEST_CASE TEST_CASE("A very nice test case") { // kód s asserty } TEST_CASE("Another very nice test case") { // kód s asserty } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 31 / 36 Použití Catch2 – sekce Dělení testů do sekcí – bloky SECTION (dají se zanořovat) TEST_CASE("Some test") { // tato část se provede vždy SECTION("First section") { // tato část se provede při prvním průchodu } SECTION("Second section") { // tato část se provede při druhém a třetím průchodu SECTION("First subsection") { // tato část se provede při druhém průchodu } SECTION("Second subsection") { // tato část se provede při třetím průchodu } } } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 32 / 36 Použití Catch2 (pokr.) Podmínky CHECK(condition); // musí být pravdivá CHECK_FALSE(condition); // nesmí být pravdivá REQUIRE(condition); // musí být pravdivá REQUIRE_FALSE(condition); // nesmí být pravdivá Catch2 umí rozumně zacházet s jednoduchými porovnáními typu x == y, x < y apod. REQUIRE zastaví test, pokud podmínka neplatí; CHECK pokračuje dál doporučení: preferujte CHECK; REQUIRE použijte tehdy, pokud další pokračování testu v případě nesplněné podmínky nedává smysl PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 33 / 36 Použití Catch2 (pokr.) Logování INFO(message) – v případě, že v budoucnosti selže nějaký assert, zadaná zpráva se zobrazí zprávy jsou lokální na úrovni bloků uvnitř INFO možno řetězit výstupy pomocí << WARN – zobrazí zprávu vždy FAIL – zobrazí zprávu a neúspěšně ukončí test CAPTURE(var) – totéž, co INFO("var := " << var) PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 34 / 36 Závěrečný kvíz https://kahoot.it PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 35 / 36 Závěrečný kvíz lecture01_08.cpp #include #include #include void f(std::vector z) { z[0] = "Omikron"; } int main() { std::vector x = {"Alpha", "Beta", "Gamma"}; std::vector y = x; x[1] = "Delta"; f(y); for (std::string s : y) { std::cout << s; } std::cout << '\n'; } PB161 přednáška 1: organizace, úvod do C++ 18. září 2018 36 / 36