3. Řídicí struktury, výrazy a funkce

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

courses/b0b36prp/lectures/lec03.txt · Last modified: 2025/10/15 12:58 by faiglj