{{indexmenu_n>2}} ====== Přednášky ====== Podklady přednášek pro aktuální akademický rok 2019/2020. 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 **K.N. King: C Programming A Modern Approach, Second Edition. W. W. Norton & Company, Inc., 2008**/* 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. [[https://app.sli.do/event/o2n6i5nd/live/questions | On-line otázky na přednášce]] /* [[https://docs.google.com/forms/d/e/1FAIpQLSfKbjdQoJG6Pjq5AOkol5KsmYosUmv3xfBFQ17hhkvv-TLHpw/viewform|On-line otázky na přednášce]] */ ^ #VTýden ^ Týden ^ Téma ^ Úterý 14:30 (Místnost T2:D3-209) ^ | 01 | 08. |[[#Informace o předmětu, základy programování v C | Přednáška 01 - Informace o předmětu, Úvod do programování v C]]\\ K. N. King: kapitoly 1, 2 a 3 | 18.02. - lec01 | | 02 | 09. |[[#Výrazy, řídicí struktury a funkce|Přednáška 02 - Výrazy, řídicí struktury a funkce]]\\ K. N. King: kapitoly 4, 5, 6 a 20 | 25.02. - lec02 | | 03 | 10. |[[#Datové typy: pole a ukazatele. Paměťové třídy. Volání funkcí|Přednáška 03 - Datové typy: pole a ukazatele. Paměťové třídy. Volání funkcí]]\\ K. N. King: kapitoly 7, 8, 9, 10, 11 a 18 | 03.03. - lec03 | | 04 | 11. |[[#Pole, řetězce a ukazatele| Přednáška 04 - Pole, řetězce a ukazatele]]\\ K. N. King: kapitoly 8, 11, 12, 13 a 17| 10.03. - lec04 | | 05 | 12. |[[#Datové typy: Složený typ, výčtový typ a bitová pole. Preprocesor a sestavení programu|Přednáška 05 - Datové typy: Složený typ, výčtový typ a bitová pole. Preprocesor a sestavení programu]]\\ K. N. King: kapitoly 10, 14, 15, 16 a 20 | 17.03. - lec05 | | 06 | 13. |[[#Vstup / výstup a standarní knihovny C|Přednáška 06 - Vstup / výstup a standarní knihovny C]] \\ K. N. King: kapitoly 21, 22, 23, 24, 26 a 27 | 24.03. - lec06 | | 07 | 14. |[[#Paralení programování, paralelní výpočty a synchronizační primitiva|Přednáška 07 - Paralení programování, paralelní výpočty a synchronizační primitiva (semafory, zprávy a sdílená paměť )]] | 31.03. - lec07 |chapters | 08 | 15. |[[#Vícevláknové programování, modely aplikací, POSIX vlákna C11 vlákna|Přednáška 08 - Vícevláknové programování, modely aplikací, POSIX vlákna C11 vlákna]] | 07.04 - lec08 | | 09 | 15. |[[#Praktická ukázka a ladění programu|Přednáška 09 - Praktická ukázka a ladění programu]] | 14.04. - lec09 | | 10 | 17. |[[#ANSI C, C99, C11 a rozdíly mezi C a C++. Úvod do objektově orientovaného programování v C++|Přednáška 10 - ANSI C, C99, C11 a rozdíly mezi C a C++. Úvod do C++]] | 21.04. - lec10 | | 11 | 18. | Přednáška 11 - [[#Stručný úvod do C++|Stručný úvod do C++]] //Objektově orientované programování v C%%++%%: třídy, objekty, dědičnost a polymorfismus// | 28.04. - lec 11| /* //Státní svátek// */ | 12 | 19. | - | **05.05. páteční rozvrh** | | 13 | 20. | Přednáška 12 - [[#C++ konstrukty v příkladech|C++ konstrukty v příkladech]] //Systémy pro správu verzí// | 12.05. | | 14 | 21. |Přednáška 13 - // **//Zkouškový písemný test//**// Objekty v C%%++%% | 19.05. - lec 13 | 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. **Podklady budou průběžně aktualizovány.** ===== 1. Informace o předmětu, základy programování v C ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec01-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec01-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec01-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec01-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec01-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/03/05 23:31// ===== 2. Výrazy, řídicí struktury a funkce ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec02-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec02-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec02-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec02-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec02-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// ===== 3. Datové typy: pole a ukazatele. Paměťové třídy. Volání funkcí ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec03-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec03-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec03-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec03-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec03-codes.zip|}} Na přednášce zmíněná funkce ''fgets()'' pro řešení HW 03 nemusí být zas až tak výhodná a mnohem výhodnější může být využití funkce ''getline()'', která však pracuje pouze s dynamicky alokovanou pamětí. --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// ===== 4. Pole, řetězce a ukazatele ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec04-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec04-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec04-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec04-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec04-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// **Příklad z přednášky** Příklad na přednášce demonstrující použití kompilace s debug, např. ''clang -g'' a ''valgrind'' pro rychlé nalezení problémového místa nám pomohl ukázat na zápis mimo přidělenou paměť na řádku 13, tj. ''sieve[i*j] = 0;'' 10 for (int i = 2; i < 1000000; ++i) { 11 if (sieve[i]) { 12 for (int j = i; i*j < 1000000; ++j) { 13 sieve[i*j] = 0; 14 } 15 } 16 } Přestože řádek vypadá relativně neškodně, je nutné uvažovat jakou hodnotu bude mít výraz ''i*j'' pokud jsou obě proměnné typu ''int''. Zcela jistě se totiž hodnota výrazu, např. 47000 * 47000, do rozsahu typu ''int'' reprezentovaného 32-bity nevejde. Možných řešení je více, jedno z nich může být využít automatické typové konverze na větší z typů, např. 10 for (int i = 2; i < 1000000; ++i) { 11 if (sieve[i]) { 12 for (long j = i; i*j < 1000000; ++j) { 13 sieve[i*j] = 0; 14 } 15 } 16 } Rozdíl je na řádku 12 v použití typu ''long'' pro řídicí proměnnou ''j''. V tomto případě je hodnota výrazu ''i*j'' typu ''long'' a problém je vyřešen. Každopádně mnohonásobné použití magické konstanty ''1000000'' lze vhodně nahradit např. #define SIEVE_SIZE 1000000 **Dotazy z přednášky** Q: //Co udělá ''realloc()'' při zmenšení velikost nebo nastavení velikosti na 0?// Zmenší alokované místo a v případě 0, např. ''realloc(ptr, 0);'' uvolní paměť a odpovídá tak volání ''free(ptr);''. **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. --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2019/03/05 13:27// ===== 5. Datové typy: Složený typ, výčtový typ a bitová pole. Preprocesor a sestavení programu ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec05-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec05-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec05-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec05-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec05-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// **Dotazy z přednášky** Q: //Jakým způsobem mohou přetypovat dynamicky alokovaný souvislý blok paměti na dvourozměrné pole o ''cols'' sloupcích?// Předně je nutné zajistit, že ukazatel odkazuje na souvislý blok paměti o příslušné velikost. Následně lze definovat proměnnou se specifikací počtu sloupců např. ''int(*matrix)[cols] = (int(*)[cols])m;'', kde ''m'' je ukazatel na souvislý blok ''int'' hodnot. V kontextu programu to může vypadat, následovně. void *alloc(size_t size) { void *ret = malloc(size); if (ret == NULL) { fprintf(stderr, "Malloc fail!"); exit(-1); } return ret; } void print_matrix(int rows, int cols, int m[][cols]) { for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { printf("%2d ", m[r][c]); } printf("\n"); } } int rows = 2; int cols = 3; int *m = alloc(rows * cols * sizeof(int)); for (int i = 0; i < rows * cols; ++i) { m[i] = i + 1; } int(*matrix)[cols] = (int(*)[cols])m; print_matrix(rows, cols, matrix); free(m); Můžeme toho například využít při řešení [[courses:b3b36prg:hw:hw05|HW05]], kdy si nejdříve odladíme funkce pro dvojrozměrné pole, které následně můžeme přímo využít pro rozšířenou implementaci s využitím dynamické alokace. Q: //Je nutné v případě dynamicky alokované matice, jako pole ukazatelů na pole hodnot, postupně paměť uvolňovat podobně jako při alokaci?// Ano je. Nejdříve je nutné postupně uvolnit dílčí pole reprezentující sloupce v jednotlivých řádcích a následně pak uvolnit pole ukazatelů (na řádky). S výhodou je možné si definovat funkce pro alokaci a uvolnění paměti, např. void *alloc(size_t size) { void *ret = malloc(size); if (ret == NULL) { fprintf(stderr, "Malloc fail!"); exit(-1); } return ret; } int **matrix_alloc(int rows, int cols) { int **matrix = alloc(rows * sizeof(int *)); for (int r = 0; r < rows; ++r) { matrix[r] = alloc(cols * sizeof(int)); } return matrix; } void matrix_free(int rows, int cols, int **matrix) { if (matrix) { for (int r = 0; r < rows; ++r) { if (matrix[r]) { free(matrix[r]); } } free(matrix); } } které můžeme následně použít například const int ROWS = 2; const int COLS = 2; int **matrix = matrix_alloc(ROWS, COLS); matrix_free(ROWS, COLS, matrix); Pragmatičtější však může být použití složeného typu ''struct''. --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2019/03/19 22:46// ===== 6. Vstup / výstup a standarní knihovny C ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec06-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec06-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec06-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec06-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec06-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// **Dotazy z přednášky** Q: //Jakým funguje Quick-Sort?// Jedná se o algoritmus řazení na principu rozděl a panuj, který je například popsán na [[https://cs.wikipedia.org/wiki/Quicksort]] nebo znázorněn na [[https://www.youtube.com/watch?v=ywWBy6J5gz8|Quick-sort with Hungarian (Küküllőmenti legényes) folk dance]]. ===== 7. Paralení programování, paralelní výpočty a synchronizační primitiva ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec07-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec07-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec07-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec07-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec07-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 15:35// ===== 8. Vícevláknové programování, modely aplikací, POSIX vlákna C11 vlákna ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec08-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec08-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec08-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec08-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec08-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2018/05/16 07:54 CEST// **Aktualizace**: Oprava output_thread() - zamčení/odemčení mutexu vně cyklu --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 19:49// ===== 9. Praktická ukázka a ladění programu ===== Přednáška formou ukázek. --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2018/02/19 16:00// **Dotazy z přednášky** Q: //Proč při nastavení terminálu do raw režimu nedochází k tisku nového řádku na začátku?// Při nastavení raw režimu ''cfmakeraw()'' je vypnuto zpracování výstupních znaků (//output postprocessing//), které automaticky nahrazuje konec řádku za "návrat vozíku a nový řádek" (NL na CR-NL). Vyřešit lze buď explicitním uvedením znaku '\r', což ale není příliš kompatibilní nebo povolením //output processing// (OPOST) např. static struct termios tio; tcgetattr(STDIN_FILENO, &tio); cfmakeraw(&tio); // nastavení raw režimu viz man termios tio.c_oflag |= OPOST; //zapnutí output processing tcsetattr(STDIN_FILENO, TCSANOW, &tio); ===== 10. ANSI C, C99, C11 a rozdíly mezi C a C++. Úvod do objektově orientovaného programování v C++ ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec10-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec10-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec10-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec10-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec10-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 19:48// **Dotazy / připomínky z přednášky** C: //Při přepnutí terminálu do raw režimu příkazem ''stty raw'' stále dochází k tisku stisknuté klávesy // Pokud tomu tak je (např. v Linuxu), je nutné ještě vypnout echo například ''stty -noecho'' příkaz pro nastavení termínálu tak může být stty raw -echo a nastavit zpět pak lze např. stty -raw echo ===== 11. Stručný úvod do C++ ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec11cc-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec11cc-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec11cc-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec11cc-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec11cc-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 19:48// ===== 12. C++ konstrukty v příkladech ===== * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec12cc-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec12cc-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec12cc-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec12cc-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec12cc-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2020/02/12 19:48// ===== Systémy pro správu verzí ===== Původní podklady pro obecný úvod do verzovacích systémů a to jak centralizovaných tak distribuovaných, s příkladem použití systémů RCS, SVN a Git. * prezentace: {{courses:b3b36prg:lectures:b3b36prg-lec12-slides.pdf|}} * zkrácená verze: {{courses:b3b36prg:lectures:b3b36prg-lec12-handout.pdf|}} * zkrácená verze 2x2: {{courses:b3b36prg:lectures:b3b36prg-lec12-handout-2x2.pdf|}} * zkrácená verze 3x3: {{courses:b3b36prg:lectures:b3b36prg-lec12-handout-3x3.pdf|}} * přiložené demonstrační programy: {{:courses:b3b36prg:lectures:b3b36prg-lec12-codes.zip|}} --- //[[faiglj@fel.cvut.cz|Jan Faigl]] 2018/02/19 16:00//