Table of Contents

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.

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. 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. Přednáška 02 - Základy programování v C
S. G. Kochan: kapitoly 2 a 3
11.10. - lec02
03 42. 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. Přednáška 04 - Řídicí struktury, výrazy a funkce
S. G. Kochan: kapitoly 4, 5, 6 a 12
25.10. - lec04
05 44. Přednáška 05 - Pole, ukazatel, textový řetězec
S. G. Kochan: kapitoly 7, 10 a 11
01.11. - lec05
06 45. 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. 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. Přednáška 08 - Standardní knihovny C. Rekurze.
S. G. Kochan: kapitola 16 a Appendix B
22.11. - lec08
09 48. Přednáška 09 - Spojové struktury 29.11. - lec09
10 49. Přednáška 10 - Stromy 06.12. - lec10
11 50. Přednáška 11 - Abstraktní datový typ (ADT) - zásobník, fronta, prioritní fronta 13.12. - lec11
12 51. 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 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

1. Informace o předmětu, Procedurální programování základy programování v C

Jan Faigl 2017/10/04 15:39

2. Základy programování v C

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");

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

Jan Faigl 2017/08/17 00:10

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 <stdio.h>
 
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

Jan Faigl 2017/08/17 00:10

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

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 <stdio.h>
 
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í

Jan Faigl 2017/08/17 00:10

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 <stdio.h>
 
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ů

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:

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

Jan Faigl 2017/11/22 12:29

9. Spojové struktury

Jan Faigl 2017/11/29 15:22

10. Stromy

Jan Faigl 2017/08/17 00:10

11. Abstraktní datový typ (ADT) - zásobník, fronta, prioritní fronta

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

Jan Faigl 2017/12/20 08:45

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().

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

Přednáška 10 - Stromy

14. Přednáška na vyzvané téma

Zkouškový test

Např. systémy pro správu verzí * prezentace: b0b36prp-lec14-slides.pdf * zkrácená verze: b0b36prp-lec14-handout.pdf * zkrácená verze 2×2: b0b36prp-lec14-handout-2x2.pdf * zkrácená verze 3×3: b0b36prp-lec14-handout-3x3.pdf Jan Faigl 2017/12/20 14:15