Datové typy, spojáky, překlad

BI-SPOL.21-19
  • Datové typy
  • Statická alokace proměnných
  • Dynamická alokace proměnných
  • Spojové seznamy
  • Modulární programování
    • Procedury
    • Funkce
    • Vstupní parametry
    • Výstupní parametry
  • Překladač
  • Linker
  • Debugger

Datové typy

  • V programovacích jazycích používáme proměnné
    • Uchovávají datovou hodnotu s nějakou vnitřní strukturou
    • Jsou identifikovány svými jmény (identifikátory)
    • Datový typ proměnné definuje vnitřní strukturu a její význam + jaké operace lze vykonávat
    • Podle typu je třeba alokovat paměť

Primitivní datové typy

  • Celočíselné
    • Existují různé délky - short, int, long, long long
    • Známkové (signed) - umí uložit i záporné hodnoty, používá se doplňkový kód
    • Neznámkové (unsigned) - jen kladné hodnoty, přímý kód
  • S pohyblivou řádovou čárkou
  • Znakové
    • Znaky jsou kódovány jako čísla, používá se ASCII, extended ASCII, Unicode, ...
    • char - zároveň slouží jako paměťově nejmenší celočíselný typ (vhodné např. pro optimalizaci, i když data v něm uložená nejsou textové znaky)
  • Logická hodnota
    • bool - true/false
    • Ve starším C přímo není, od C99 výše je nutné přidat knihovnu #include <stdbool.h>, od C23 existuje nativně
    • Zabírá 8b (1 byte), i když stačí k uložení 1 bit. V C++ lze využít efektivní std::vector<bool> nebo std::bitset<>
Klíčové slovo Obvyklá paměť (64-bit PC) Garantované minimum standardem Rozsah hodnot (pro 64-bit PC)
bool 1 Byte 1 Byte 0 (false) až 1 (true)
char 1 Byte 1 Byte -128 až 127
unsigned char 1 Byte 1 Byte 0 až 255
short 2 Byte 2 Byte (16 bitů) -32 768 až 32 767
unsigned short 2 Byte 2 Byte (16 bitů) 0 až 65 535
int 4 Byte 2 Byte (16 bitů) -2 147 483 648 až 2 147 483 647
unsigned int 4 Byte 2 Byte (16 bitů) 0 až 4 294 967 295
long 8 Byte (Linux) / 4 Byte (Win) 4 Byte (32 bitů) dle architektury (typicky jako long long na Linuxu)
unsigned long 8 Byte (Linux) / 4 Byte (Win) 4 Byte (32 bitů) dle architektury
long long 8 Byte 8 Byte (64 bitů) -9 223 372 036 854 775 808 až
float 4 Byte 4 Byte
double 8 Byte 8 Byte
long double 16 Byte (často jen 10B reálně) double
void Nemá smysl Nemá smysl Typ reprezentuje prázdnou množinu hodnot

Strukturované typy

Zatímco C++ má obří standardní knihovnu (STL) plnou kontejnerů jako std::vector, std::map nebo std::list, jazyk C žádné vestavěné kontejnery nemá.

  • Pole
    • Jediný vestavěný "kontejner" v C
    • Sekvenční blok paměti se statickou (předem danou) velikostí
    • Všechny prvky mají stejný datový typ
    • int cisla[10]
  • Struktura
    • Umožňuje seskupit různé datové typy pod jedno jméno
    • Neobsahuje funkce, pouze data
    • struct Uzivatel { int id; char jmeno[50]; float kredit; };
  • Union
    • Podobné structu, ale ukládá více datových typů na jedno místo
    • V jeden čas obsahuje pouze jednu hodnotu
    • union Kontakt { char email[50]; int telefon; };
  • Enum
    • Výčtový typ, sada pojmenovaných celočíselných konstant
    • V C je pod kapotou obyčejný int
    • enum Level { LOW = 25, MEDIUM = 50, HIGH = 75 };

Ukazatele

  • Pointer
  • Drží paměťovou adresu jiné proměnné
  • & = reference, zjištění adresy v paměti
  • * (při deklaraci) = označuje proměnnou jako pointer
  • * (v kódu) = dereference, zjištění hodnoty na adrese

Alokace proměnných

Statická alokace

  • Vzniknou běžnou deklarací

  • Velikost paměti se rozhodne už při kompilaci programu na základě datového typu

  • Z hlediska uložení v RAM a životnosti ji ale musíme rozlišit na dva typy:

    • A) Automatická statická alokace (Zásobník / Stack)
      • Běžné lokální proměnné uvnitř funkcí (např. int x;, char pole[100];)
      • Proměnné vznikají při vstupu do funkce a automaticky zanikají při jejím opuštění
      • Extrémně rychlý přístup, správa je automatická, zásobník má však omezenou velikost (hrozí Stack Overflow)
    • B) Globální statická alokace (Datové segmenty)
      • Globální proměnné a proměnné označené klíčovým slovem static.
      • Žijí v paměti po celou dobu běhu programu (od spuštění do konce).
      • Kam se ukládají:
        • .data segment - pro proměnné inicializované na nenulovou hodnotu (např. static int data[5] = {1,2,3,4,5}; )
          • .bss segment – pro neinicializované proměnné (OS je při spuštění vynuluje) (např. static int data[5];)
  • Výhody: Extrémně rychlé, bezpečné (nedochází k memory leakům, uvolní se automaticky)

  • Nevýhody: Nutné znát velikost předem (např. u pole), zásobník má omezenou velikost (může dojít ke Stack Overflow)

