{{indexmenu_n>2}} ====== Přednášky ====== Podklady přednášek pro aktuální akademický rok 2017/2018. Podklady se skládají z promítaných slidů, které jsou také k dispozici ve zkrácených verzích šetrnějších k případnému tisku, bez přechodů mezi snímky a ve formátu čtyř a devíti snímků na stránku. **Podklady tvoří podpůrný materiál a jejich učelem není nahradit vlastní zápisky z přednášky, které slouží také jako prostředek osvojení si studované problematiky.** Tématicky je náplň přednášek pokryta v knize **Stephen G. Kochan: Programming in C (3rd Edition), Sams Publishing, 2005**, případně též //Pavel Herout, Učebnice Jazyka C - 1. díl, Kopp, 2016//. Před přednáškou je doporučeno pročíst si odkazované kapitoly. V přednáškách uvedené zdrojové kódy jsou přiloženy v příslušném ''.zip'' archivu. Kromě vyzkoušení programů je též vřele doporučeno si složitější úlohy samostatně naprogramovat a přednáškové příklady využít pro inspiraci. /* **Aktualizováno!** Seznam záznamů přednášek najdete po přihlášení v [[https://cw.felk.cvut.cz/courses/b0b36prp/lectures.html|Upload systému]] nebo na těchto stránkách po přihlášení přístupné [[courses:b0b36prp:resources:records|záznamy přednášek]]. */ [[https://docs.google.com/forms/d/e/1FAIpQLSc0PwY1XjEpc0F-3DGXj_S0HPETkX-TMHr9U3kdQjM4VZETUQ/viewform|On-line otázky na přednášce]] ===== Harmonogram přednášek ===== ^ #VTýden ^ Týden ^ Téma ^ Středa 16:15 (Místnost T2:D3-309) ^ | 01 | 40. | [[#Informace o předmětu, Úvod do programování|Přednáška 01 - Informace o předmětu, Úvod do programování]] \\ S. G. Kochan: kapitoly 2 a 3 | 04.10. - lec01 | | 02 | 41. | [[#Základy programování v C|Přednáška 02 - Základy programování v C]]\\ S. G. Kochan: kapitoly 2 a 3 | 11.10. - lec02 | | 03 | 42. | [[#Zápis programu v C a základní řídicí struktury|Přednáška 03 - Zápis programu v C a základní řídicí struktury]] \\ S. G. Kochan: kapitoly 3, 4, 5 a část 6 | 18.10. - lec03 | | 04 | 43. | [[#Řídicí struktury, výrazy a funkce|Přednáška 04 - Řídicí struktury, výrazy a funkce]] \\ S. G. Kochan: kapitoly 4, 5, 6 a 12 | 25.10. - lec04 | | 05 | 44. | [[#Pole, ukazatel, textový řetězec|Přednáška 05 - Pole, ukazatel, textový řetězec]] \\ S. G. Kochan: kapitoly 7, 10 a 11 | 01.11. - lec05 | | 06 | 45. | [[#Ukazatele, paměťové třídy a volání funkcí|Přednáška 06 - Ukazatele, paměťové třídy a volání funkcí]] \\ S. G. Kochan: kapitoly 8 a 11 | 08.11. - lec06 | | 07 | 46. | [[#Struktury a uniony, přesnost výpočtů a vnitřní reprezentace číselných typů|Přednáška 07 - Struktury a uniony, přesnost výpočtů a vnitřní reprezentace číselných typů]] \\ S. G. Kochan: kapitoly 9, 14, 17 a Appendix B | 15.11. - lec07 | | 08 | 47. | [[#Standardní knihovny C. Rekurze.|Přednáška 08 - Standardní knihovny C. Rekurze.]] \\ S. G. Kochan: kapitola 16 a Appendix B | 22.11. - lec08 | | 09 | 48. | [[#Spojové struktury|Přednáška 09 - Spojové struktury]]| 29.11. - lec09 | | 10 | 49. | [[#Stromy|Přednáška 10 - Stromy]] | 06.12. - lec10 | | 11 | 50. | [[#Abstraktní datový typ (ADT) - zásobník, fronta, prioritní fronta|Přednáška 11 - Abstraktní datový typ (ADT) - zásobník, fronta, prioritní fronta]] | 13.12. - lec11| | 12 | 51. | [[#Prioritní fronta, halda. Příklad použití prioritní fronty při hledání nejkratší cesty v grafu|Přednáška 12 - Prioritní fronta, halda. Příklad použití při hledání nejkratší cesty v grafu]] | 20.12. - lec12 | | -- | 52. | //Zimní prázdniny// | | 13 | 01. | Přednáška 13 - //Rezerva // \\ Dokončení přednášky [[#Stromy|Přednáška 10 - Stromy]] \\ Přehled zdrojových souborů k implementační zkoušce. \\ Dotazy a upřesnění náročnějších pasáží předchozích přednášek a domácích úkolů | 03.01. - lec13 | | 14 | 02. | Přednáška 14 - //Přednáška na vyzvané téma // - Systémy pro správu verzí **Zkouškový test** | 10.01. - lec14 | /* //Přednášky jsou řazeny chronologicky za sebou, v případě státního svátku nebo změny v rozvrhu tak nemusí číslo přednášky odpovídat aktuálním výukovému týdnu (#VTýden)// */ /* **Podklady budou průběžně aktualizovány **: bodové hodnocení, zadání domácích úkolů. */ /* | 13 | 01. | Přednáška 13 - //Rezerva // - Dotazy a upřesnění náročnějších pasáží předchozích přednášek a domácích úkolů - [[#Stromy|Přednáška 10 - Stromy]] | 03.01. - lec13 | */ ===== 1. Informace o předmětu, Procedurální programování základy programování v C ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec01-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec01-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec01-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec01-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec01-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/10/04 15:39// ===== 2. Základy programování v C ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec02-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec02-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec02-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec02-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec02-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/10/11 14:36// **Dotazy z přednášky** Q: //Jaká je vnitřní reprezentace typu _Bool?// Norma standardu C uvádí, že dostatečná pro uložení hodnot 0 a 1. Prakticky je to ''char'', tj. jeden byte, viz příklad ''lec02/bool.c''. Q: //Jak vytisknu znak '%' nebo '\' ve funkci ''printf()''?// Jako dvojici znaků, tj. printf("%% a \\ a následně například nový řádek \n"); --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/10/20 08:21// **Aktualizace**: Oprava překlepů, doplnění informace o unárním operátoru přetypování. ===== 3. Zápis programu v C a základní řídicí struktury ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec03-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec03-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec03-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec03-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec03-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/10/26 09:42// **Aktualizace**: Oprava překlepů a diagramu pro do..while() **Doplnění načítání vstupu ** Při načítání vstupu funkcí scanf() lze rozlišit tři případy - úspěšné načtení požadované hodnoty, detekce ukončení vstupu a vstup neodpovídající načítané hodnotě, více viz ''man scanf''. #include int main(void) { int v; int r; int c = 0; while ((r = scanf("%d", &v)) > 0) { c += 1; } if (r == EOF) { printf("End of file detected, no. of parsed values %i\n", c); } else { printf("Error occur during parsing value no. %i\n", c + 1); } return 0; } ===== 4. Řídicí struktury, výrazy a funkce ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec04-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec04-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec04-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec04-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec04-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/10/26 09:42// **Aktualizace**: Doplnění kódů pro příklady nedefinovaného chování **Dotazy z přednášky** Q: //Je možné umístit návěští pro příkaz ''goto'' před cyklus?// V zásadě ano, jediným omezením je použití pouze v rámci jedné funkce a dále pak otvírá rozsah platnosti (scope) proměnných konkretního bloku. To souvisí s paměťovou třídou lokálních proměnných (viz přednáška 6). V podstatě nelze příkazem ''goto'' skočit na místo, kde ještě není proměnná deklarována (v rámci jednoho bloku). ^ Návěští před začátkem cyklu ^ Návěští před začátkem cyklu, ale před deklarací proměnné (**nelze**)^ | int a; // začátek platnosti a outer: for (int i = 0; i < 3; ++i) { goto outer; } | outer: // proměnná a (bloku) není deklarována, návěští nelze uvést int a; for (int i = 0; i < 3; ++i) { goto outer; } | Další podstatnou nevýhodou umístění návěští před cyklus je horší čitelnost a tím také vyšší náchylnost k chybě a zacyklení. ===== 5. Pole, ukazatel, textový řetězec ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec05-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec05-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec05-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec05-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec05-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// **Dotazy z přednášky** Q: //Proč uvedený příklad načítání skončil v nekonečné smyčce?// Načítání hodnot celých čísel funkcí ''scanf()'' ve smyčce ''while'': #include int main(void) { int v; int i = 0; while (scanf("%d", &v) > 0) { printf("%d %d\n", ++i, v); } printf("No. of read values %d\n", i); return 0; } Skončil v nekonečné smyčce, neboť původní podmínka cyklu while (scanf("%d", &v)) { ... } je vyhodnocena jako logická pravda i v případě neúspěšného načtení nové celočíselné hodnoty. V proměnné zůstane původní hodnota. Při opravě jsem, jak někdo na přednášce zmínil, zapomněl soubor uložit. ===== 6. Ukazatele, paměťové třídy a volání funkcí ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec06-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec06-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec06-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec06-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec06-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/11/09 21:56// **Aktualizace**: Oprava překlepů a přidání snímku 26 s příkladem na ''extern'' **Dotazy z přednášky** Q: //Snažím se načíst celé číslo do typu ''unsigned int'' funkcí ''scanf()'' a když dám na vstup celé záporné číslo, např. -10, nejen, že se hodnota načte, ale hodnota je veliká. Jak je to možné?// Minimální kód programu ''read_unsigned.c'' může být například: #include int main(void) { unsigned int i; int r = scanf("%+u", &i); printf("Return value %i read value %u\n", r, i); return 0; } Výstup pak například clang read_unsigned.c && echo "-10" | ./a.out Return value 1 read value 4294967286 Hodnota 4294967286 odpovídající maximálním hodnotě typu ''unsigned int'' bez 10 vyplývá z použití doplňkového kódu. Program nemá zřejmé očekávané chování. Při bližším pohledu na chování funkce ''scanf()'', např. ''man scanf'' NAME scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf — input format conversion LIBRARY Standard C Library (libc, -lc) ... u Matches an optionally signed decimal integer; the next pointer must be a pointer to unsigned int. ... se dočteme, že konverze přes ''"%u"'' načítá znamenkový ''integer''. Funkce se tak chová dle dokumentace. V případě, že bychom se chtěli vyhnout takovému chování můžeme buď použití větší datový typ, např. ''unsigned long'', a kontroloval rozsah pro ''unsigned int'' nebo si napsat vlastní načítání pouze kladných hodnot a při výskytu znaku '''-''' na vstupu indikovat špatný vstup. ===== 7. Struktury a uniony, přesnost výpočtů a vnitřní reprezentace číselných typů ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec07-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec07-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec07-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec07-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec07-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/11/15 16:05// **Dotazy z přednášky** Q: //Je nutné nebo vhodné explicitně typovat ukazatel návratové hodnoty z volání funkce ''malloc''()?// Vyloženě nutné to v současných verzích Cčka není, přestože pro některé kompilátory (zvláště pak před standarem) to nutné bylo. V současné době je typ ''void*'' chápan jako generický ukazatel, jehož přetypování na konktrétní typ ukazatel na proměnné příslušné typu je zřejmé dle typu proměnné a není tak nutné explicitní přetypování uvádět. Jestli je vhodné explicitně přetypovat, tak na to se názory různí. Například v knize //S.G.Kochan: Programming in C (3rd Edition), Sams Publishing, 2005// je uváděn ''malloc'' vždy s explicitním přetypováním: int *a = (int*)malloc(10 * sizeof(int)); Naproti tomu v knize K//.N. King: C Programming A Modern Approach, Second Edition. W. W. Norton & Company, Inc., 2008// je preferována varianta bez přetypování: int *b = malloc(10 * sizeof(int)); Obě varianty jsou přípustné, argumenty proti explicitnímu přetypování jsou uváděny například: přehlednější kód a je to zbytečné, neboť dochází k přetypování automaticky. Na druhé straně relativně silné argumenty pro explicitní přetypování uvedené v diskusi [[http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc]] jsou například: You do cast, because: * It makes your code more portable between C and C++, and as SO experience shows, a great many programmers claim they are writing in C when they are really writing in C++ (or C plus local compiler extensions). * Failing to do so can hide an error: note all the SO examples of confusing when to write type * versus type **. * The idea that it keeps you from noticing you failed to #include an appropriate header file misses the forest for the trees. It's the same as saying "don't worry about the fact you failed to ask the compiler to complain about not seeing prototypes -- that pesky stdlib.h is the REAL important thing to remember!" * It forces an extra cognitive cross-check. It puts the (alleged) desired type right next to the arithmetic you're doing for the raw size of that variable. I bet you could do an SO study that shows that malloc() bugs are caught much faster when there's a cast. As with assertions, annotations that reveal intent decrease bugs. * Repeating yourself in a way that the machine can check is often a great idea. In fact, that's what an assertion is, and this use of cast is an assertion. Assertions are still the most general technique we have for getting code correct, since Turing came up with the idea so many years ago. Je to tak spíše věc osobního vkusu, preferencí, případně používaného kódovacího stylu. Q: //Jak funguje ukazatelová aritmetika v případě void*// Přičítá se hodnota jednoho bajtu, například pro hodnotu ukazatele ''void *a = 0x100;'' bude je hodnota ''(a+1)'' rovna 0x101. ===== 8. Standardní knihovny C, rekurze ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec08-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec08-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec08-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec08-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec08-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/11/22 12:29// ===== 9. Spojové struktury ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec09-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec09-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec09-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec09-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec09-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/11/29 15:22// ===== 10. Stromy ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec10-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec10-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec10-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec10-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec10-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// ===== 11. Abstraktní datový typ (ADT) - zásobník, fronta, prioritní fronta ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec11-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec11-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec11-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec11-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec11-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/08/17 00:10// ===== 12. Prioritní fronta, halda. Příklad použití prioritní fronty při hledání nejkratší cesty v grafu ===== * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec12-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec12-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec12-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec12-handout-3x3.pdf|}} * přiložené demonstrační programy: {{courses:b0b36prp:lectures:b0b36prp-lec12-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/12/20 08:45// --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/12/23 08:09// **Aktualizace**: Zjednoušení návratové hodnoty funkce ''dijkstra_solve()'' a zpřehlednění podmínky v ''pq_down()''. --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2018/01/08 08:48// **Aktualizace**: tdijkstra verze 2.3.6. - fix segfault při pokusu testovat řešení většího grafu než je vstupní graf ===== 13. Rezerva ===== [[#Stromy|Přednáška 10 - Stromy]] ===== 14. Přednáška na vyzvané téma ===== Zkouškový test Např. systémy pro správu verzí * prezentace: {{courses:b0b36prp:lectures:b0b36prp-lec14-slides.pdf|}} * zkrácená verze: {{courses:b0b36prp:lectures:b0b36prp-lec14-handout.pdf|}} * zkrácená verze 2x2: {{courses:b0b36prp:lectures:b0b36prp-lec14-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b0b36prp:lectures:b0b36prp-lec14-handout-3x3.pdf|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2017/12/20 14:15//