Search
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.
.zip
On-line otázky na přednášce
— Jan Faigl 2017/10/04 15:39
— 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.
char
lec02/bool.c
Q: Jak vytisknu znak '%' nebo '\' ve funkci printf()?
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í.
— 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.
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; }
— Jan Faigl 2017/10/26 09:42 Aktualizace: Doplnění kódů pro příklady nedefinovaného chování
Q: Je možné umístit návěští pro příkaz goto před cyklus?
goto
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).
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í.
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:
scanf()
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)) { ... }
— Jan Faigl 2017/11/09 21:56 Aktualizace: Oprava překlepů a přidání snímku 26 s příkladem na extern
extern
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é?
unsigned int
Minimální kód programu read_unsigned.c může být například:
read_unsigned.c
#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
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. ...
“%u”
integer
unsigned long
'-
— Jan Faigl 2017/11/15 16:05
Q: Je nutné nebo vhodné explicitně typovat ukazatel návratové hodnoty z volání funkce malloc()?
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:
void*
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.
void *a = 0x100;
(a+1)
— Jan Faigl 2017/11/22 12:29
— Jan Faigl 2017/11/29 15:22
— 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().
dijkstra_solve()
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
Přednáška 10 - Stromy
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