Displej - zpráva

NSWI170, 2026, Labs 06

Jáchym Bártík

Feedback

  • Minimalizace závislostí
    • Potřebuje displej vědět o času?
    • Potřebují stopky vědět o displeji či tlačítkách?
  • Omezení scope
    • Konstanty, enumy, atd.
    • Rozšíření principu zapouzdření (Pravidlo #5)
  • Unforgivable curses
    • Zejména konstanty (Pravidlo #2) - velmi snadno se kontroluje

Pointery (ukazatele)

  • Ukazují na nějakou adresu v paměti
    • Ta se interpretuje jako hodnota daného typu.
  • Vytvoření:
    • Defaultně - ukazuje na náhodné místo (nepoužívejte)
    • nullptr - neukazuje nikam (používejte místo NULL)
    • Adresa nějaké konkrétní hodnoty (operátor &)
    • Výpočet z jiného pointeru (pointerová aritmetika)
    • Alokace - operátor new, funkce malloc, ...

int* p1;            // Pointer to a random place in memory.
int* p2 = nullptr;  // Pointer to nowhere.

int x = 42;
int* p3 = &x;       // Pointer to the place where the value 42 is stored.
int y = *p3 + 35;   // Pointer dereference - access to the value it points to.
cout << y;          // 77

int* p4 = p3 + 1;   // Pointer to the next integer after p3.
int* p5 = malloc(7 * sizeof(int));  // Pointer to the first element in an array of seven integers.
    

Pointerová aritmetika

  • Pointer je vlastně jen adresa místa v paměti, neboli číslo
    • Z jedné adresy se můžeme snadno posunout na další
    • Pozor: pointery nealokují paměť!

int x = 42;
int* p = &x;
*(p + 1) = 13;
    
*(p - 1) *p *(p + 1) *(p + 2) *(p + 3)
? 42 13 ? ?
  • Pointery jsou vlastně jako pole
    • Přesněji, pole je pointer na první prvek
  • Platí *(p + i) = p[i] (pro integer i)
    • Pokud pracujete s poli, vždy používejte závorky []

Na co si dát pozor

  • Pointery mohou vést na nedefinované chování
    • Přepsání libovolné paměti programu
      • Včetně instrukcí (funkční pointery ...)
    • Paměť ani nemusí být alokována (Exception)
  • Neinicializované pointery mají náhodnou hodnotu
    • Vždy je rovnou inicializujte (nebo použijte nullptr)!
  • Indexování pole mimo rozsah se nikde neověřuje
    • Opět hrozí přístup na náhodnou adresu
    • Buffer overflow
  • Memory leaky
    • Při ruční alokaci paměti je nutné ji zase dealokovat (pomocí delete)

String

  • V C++ existuje třída String
  • V C je to složitější - musíme použít const char*
    • Pole konstantních znaků
    • Je ukončeno znakem '\0' (null)

const char* string = "Hello world";
    
H e l l o W o r l d \0

int foo(const char* s) {
    int i = 0;
    while (s[i]) // null character is treated as false
        i++;
    return i;
}

foo(string);     // What is the output of this function?
    

Cvičení #1

  • Zobrazte na displeji krátkou zprávu
    • Upravte třídu pro displej tak, aby jí bylo možné předat zprávu (const char*)
    • Z ní vypište první čtyři znaky
      • Použijte multiplexing (jako minule)
      • Mapa znaků je v knihovně funshield.h
      • Znaky mimo zprávu považujte za prázdné
  • Bonus: Tlačítka posouvají zprávu doleva a doprava

Cvičení #2

  • Zobrazte na displeji běžící zprávu
    • Každých 300 ms posuňte zobrazované znaky o jedna
    • Struktura:
      • Třída A - zapisuje na displej pomocí multiplexingu
      • Třída B - řeší rotování zprávy (říká A co má vypsat)
      • Funkce loop - komunikuje pouze s B
    • Příklad - Hello:
      ___H __He _Hel Hell ello llo_ lo__ o___ ____

Domácí úkol #6

  • Vytvořte displej zobrazující běžící zprávu
    • Vyjděte ze cvičení #2
    • Zpráva se předává sériovým portem
      • Vždy se zobrazí celá
      • Jakmile skončí, zjistíte, jestli existuje nová (pokud ne, zobrazíte znovu starou)
      • Komunikaci řeší knihovna (ke stažení na recodexu)
    • Používejte pointery a C stringy (const char*), ne pokročilé C++ konstrukce