Dynamická alokace

  • Ukládají se na haldu (heap)

  • Vzniknou dynamicky za běhu programu

  • Programátor si o paměť musí říct sám int *pole = malloc() a poté ji uvolnit free(pole)

  • Výhody: Flexibilita (velikost se určuje za běhu), obrovská kapacita (omezená prakticky velikostí RAM)

  • Nevýhody: Pomalejší než stack, bez uvolnění zůstane blokovaná až do ukončení programu (Memory Leak)

Spojové seznamy

  • Dynamicky alokovaná struktura

  • Každý prvek obsahuje hodnotu a ukazatel na další prvek (případně i/jen předchozí)

  • Lze ukládat předem neznámý objem dat

  • Nelze jednoduše indexovat, lze ale libovolně přidávat/odebírat z jakékoliv pozice v seznamu

  • Přidání - jen malloc() a update pointeru

  • Find - průchod přes všechny pointery (v případě neseřazeného seznamu)

  • Odebrání - nejdříve je potřeba nalézt daný prvek a prvek před/za ním pro update pointerů

../../Attachments/Pasted image 20260608213104.png

Modulární programování

  • Rozdělení složitějších programů do více modulů (např. souborů, tříd)
  • Tyto moduly lze použít v různých dalších částech programu

Modul

  • Část programu, která poskytuje určitou funkcionalitu pro zbytek programu

  • "Black box s veřejným interfacem"

  • Modul má dvě části:

    • Specifikační
      • Deklarace poskytovaných prostředků/rozhraní
      • V C/C++ hlavičkový soubor .h/.hpp
    • Implementační
      • Definice a implementace poskytovaných prostředků
      • V C/C++ implementační soubor .c/.cpp

Procedury / funkce

  • Posloupnost příkazů uložených v paměti programu

  • "Podprogram", který řeší dílčí problém

  • Může mít vstupní parametry, případně něco vracet

  • Procedura - nic nevrací, typu void, jen provede posloupnost příkazů

  • Funkce - má návratovou hodnotu

  • typ jméno (seznam parametrů) { tělo }

    • Typ - návratový typ funkce, výstupní parametr z return
    • Jméno - identifikátor, pomocí kterého ji voláme
    • Seznam parametrů - lokální proměnné funkce, před zavoláním funkce jsou vyhodnoceny
    • Tělo - blok příkazů, jež je proveden po zavolání

Kompilace programu

Při spuštění kompilace, např. gcc main.c -o program.out, proběhnou 4 fáze:

1. Preprocessor

  • Pouze textově upravuje zdrojový kód na základě direktiv začínajících #

  • Vloží deklarace funkcí z knihoven #include

  • Nahradí makra #define

  • Vymaže části podmíněného překladu #ifdef

  • Vymaže všechny komentáře

  • Výstupem je soubor s příponou .i

2. Překladač (Compiler)

  • Překládá vyšší programovací jazyk do nižšího

  • Vezme čistý C kód, zkontroluje syntaxi

  • Přeloží do jazyka Assembleru, specifický pro danou architekturu

  • Provádí optimalizace kódu

    • Odstraní nepotřebné proměnné
    • Odstraní nedosažitelný kód
    • Spočítá konstanty (např. int sekundy_v_tydnu = 60 * 60 * 24 * 7; na int sekundy_v_tydnu = 604800;)
    • Rozbalí jednoduché smyčky (např. for (int i = 0; i < 3; i++) { printf("Ahoj"); } na printf("Ahoj"); printf("Ahoj"); printf("Ahoj");)
    • Inlinuje jednoduché funkce (např. int add(int a, int b) { return a+b; }; int vysledek = add(5,10); na int vysledek = 5 + 10;)
  • Výstupem soubor .s (často se ale ani neukládá na disk, rovnou se předá assembleru a výstupem je ˙.o˙)

3. Assembler

  • Převede textový soubor v Assembleru do čisté binární formy

  • Výstup obsahuje strojový kód, ale nelze ještě spustit

  • Výstupem soubor .o

4. Linker

  • Vezme všechny objektové .o soubory a spojí je dohromady

  • Nalinkuje potřebné knihovny

  • Statické knihovny

    • V Linuxu soubory .a, ve Windows .lib
    • Pokud program používá funkci ze statické knihovny, linker najde její strojový kód a "vlepí" ho přímo do výsledného programu
    • Výsledný program je soběstačný, lze ho přenést jinam, ale soubor je velký. Zároveň bez rekompilace nedostane opravy při aktualizaci knihovny
  • Dynamické knihovny

    • V Linuxu soubory .so, ve Windows .dll
    • Linker do výsledného souboru pouze vloží poznámku, že je potřeba určitá dynamická knihovna. Ta se načte do RAM až při spuštění programu
    • Pokud více programů používá stejnou knihovnu, sdílí se jedno místo v paměti
    • Standardní knihovna C se na moderních systémech linkuje téměř výhradně dynamicky
  • Výstupem spustitelný soubor, na Linuxu bez přípony nebo .out, na Windows .exe

Debugger

  • Samostatný nástroj pro ladění a hledání chyb v kódu (např. program GDB)
  • Umožňuje např. krokování programu, sledování obsahu proměnných
  • Je vhodné kompilovat s informacemi pro ladění gcc -g a vypnutou optimalizací gcc -O0
    • Překladač do binárního souboru vloží "mapu", která instrukce odpovídá jakému řádku kódu

Vytvořeno: 9. 6. 2026, 13:06
Poslední aktualizace: 9. 6. 2026, 13:09