Základy programování (IZP) Šesté 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 6. týden
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í 6 2
Důležité informace 1. projekt Práce s textem 30. 10. Obhajoba projektu Bez ohhajoby: 0b 4.11. Odevzdání projektu do WISu Jméno souboru: proj1.c IZP cvičení 6 3
Náplň cvičení Diskuze k prvnímu projektu Opakování pojmů Z minula: předávání parametrů funkcím hodnotou, odkazem Řídicí struktury a jejich převod Převod mezi cykly Ukazatele a alokace paměti IZP cvičení 6 4
DISKUZE K PRVNÍMU PROJEKTU IZP cvičení 6 5
1. projekt rady, doporučení Testujte na serveru merlin Překládejte i s přepínačem Werror Důsledně dodržujte formát výstupu, projekt bude hodnocen automaticky Projděte si funkce dostupné v hlavičkových souborech IZP cvičení 6 6
Knihovna ctype.h Funkce vrací číslo > 0 nebo 0 Zkontroluje, zda je znak c bílý znak int isspace(int c); Zkontroluje, zda je znak c číslice int isdigit(int c); Zkontroluje, zda je znak c písmeno int isalpha(int c); Více informací o ctype.h man ctype.h Internet IZP cvičení 6 7
OPAKOVÁNÍ POJMŮ IZP cvičení 6 8
Opakování pojmů Funkce IZP cvičení 6 9
Opakování pojmů Funkce Funkce sdružuje příkazy v jeden celek. Jedna z funkcí je funkce main() a musí být v programu vždy uvedena. Je vhodné program rozdělit na funkce, které odpovídají jednotlivým činnostem, které má program vykonávat. IZP cvičení 6 10
Opakování pojmů Deklarace funkce (prototyp funkce, hlavička) IZP cvičení 6 11
Opakování pojmů Deklarace funkce (prototyp funkce, hlavička) Deklaruje funkci před jejím použitím a před tím než je definována. navrattyp JmenoFce(arg1, arg2,,argn); IZP cvičení 6 12
Opakování pojmů Deklarace funkce (prototyp funkce, hlavička) Deklaruje funkci před jejím použitím a před tím než je definována. navrattyp JmenoFce(arg1, arg2,,argn); Poznámka: Funkce main() prototyp nepotřebuje jedná se o funkci, která má zvláštní postavení Každý spustitelný program ji musí obsahovat Její návratový typ je vždy int IZP cvičení 6 13
Opakování pojmů Poznámka: Funkce main má 0 nebo 2 parametry 0 parametrů: nepotřebujeme pracovat s argumenty příkazové řádky int main(){ } 2 parametry: potřebujeme argumenty příkazové řádky int main(int argc, char* argv[]){ } Poznámka: Nezáleží na pojmenování parametrů, důležité jsou pouze jejich datové typy! Uvedené pojmenování je ale konvence, která se používá všude IZP cvičení 6 14
Opakování pojmů Definice funkce (implementace funkce) IZP cvičení 6 15
Opakování pojmů Definice funkce (implementace funkce) Uvedení toho, co má funkce dělat Hlavička funkce + tělo funkce navrattyp JmenoFce(arg1, arg2,,argn) { // tělo: co má funkce provádět } IZP cvičení 6 16
Opakování pojmů Datový typ IZP cvičení 6 17
Opakování pojmů 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() IZP cvičení 6 18
Opakování pojmů 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í 6 19
Opakování pojmů 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í 6 20
Opakování pojmů Deklarace IZP cvičení 6 21
Opakování pojmů 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í 6 22
Opakování pojmů 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 IZP cvičení 6 23
Opakování pojmů 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í 6 24
Opakování pojmů Příkaz IZP cvičení 6 25
Opakování pojmů Příkaz Příkaz definuje činnost, kterou program vykoná (výpis textu na obrazovku, opakování části programu, atp.). IZP cvičení 6 26
Opakování pojmů Řídicí konstrukce (struktury) programu IZP cvičení 6 27
Opakování pojmů Řídicí konstrukce (struktury) programu Části programovacího jazyka, které řídí, jakým směrem se bude výpočet ubírat. Patří sem: Funkce Příkazy: složený příkaz, podmíněný příkaz, cykly, příkazy skoku IZP cvičení 6 28
Opakování pojmů Výraz IZP cvičení 6 29
Opakování pojmů Výraz Konstrukce jazyka, která má hodnotu (nějakého datového typu) Výraz příkaz Výraz: představuje dále použitelnou hodnotu Příkaz: jeho úkolem je vykonat nějaký kód IZP cvičení 6 30
Opakování pojmů Operátory IZP cvičení 6 31
Opakování pojmů Operátory Aritmetické IZP cvičení 6 32
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické IZP cvičení 6 33
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické: && (AND), (OR),! (NOT) A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 IZP cvičení 6 34
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické: && (AND), (OR),! (NOT) A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 Relační 1 1 1 1 IZP cvičení 6 35
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické: && (AND), (OR),! (NOT) Relační: ==, >, <, >=, <= A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 IZP cvičení 6 36
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické: && (AND), (OR),! (NOT) Relační: ==, >, <, >=, <= Bitové A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 IZP cvičení 6 37
Opakování pojmů Operátory Aritmetické: unární (+, -, speciální: ++, --), binární (+, -, *, /, %, =) Logické: && (AND), (OR),! (NOT) Relační: ==, >, <, >=, <= A B AND OR 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 Bitové: výsledkem je číselná hodnota (ne logická!) & (bit. AND), (bit. OR), ~ (bit. NOT), ^ (bit. XOR), << (bit. posun vlevo), >> (bit. posun vpravo) IZP cvičení 6 38
Opakování pojmů Homogenní/heterogenní datová struktura IZP cvičení 6 39
Opakování pojmů Homogenní/heterogenní datová struktura Homogenní: všechny komponenty struktury jsou stejného datového typu Příklad: pole int moje_pole[6]; Heterogenní: komponenty struktury nejsou stejného datového typu Příklad: struktura (později na tomto cvičení ) IZP cvičení 6 40
Opakování pojmů Cyklus IZP cvičení 6 41
Opakování pojmů Cyklus Cyklem myslíme opakování určité části programu. Rozeznáváme dva základní druhy cyklů: se známým počtem průchodů (iterací) (for) s neznámým počtem průchodů (iterací) (while, do-while) IZP cvičení 6 42
JEDNODUCHÉ CYKLY IZP cvičení 6 43
Příklad 1 cykly Se známým počtem průchodů jaký cyklus? Vzestupně - interval [0;n) Vzestupně - interval [a;b] Sestupně - interval [a;b) Vzestupně ob jedno - interval [a;b] Po jednotlivých znacích řetězce Po jednotlivých znacích načtených ze stdin IZP cvičení 6 44
Příklad 1 cykly Se známým počtem průchodů cyklus for Vzestupně - interval [0;n) Vzestupně - interval [a;b] Sestupně - interval [a;b) Vzestupně ob jedno - interval [a;b] Po jednotlivých znacích řetězce Po jednotlivých znacích načtených ze stdin IZP cvičení 6 45
Časté chyby Pozor na = a == for(int i=0; i=5; i++){ } Pozor na pořadí jednotlivých částí cyklu for for(int i=0; i++; i<5){ } for(int i=5; i--; i>0){ } IZP cvičení 6 46
Funkce Příklady výše lze zobecnit tak, že je dekomponujeme do funkcí Napište program, který bude obsahovat funkci s prototypem int countchars(char* str, char c); Tato funkce vrací počet výskytu znaku c v řetězci str IZP cvičení 6 47
PŘEVODY MEZI CYKLY IZP cvičení 6 48
Příklad 2 převody mezi cykly Napište program, který projde všechny argumenty příkazové řádky a zjistí, zda byl zadán argument h Pokud byl zadán, ihned ukončete provádění cyklu Použijte cyklus while a příkaz break IZP cvičení 6 49
Příklad 2 převody mezi cykly Napište program, který projde všechny argumenty příkazové řádky a zjistí, zda byl zadán argument h Pokud byl zadán, ihned ukončete provádění cyklu Použijte cyklus while a příkaz break Modifikace 1: převeďte s cyklem while bez použití break a continue IZP cvičení 6 50
Příklad 2 převody mezi cykly Napište program, který projde všechny argumenty příkazové řádky a zjistí, zda byl zadán argument h Pokud byl zadán, ihned ukončete provádění cyklu Použijte cyklus while a příkaz break Modifikace 1: převeďte s cyklem while bez použití break a continue Modifikace 2: přepište cyklus while na for IZP cvičení 6 51
Příklad 2 převody mezi cykly for(inicializace; test; inkrementace) { } inicializace; while(test) { inkrementace; } IZP cvičení 6 52
Příklad 2 převody mezi cykly Napište program, který projde všechny argumenty příkazové řádky a zjistí, zda byl zadán argument h Pokud byl zadán, ihned ukončete provádění cyklu Použijte cyklus while a příkaz break Modifikace 1: převeďte s cyklem while bez použití break a continue Modifikace 2: přepište cyklus while na for IZP cvičení 6 53
Převody mezi cykly II PŘÍKLAD 3 IZP cvičení 6 54
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu IZP cvičení 6 55
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] IZP cvičení 6 56
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h IZP cvičení 6 57
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e IZP cvičení 6 58
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l IZP cvičení 6 59
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l IZP cvičení 6 60
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o IZP cvičení 6 61
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o 2 w IZP cvičení 6 62
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o 2 w o IZP cvičení 6 63
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o 2 w o r IZP cvičení 6 64
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o 2 w o r l IZP cvičení 6 65
Příklad 3 - Převody mezi cykly II Zjistěte, zda libovolný argument programu obsahuje písmeno h. Do proměnné i uložte pozici argumentu obsahující písmeno h Do proměnné j uložte pozici písmene v daném argumentu./prog hello world argv[1] = hello argv[2] = world Index argumentu i argv[i][0] argv[i][1] argv[i][2] argv[i][3] argv[i][4] 1 h e l l o 2 w o r l d IZP cvičení 6 66
UKAZATELE IZP cvičení 6 67
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data IZP cvičení 6 68
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data Ukazatel (pointer) proměnná, která uchovává adresu nějakého místa v paměti Říkáme, že ukazatel ukazuje na místo, které je určeno touto adresou IZP cvičení 6 69
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data Ukazatel (pointer) proměnná, která uchovává adresu nějakého místa v paměti Říkáme, že ukazatel ukazuje na místo, které je určeno touto adresou Velikost ukazatele závisí na tom, kolikabitový máme procesor/překladač (16, 32, 64 bitů) IZP cvičení 6 70
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data Ukazatel (pointer) proměnná, která uchovává adresu nějakého místa v paměti Říkáme, že ukazatel ukazuje na místo, které je určeno touto adresou Velikost ukazatele závisí na tom, kolikabitový máme procesor/překladač (16, 32, 64 bitů) Adresa proměnné referenční operátor & IZP cvičení 6 71
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data Ukazatel (pointer) proměnná, která uchovává adresu nějakého místa v paměti Říkáme, že ukazatel ukazuje na místo, které je určeno touto adresou Velikost ukazatele závisí na tom, kolikabitový máme procesor/překladač (16, 32, 64 bitů) Adresa proměnné referenční operátor & Hodnota z adresy dereferenční operátor * IZP cvičení 6 72
Ukazatel, reference, dereference Proměnná pojmenované místo v paměti, ve kterém uchováváme data Ukazatel (pointer) proměnná, která uchovává adresu nějakého místa v paměti Říkáme, že ukazatel ukazuje na místo, které je určeno touto adresou Velikost ukazatele závisí na tom, kolikabitový máme procesor/překladač (16, 32, 64 bitů) Adresa proměnné referenční operátor & Hodnota z adresy dereferenční operátor * NULL používá se pro inicializaci ukazatelů říká, že ukazatel nikam neukazuje IZP cvičení 6 73
Ukazatel, reference, dereference IZP cvičení 6 74
Ukazatel, reference, dereference int i = 10; int *p; //? p = &i; //? *p = 20; //? printf("hodnota promenne i: %d\n", i); //? IZP cvičení 6 75
Ukazatel, reference, dereference int i = 10; int *p; // ukazatel p není inicializován! p = &i; *p = 20; printf("hodnota promenne i: %d\n", i); IZP cvičení 6 76
Ukazatel, reference, dereference int i = 10; int *p; // ukazatel p není inicializován! p = &i; // ukazatel p ukazuje na i *p = 20; printf("hodnota promenne i: %d\n", i); IZP cvičení 6 77
Ukazatel, reference, dereference int i = 10; int *p; // ukazatel p není inicializován! p = &i; // ukazatel p ukazuje na i *p = 20; // pomocí p jsme změnili hodnotu i printf("hodnota promenne i: %d\n", i); IZP cvičení 6 78
Předání parametrů funkcím Parametry můžeme funkcím předávat Hodnotou (vytvoříme lokální kopii proměnné) Lokální proměnná se vytvoří na zásobníku Odkazem (do funkce předáváme pouze adresu proměnné v paměti) Předání hodnotou by mělo být bez problémů Jak funguje předání odkazem? Následuje příklad IZP cvičení 6 79
Předání parametrů funkcím předávání odkazem Abychom si ukázali, jak funguje předávání odkazem, definujme následující funkci void inc(int* n) { } *n = *n + 1; Vidíme, že funkce nic nevrací. Hodnotu ale můžeme z funkce získat přes ukazatel Jak ji tedy zavoláme a použijeme v programu? IZP cvičení 6 80
Předání parametrů funkcím předávání odkazem // deklarace: void inc(int* n); int main() { int a = 5; inc(&a); printf("hodnota a: %d", a); //?? } IZP cvičení 6 81
Funkce swap Napište funkci, která prohodí hodnoty dvou proměnných typu int Proměnné do funkce předejte odkazem Poznámka: v předmětu IOS uvidíte, jak se funkce swap používá prakticky IZP cvičení 6 82
Záměna dvou prvků v poli Napište funkci, která zamění (prohodí) dva prvky v poli typu int Použijte funkci swap IZP cvičení 6 83
STRUKTURY, VLASTNÍ DATOVÉ TYPY IZP cvičení 6 84
Pole x Struktura Pole Homogenní Musí obsahovat položky stejného datového typu Struktura Heterogenní Může obsahovat položky různého datového typu IZP cvičení 6 85
Struktury Klíčové slovo struct struct person { }; char* name; // jmeno char* surname; // prijmeni int pay; int main() { struct person test; test.pay = 1000; // plat test.name = "Pepa"; //podobne surname printf("pay: %d\n", test.pay); printf("name: %s\n", test.name); } IZP cvičení 6 86
Struktury vlastní datový typ Nový datový typ klíčové slovo typedef typedef struct person { char* name; // jmeno char* surname; // prijmeni int pay; }TPerson; int main() { Tperson test; test.pay = 1000; // plat test.name = "Pepa"; //podobne surname printf("pay: %d\n", test.pay); printf("name: %s\n", test.name); } IZP cvičení 6 87
Struktury demo: jak to vypadá v paměti Velikosti datových typů závisí na architektuře IZP cvičení 6 88
Struktury demo: alokace paměti typedef struct person { char* name; // jmeno char* surname; // prijmeni int pay; // plat }TPerson; int main() { Tperson test; test.name = // jak alokujeme paměť? } IZP cvičení 6 89
Struktury demo: alokace paměti typedef struct person { char* name; // jmeno char* surname; // prijmeni int pay; }TPerson; int main() { } Tperson test; test.name = // plat malloc((strlen("pepa")+1)*sizeof(char); // jak ověříme, že je alokace OK? IZP cvičení 6 90
Struktury demo: alokace paměti typedef struct person { char* name; // jmeno char* surname; // prijmeni int pay; }TPerson; int main() { } Tperson test; test.name= // plat malloc((strlen("pepa")+1)*sizeof(char); if(test.name == NULL) { fprintf(stderr, "Chyba alokace! ); return -1; } IZP cvičení 6 91
Struktury přístup k prvkům Operátor. nebo -> -> (šipka) pokud předáváme strukturu (složený datový typ) jako ukazatel void setpay(tperson* p) { } //?. (tečka) jindy TPerson setpay(tperson p) { } //? IZP cvičení 6 92
Struktury přístup k prvkům Operátor. nebo -> -> (šipka) pokud předáváme strukturu (složený datový typ) jako ukazatel void setpay(tperson* p) { } p->pay = 1000;. (tečka) jindy TPerson setpay(tperson p) { } p.pay = 10; return p; IZP cvičení 6 93
Příklad Vytvořte datový typ pro záznam informací o pacientech O každém pacientovi se bude uchovávat Jméno datum narození Výška Váha Pohlaví Vyzkoušejte si pole alokovat (třeba pro 5 pacientů) a vypište datum narození 3. pacienta IZP cvičení 6 94
Wiki: ordinační hodiny Prostudujte si příklad, který načítá ordinační hodiny lékaře Pokuste se doplnit kód na chybějící místa IZP cvičení 6 95
Wiki: alokace a dealokace řídkého pole Prostudujte si zdrojový kód k alokaci/dealokaci řídkého pole. Jak budou data vypadat v paměti? IZP cvičení 6 96
Děkuji Vám za pozornost! IZP cvičení 6 97