— Jan Faigl 2025/10/15 12:58
#define BITS 4 //number of bits to print (4 to make it readable) void print_binary(char *prefix, uint8_t n) { printf(prefix, n); int mask = 1<<(BITS-1); // we need to shift 1 to BITS position, thus -1 for (int i = 0; i < BITS; ++i) { putc((n & mask) ? '1' : '0', stdout); mask = mask >> 1; // } printf("\n"); } uint8_t a = 4; print_binary("a dec: %d bin: ", a);
Dotazy z přednášek
Q: Proč program i po stísku Ctrl+D dále pokračuje v načítání vstupu?
Je to proto, že Ctrl+D bylo stisknuto pro nějaký rozepsaný vstup, který nebyl programu ještě odeslán klávesou Enter
, resp. znakem nového řádku.
Vstup programu na stdin
je v našem případě předáván prostřednictvím emulátoru terminálů, který je ve výchozím nastavení řádkově orientovaný, tj. náš vstup je programu předám po stisku klávesy Enter
. Stiskem kombince Ctrl+D
vyvoláme předání aktuálního vstupu programu. Pokud je aktuální vstup prázdný, generuje terminál EOF
(End Of File), standardní vstup je uzavřen a následně čtení např. funkcí scanf()
nebo getchar()
vrací hodnotu EOF (-1). Více informací lze nalézt např. v manuálové stránce termios v části Special Characters znak EOF
.
EOF | Special character on input and is recognized if the ICANON flag is set. When received, all the bytes waiting to be read are immediately passed to the process, without waiting for a newline, and the EOF is discarded. Thus, if there are no bytes waiting (that is, the EOF occurred at the beginning of a line), a byte count of zero is returned from the read(), representing an end-of-file indication. If ICANON is set, the EOF character is discarded when processed. |
Q: Jak mohu porovnat dva soubory?
Kromě použítí příkazu diff
existují další nástroje, např. https://meldmerge.org/, případně konzolový vimdiff
nebo grafický gvimdiff
editoru vim, více např. vimdiff-nastroj-drsnaku.
Q: Proč kompilátor hlásí chybu chybějícího znaku nového řádku na konci souboru?
Při kompilaci programu bez znaku konce řádku na konci souboru, např. při kompilaci clang -pedantic -Wall -Werror main.c
, dojde k chybě.
error: no newline at end of file [-Werror,-Wnewline-eof]
Je do dáno historickým rozhodnutím, že neprázdný zdrojový soubor by měl být zakončem znakem nového řádku. Je tak součástí standardu jazyka.
Dobrý důvod proč je vhodné zakončovat soubory koncem řádku je například při použit vložení souborů příkazem preprocesoru #include
, který nevkládá nový řádek, přestože to mnoho moderních kompilátorů dělá. Stále však platí, že starší kompilátory s tím mohou mít potíže a může to být velmi těžko odhalitelná chyba. V novém C++11, již tento požadevek není, stále však zůstává pro C99.
V případě VS Code, podobně jako v celé řadě jiných programů, lze chování editor nastavit, např. Insert New Line at the End of Files.
Q: Je možné umístit návěští pro příkaz goto
před cyklus?
V zásadě ano, jediným zásadním omezením je pouze v rámci jedné funkce. Dále je nutné, aby za návěštím byl příkaz, například definice proměnné není příkaz. Musí existovat adresa instrukce, na kterou má goto
skočit.
Návěští před začátkem cyklu | Návěští před začátkem cyklu před definicí proměnné (nelze) | Návěští před začátkem cyklu s příkazem |
---|---|---|
int a; // začátek platnosti a outer: for (int i = 0; i < 3; ++i) { goto outer; } | outer: // definice proměnné není příkaz int a; for (int i = 0; i < 3; ++i) { goto outer; } | outer: // po návěští je příkaz ; int a; for (int i = 0; i < 3; ++i) { goto outer; } |
Nicméně 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í.