Základy programování (IZP) Čtvrté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 2016/2017
Důležité informace Můj profil: http://www.fit.vutbr.cz/~iveigend/ Kancelář: A221 Konzultační hodiny: po domluvě emailem Karta Výuka odkaz na osobní stránky Komunikace: email prosím používejte předmět: IZP - <předmět emailu> IZP cvičení 4 2
Důležité informace Nezapomeňte se ve WISu přihlásit na všechny 4 termíny: 3 projekty IZP 1 dokumentace ke třetímu projektu Pozor: přihlašujte se ke správnému asistentovi! Asistent Veigend Přihlašování začalo 10. 10. 2016 v 8:00 (DNES!!!) PŘIHLAŠTE SE RADĚJI HNED TEĎ Přihlašování končí 30. 10. 2016 ve 22:00 IZP cvičení 4 3
Důležité informace 1. projekt Práce s textem 31. 10. Obhajoba projektu 6.11. Odevzdání projektu do WISu Jméno souboru: proj1.c 2. projekt Odevzdání již 27. 11. 2016 3. projekt Odevzdání již 11. 12. 2016 IZP cvičení 4 4
Náplň cvičení Proměnné, datové typy, příkazová řádka Řešení všech máte na wiki stránkách ale když už jsme tady, vyzkoušíme je aspoň trochu samostatně (jako minule) Pokud nebudete vědět, jak se zapisuje nějaká programová konstrukce (proměnná, podmínka, atd.), zapište si do zdrojového souboru komentář // tady se budou vypisovat dva retezce /* komentar na vice radku */ IZP cvičení 4 5
Číselné proměnné a konstanty Základní pojmy Proměnná IZP cvičení 4 6
Číselné proměnné a konstanty Základní pojmy Proměnná Pojmenované místo v paměti, ve kterém uchováváme data. Má určitý datový typ a její hodnota se může za běhu programu měnit. Příklad: int a=10; IZP cvičení 4 7
Číselné proměnné a konstanty Základní pojmy Proměnná Pojmenované místo v paměti, ve kterém uchováváme data. Má určitý datový typ a její hodnota se může za běhu programu měnit. Příklad: int a=10; Konstanta IZP cvičení 4 8
Číselné proměnné a konstanty Základní pojmy Proměnná Pojmenované místo v paměti, ve kterém uchováváme data. Má určitý datový typ a její hodnota se může za běhu programu měnit. Příklad: int a=10; Konstanta Pojmenované místo v paměti, ve kterém uchováváme data. Má určitý datový typ, její hodnota se nemůže za běhu programu měnit. Příklad: const int b=10; IZP cvičení 4 9
Proměnné Datový typ IZP cvičení 4 10
Proměnné Datový typ Jaká data mohou být na pojmenovaném místě uložena Jaké operace mohou být s daty prováděny Např. int, double, float, char, bool, Pro určení velikosti datového typu můžeme s výhodou použít operátor sizeof() Příklad za okamžik IZP cvičení 4 11
Proměnné Pojmenování (identifikátor) To, jak je proměnná pojmenovaná, závisí pouze na programátorovi ALE proměnné pojmenované test12345, mojenejuzasnejsipromenna apod. asi nebudou úplně nejvhodnější Indexy: i, j, k, l, Řetězce: str, s, Znaky: c, ch, Konstanty: KONSTANTA (velká písmena) Datové typy: TArray, ColorSpace, (později) IZP cvičení 4 12
Proměnné Nedoporučuje se, aby název proměnné začínal podtržítkem - mnoho takových názvů je definováno překladačem a mají proto zvláštní význam. int _promenna Názvy proměnných a funkcí, které jsou delší, než jedno slovo můžeme zapisovat velmi_dlouhy_nazev_id velmidlouhynazevid (angl. Camel-Caps, Camel-Case) Vyberte si jeden styl zapisování a držte se ho Je vhodné (nikoliv nutné) pojmenovávat v angličtině IZP cvičení 4 13
Proměnné Deklarace Deklarace proměnné vytváří novou proměnnou, kterou je možno použít dál v programu int i; // nepřiřazena žádná hodnota IZP cvičení 4 14
Proměnné Deklarace Deklarace proměnné vytváří novou proměnnou, kterou je možno použít dál v programu int i; // nepřiřazena žádná hodnota Inicializace Přiřazení počáteční hodnoty deklarované proměnné int j = 10; // inicializováno na 10 a = 60; // NELZE, proměnná není // deklarována IZP cvičení 4 15
Proměnné Přiřazení (operátor =) Nastavení hodnoty proměnné int j = 10; // inicializováno na 10 j = 60; // nová hodnota j je 60 Porovnání (operátor ==) Využíváme v podmínkách if(i == 0) { } Pozor: neplést s přiřazovacím operátorem! IZP cvičení 4 16
Proměnné Několik ukázek z wiki int i; char* s = "Hello"; char c1 = '\0', c2; char *s2, c; i = 2; c2 = s[i]; // jaký znak získáme? IZP cvičení 4 17
Ukazatel (podrobněji později ) Ukazatele proměnné uchovávají adresu, která ukazuje do paměti počítače Vážou se k určitému datovému typu Definice proměnné typu ukazatel: bazovy_typ *nazev_promenne; int *int_ptr; // ukazatel na int IZP cvičení 3 18
Řetězce Na minulém cvičení jsme už řetězce trochu zkoumali a nyní si je zopakujeme oficiálně Řetězcový literál (neboli konstanta) Inicializujeme char* s = "Hello"; Jednotlivé znaky nelze měnit za běhu programu IZP cvičení 4 19
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 IZP cvičení 3 20
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 Pole: prvky stejného typu, spojité místo v paměti IZP cvičení 3 21
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 Pole: prvky stejného typu, spojité místo v paměti Deklarace staticky: int moje_pole[6]; IZP cvičení 3 22
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 Pole: prvky stejného typu, spojité místo v paměti Deklarace staticky: int moje_pole[6]; Velikost pole: operátor sizeof() velikost v bajtech U polí vrací součet velikostí jeho položek IZP cvičení 3 23
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 Pole: prvky stejného typu, spojité místo v paměti Deklarace staticky: int moje_pole[6]; Velikost pole: operátor sizeof() velikost v bajtech U polí vrací součet velikostí jeho položek Velikost moje_pole: int velikost = 6*sizeof(int); IZP cvičení 3 24
Datový typ pole Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 10 20 30 40 50 60 Pole: prvky stejného typu, spojité místo v paměti Deklarace staticky: int moje_pole[6]; Velikost pole: operátor sizeof() velikost v bajtech U polí vrací součet velikostí jeho položek Velikost moje_pole: int velikost = 6*sizeof(int); Pozor: velikost datového typu záleží na procesoru sizeof(int) může být 2, 4 nebo 8 IZP cvičení 3 25
Datový typ pole řetězce Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 'h' 'e' 'l' 'l' 'o' '\0' IZP cvičení 3 26
Datový typ pole řetězce Skutečná adresa 1634 1635 1636 1637 1638 1639 Index 0 1 2 3 4 5 Hodnota 'h' 'e' 'l' 'l' 'o' '\0' Řetězce: pole typu char zakončená nulovým znakem '\0' Pozor: char pole[5]; Není zde místo pro ukončovací nulu ('\0') Pozor: je nutné hlídat meze pole! IZP cvičení 3 27
PŘÍKLADY IZP cvičení 4 28
Výpis argumentů programu Na rozehřátí poslední příklad z minula, ale nejdřív argumenty trochu zopakujeme IZP cvičení 4 29
Argumenty programu Jednotlivé argumenty budeme oddělovat mezerou Argumenty se dají získat pomocí následující konstrukce: int main(int argc, char* argv[]) { // argc počet argumentů // argv jednotlivé argumenty, argv[0] // (název souboru s programem) } Pro./hello sum 10 20 argc=4 argv[0] argv[1] argv[2] argv[3] "hello" "-sum" "10" "20" IZP cvičení 4 30
Spouštění programu s parametry Code::Blocks Project Set program s arguments OK Spustíme program Linux./program arg1 arg2 arg3 Jednotlivé argumenty jsou od sebe odděleny mezerou IZP cvičení 4 31
PŘÍKLAD 1 VÝPIS ARGUMENTŮ PŘÍKAZOVÉHO ŘÁDKU IZP cvičení 4 32
Výpis argumentů programu Napište program, který bezpečně vypíše všechny argumenty, se kterými byl program spuštěn Nápověda: Použijte cyklus (while, for) Cyklus while: nezpomeňte inkrementovat řídící proměnnou v těle cyklu Funkce printf() nutné #include <stdio.h> printf("text"); int i = 10; printf("cislo: %d", i); char* retezec = "Ahoj"; printf("retezec: %s", retezec); IZP cvičení 4 33
Cykly a převody mezi nimi for(inicializace; test; inkrementace) { } inicializace; while(test) { inkrementace; } IZP cvičení 3 34
PŘÍKLAD 2 POROVNÁNÍ DVOU ŘETĚZCŮ IZP cvičení 4 35
Funkce pro práci s řetězci string.h Nutné vložit knihovnu: #include <string.h> Lexikografické porovnání řetězců s1 a s2 int strcmp(char* s1, char* s2); Funkce vrací číslo (int) A další == 0 pokud jsou řetězce s1 a s2 stejné > 0 pokud je řetězec s1 lexikograficky větší než s2 < 0 pokud je řetězec s1 lexikograficky menší než s2 IZP cvičení 4 36
Funkce strcmp() a podmíněný příkaz Složený příkaz: if(podmínka){ } else{ } Pokud je podmínka pravdivá: provede se větev if Pokud není podmínka pravdivá: provede se větev else Jak tedy zjistíme, že jsou dva řetězce shodné? 1) Musíme zavolat funkci strcmp() 2) Musíme v podmínce ověřit, jak porovnání dopadlo 2 způsoby: Lepší: if(strcmp("ahoj","ahoj") == 0) { } int pom; pom = strcmp("ahoj","ahoj"); // lze také if(pom == 0) { } IZP cvičení 4 37
Porovnání dvou řetězců Napište program, který porovná první argument programu s řetězcem -help Pokud se první argument s tímto řetězcem shoduje, vypište libovolný text na obrazovku Zkontrolujte, zda byl první argument opravdu zadán, složitější kontrolu argumentů NEPROVÁDĚJTE. Nápověda int strcmp(char* s1, char* s2); Funkce vrací 0, pokud jsou řetězce shodné IZP cvičení 4 38
PŘÍKLAD 3 HLEDÁNÍ ARGUMENTU -H IZP cvičení 4 39
Hledání argumentu -h Napište program, který zjistí, zda byl zadán argument -h Pokud ano, vypište libovolný text na obrazovku Zároveň vypište, na jakém indexu se argument -h nachází Nápověda int strcmp(char* s1, char* s2); Funkce vrací 0, pokud jsou řetězce shodné Pro kontrolu argumentů využijte cyklus IZP cvičení 4 40
PŘÍKLAD 4 ZPRACOVÁNÍ ARGUMENTŮ PŘÍKAZOVÉ ŘÁDKY IZP cvičení 4 41
Zpracování argumentů příkazové řádky Než začneme s dalším příkladem, několik funkcí (a hlavičkových souborů), které se mohou hodit Knihovna #include <stdlib.h> Funkce atoi() Převádí řetězce na čísla, vrací získané číslo POZOR: je nutné funkci předat opravdu číslo, ne nesmysl int cislo = atoi("123abc456"); printf("prevedene cislo: %d", cislo); // prevedene cislo: 123 Pokud předáte opravdu nesmysl, vrátí 0 V projektu budete převádět ručně (nebo si musíte být opravdu jistí) Bezpečnější varianta: strtol() (později) IZP cvičení 4 42
Zpracování argumentů příkazové řádky Knihovna #include <stdbool.h> Poté můžete používat datový typ bool Pravdivostní hodnoty true/false Číselně: false == 0, true!= 0 (cokoli jiného než 0) bool pravdivapodminka = true; bool nepravdivapodminka = false; V podmínce if (pravdivapodminka) { } if (!nepravdivapodminka) { } IZP cvičení 4 43
Zpracování argumentů příkazové řádky A na závěr ještě operátory Aritmetické: unární, binární Logické: && (AND), (OR) Relační: =, ==, >, <, >=, <= A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 Výpis chybových hlášení standardní chybový výstup: fprintf(stderr, "Chyba!\n"); Toto je potřeba v projektech! A teď konečně příklad IZP cvičení 4 44
Zadání Napište program, který bude kontrolovat zadané argumenty příkazové řádky Pokud nebyl zadán žádný argument, vypíše chybu na stderr Pokud byl zadán argument h (většinou nápověda), vypíše na standardní výstup řetězec Napoveda Pokud byl zadán argument o, vypíše na standardní výstup libovolný jiný řetězec Argumenty h a o nelze použít zároveň (v tom případě chyba, výpis na stderr) Program může přijímat pouze argumenty -h a -o, v opačném případě chyba Pokuste se oddělit zpracování argumentů od výpisů bool hflag = false; if (hflag) IZP cvičení 3 45
PŘÍKLAD 5 PŘEVOD ŘETĚZCE NA ČISLO IZP cvičení 4 46
Převod řetězce na číslo Několik funkcí (a hlavičkových souborů), které se mohou hodit Knihovna #include <stdlib.h> Funkce int atoi(const char* str); Převádí řetězce na čísla, vrací získané číslo POZOR: je nutné funkci předat opravdu číslo, ne nesmysl int cislo = atoi("123abc"); printf("prevedene cislo: %d", cislo); // prevedene cislo: 123 Pokud předáte opravdu nesmysl, vrátí 0 Bezpečnější varianta: strtol() (později) IZP cvičení 4 47
Převod řetězce na číslo Funkce long int strtol (const char* str, char** endptr, int base); str řetězec k převodu endptr ukazatel na poslední znak, který zbyl po konverzi if(*endptr!= '\0') { // chyba } base základ, v tomto případě desítková soustava (tedy 10) IZP cvičení 3 48
PŘÍKLAD 6 NAČÍTÁNÍ SLOV ZE STANDARDNÍHO VSTUPU (STDIN) IZP cvičení 4 49
Projektová nápověda - načítání slov Při práci na projektu budete muset nejdříve načíst slova ze standardního vstupu Možnosti: Po znacích: funkce getchar() Celý řádek: funkce scanf scanf() vrací: cislo = 1 pokud se slovo načetlo cislo <= 0 při chybě int cislo = scanf("%format", kam); IZP cvičení 4 50
Projektová nápověda - načítání slov Při práci na projektu budete muset nejdříve načíst slova ze standardního vstupu Možnosti: Po znacích: funkce getchar() Celý řádek: funkce scanf Napíšeme program, který načte slovo o maximální délce 10 znaků Bude slova načítat, dokud nenarazí konec souboru (EOF = End Of File) Windows: CTRL-Z scanf() vrací: cislo = 1 pokud se slovo načetlo cislo <= 0 při chybě Linux: CTRL-D char slovo[?]; // co tu bude? int code = scanf("%10s", slovo); IZP cvičení 4 51
Příště - první bodované cvičení Budu se ptát na jednoduché věci, které se budou týkat tématu cvičení nebo toho, co jsme tady už dělali Budete zase programovat samostatně, tak jako na tomto a předchozím cvičení Pokud vám dělaly problémy dnešní příklady, využijte tento týden k procvičení Hodnocení Rád bych všem dal ALESPOŇ 1b, ale budu chtít vidět aktivitu a to, že jste se na cvičení připravili Se samostatným příkladem případně pomůžu, ale většinu musíte zvládnout sami IZP cvičení 4 52
Děkuji za pozornost
Zpracování argumentů příkazové řádky Vytvořte program, který zpracuje příkazovou řádku a vypíše, zda byl zadán (v opačném případě chyba): argument -h, nebo argument -o, nebo číslo Ošetřete, aby číslo mohlo být zadáno pouze jednou Pokud by bylo zadáno vícekrát chyba (nějak si to zaznamenejte) Oddělte od sebe načtení příkazové řádky a výpis zjištěných údajů. V části pro výpis argumentů ošetřete případné chyby Nápověda: je vhodné použít datový typ bool IZP cvičení 4 54
Zpracování argumentů příkazové řádky - otázky Otázka: Může být -h či -o zadáno vícekrát? IZP cvičení 4 55
Zpracování argumentů příkazové řádky - otázky Otázka: Může být -h či -o zadáno vícekrát? Odpověď: Ano, může Pouze se opakovaně provede některá z větví podmíněného příkazu if IZP cvičení 4 56
Zpracování argumentů příkazové řádky - otázky Otázka: Jak zařídit, aby -h a -o bylo výlučné? IZP cvičení 4 57
Zpracování argumentů příkazové řádky - otázky Otázka: Jak zařídit, aby -h a -o bylo výlučné? Odpověď: Přidáme podmínku do části výpisu if(hflag && oflag) { printf("chyba: zadano h i -o!\n"); return -1; // proč return? } AND = 1: Podmínka se provede, jen pokud jsou zadány OBA argumenty! (-h) (-o) AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 IZP cvičení 4 58
Zpracování argumentů příkazové řádky - otázky Otázka: Záleží na pořadí zadaných argumentů? IZP cvičení 4 59
Zpracování argumentů příkazové řádky - otázky Otázka: Záleží na pořadí zadaných argumentů? Odpověď: Ne, nezáleží IZP cvičení 4 60
Zpracování argumentů příkazové řádky - otázky Otázka: Je některý argument povinný? IZP cvičení 4 61
Zpracování argumentů příkazové řádky - otázky Otázka: Je některý argument povinný? Odpověď: Ne, není Můžeme klidně spustit program zcela bez parametrů IZP cvičení 4 62
Zpracování argumentů příkazové řádky - otázky Otázka: Co musíme udělat, aby byl argument h povinný? IZP cvičení 4 63
Zpracování argumentů příkazové řádky - otázky Otázka: Co musíme udělat, aby byl argument h povinný? Odpověď: Opět musíme přidat podmínku do části výpisu if (hflag) { } else { } printf("byl zadan argument -h\n"); printf("chyba: arg. -h nebyl zadan!\n"); return 1; IZP cvičení 4 64
Styl psaní zdrojových kódů Základní styly: llvm http://llvm.org/docs/codingstandards.html Mozilla Gnu https://developer.mozilla.org/en- US/docs/Mozilla/Developer_guide/Coding_Style https://www.gnu.org/prep/standards/standards.html IZP cvičení 3 65