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

On-line otázky na přednášce

#VTýden Týden Téma Úterý 14:30 (Místnost T2:D3-208)
01 08. Přednáška 01 - Informace o předmětu, Úvod do programování v C
K. N. King: kapitoly 1, 2 a 3
20.02. - lec01
02 09. Přednáška 02 - Výrazy, řídicí struktury a funkce
K. N. King: kapitoly 4, 5, 6 a 20
27.02. - lec02
03 10. 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
06.03. - lec03
04 11. Přednáška 04 - Pole, řetězce a ukazatele
K. N. King: kapitoly 8, 11, 12, 13 a 17
13.03. - lec04
05 12. 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
20.03. - lec05
06 13. Přednáška 06 - Vstup / výstup a standarní knihovny C
K. N. King: kapitoly 21, 22, 23, 24, 26 a 27
27.03. - lec06
07 14. Přednáška 07 - Paralení programování, paralelní výpočty a synchronizační primitiva (semafory, zprávy a sdílená paměť ) 03.04. - lec07
08 15. Přednáška 08 - Vícevláknové programování, modely aplikací, POSIX vlákna C11 vlákna 10.04. - lec08
09 16. Přednáška 09 - Praktická ukázka a ladění programu 17.04. - lec09
10 17. Přednáška 10 - ANSI C, C99, C11 a rozdíly mezi C a C++. Úvod do C++ 24.04. - lec10
11 18. Státní svátek 01.05. Státní svátek
12 19. Státní svátek 08.05. Státní svátek
13 20. Přednáška 11 - Stručný úvod do C++ Objektově orientované programování v C++: třídy, objekty, dědičnost a polymorfismus 15.05. - lec11
13 20. Přednáška 12 - C++ konstrukty v příkladech Systémy pro správu verzí 17.05. čtvrtek - lec12
14 21. Přednáška 13 - Zkouškový písemný test Objekty v C++ 22.05. - Test

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

Jan Faigl 2018/02/27 12:50

2. Výrazy, řídicí struktury a funkce

Jan Faigl 2018/02/27 12:50

3. Datové typy: pole a ukazatele. Paměťové třídy. Volání funkcí

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

Jan Faigl 2018/02/03 09:21

4. Pole, řetězce a ukazatele

Příklad 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.

Jan Faigl 2018/03/13 12:53

5. Datové typy: Složený typ, výčtový typ a bitová pole. Preprocesor a sestavení programu

Jan Faigl 2018/03/21 07:53

6. Vstup / výstup a standarní knihovny C

Jan Faigl 2018/03/27 19:14

7. Paralení programování, paralelní výpočty a synchronizační primitiva

Jan Faigl 2018/04/11 09:05

8. Vícevláknové programování, modely aplikací, POSIX vlákna C11 vlákna

Jan Faigl 2018/05/16 07:54 CEST Aktualizace: Oprava output_thread() - zamčení/odemčení mutexu vně cyklu

Jan Faigl 2018/02/19 16:00

9. Praktická ukázka a ladění programu

Přednáška formou ukázek.

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++

Jan Faigl 2018/02/19 16:00

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++

Jan Faigl 2018/05/15 08:55

12. C++ konstrukty v příkladech

Jan Faigl 2018/05/10 22:24

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.

Jan Faigl 2018/02/19 16:00

courses/b3b36prg/lectures/start.txt · Last modified: 2018/05/16 07:55 by faiglj