Týždeň 05

reprezentácia času v počítači, pretečenie, enumeračné typy, exit status, štandardné kanály/prúdy

Záznam z prednášky

Oznamy

  • (slide) Problemset 2
    • samostatný kanál na Mattermost-e s názvom ~problems-to-solve
    • -Wconversion a úprava pomocnej funkcie
  • (slide) Namakaný deň 2019 is comming
    • 10.apr.2019
    • prednáška v stredu nebude, ale všetci ste pozvaní na akciu ;)

Date and Time Representation

  • (slide) Vráťme sa teraz k problému, ktorý sme odložili - v štruktúre struct person, ktorú sme si vytvorili, sme zavrhli možnosť ukladať informáciu o veku osoby vo forme celého čísla typu int. A to hlavne z dôvodu, že samotná aktualizácia veku sa stane problémom - nebudeme vedieť, kedy máme vek u každej jednej osoby aktualizovať a budeme to musieť robiť hromadne pre všetky z nich. Chýbal nám spôsob, akým by sme vedeli reprezentovať dátum narodenia každej osoby.

  • (slide) Dnes sa teda pokúsime odpovedať aj na otázku: Ako je teda reprezentovaný čas v počítači?

DateTime Structure

  • (slide) Čo je vlastne čas a dátum? Len ďalší štruktúrovaný údajový typ. Ak budeme chcieť reprezentovať dátum, jedná sa o štruktúru pozostávajúcu z dňa, mesiaca a roku. Ak zasa čas, bude sa jednať o štruktúru hodiny, minúty, sekundy. Samozrejme môžeme uvažovať aj o milisekundách a mikrosekundách, ale tie nás momentálne nebudú zaujímať.

  • Samozrejme však môžeme vytvoriť samostatnú štruktúru, ktorá bude obsahovať všetky tieto údaje dokopy. Vyzerať môže napríklad takto (slide):

    Poznámka

    Samozrejme na reprezentácie jednotlivých členov by bolo možné v tomto v prípade použiť menšie údajové typy, ako je typ int. Pre ilustráciu však stačí aj tento typ.

Enumeration Constants

Unix Time

  • Interne sa však čas zvykne uchovávať vo forme celého čísla, ktoré je reprezentované ako počet sekúnd od počiatku epochy. Epocha sa začala rátať presne od polnoci (00:00:00) 1. januára 1970. Tento čas je tiež známy pod ďalšími menami, ako Coordinated Universal Time (UTC) alebo POSIX time alebo Epoch time. (slide)

    Poznámka

    Vhodnými ilustráciami pre epochu môže byť napr. pred naším letopočtom / nášho letopočtu alebo pred Kristom a po Kristovi.

  • Ak chceme v jazyku C získať hodnotu aktuálneho času (čiže počet sekúnd od počiatku epochy), môžeme za tým účelom použiť funkciu time() z knižnice time.h (slide). Príklad použitia si ukážeme na fragmente kódu, ktorý každú sekundu vypíše počet uplynulých sekúnd od počiatku epochy (unixtime.c):

Representing the Number

Overflow

  • Po spustení sa síce žiadny koniec sveta neudial, ale udiala sa iná vec. Ako sa volá?

  • Tento problém sa volá pretečenie (z angl. overflow) (slide) alebo v tomto prípade môžeme rovno hovoriť o integer overflow. Ku pretečeniu dôjde vtedy, keď (slide)

    výsledkom aritmetickej operácie je číslo, ktoré nie je možné zapísať na uvedený počet bytov (je mimo rozsah).

  • Tento problém sa dá jednoducho ilustrovať pomocou tachometra v aute (slide) - keď dosiahne max hodnotu 99999, po prejdení +dalšieho kilometra sa vynuluje.

  • Takže tomuto problému vieme v tomto prípade predísť jednoducho tým, že použijeme vhodne veľký údajový typ. Napríklad long. Ten nám zabezpečí výrazne viac času, ako typ int.

Structure in Structure

Exit Status

  • Na tomto mieste si dovolím jemnú odbočku a síce pozrime sa na deklaráciu funkcie main(), ktorá vyzerá nasledovne (slide):

  • Pracovať s parametrami príkazového riadku ste sa naučili v rámci predmetu Základy algoritmizácie a programovania v rámci zimného semestra. Viete však, čo znamená návratová hodnota typu int? A načo sa používa?

  • Tejto návratovej hodnote hovoríme exit status (slide). A je to spôsob, akým vieme z našej aplikácie dať vedieť operačnému systému, ako sa naša aplikácia ukončila - či úspešne alebo neúspešne. Ak sa ukončila úspešne, vrátime systému hodnotu 0. Ak sa aplikácia ukončila neúspešne (došlo k zlyhaniu), vrátime hodnotu inú ako je hodnota 0. Na základe tejto hodnoty môžeme dokonca identifikovať problém, ku ktorému došlo.

  • V Linux-ových systémoch sa viete k hodnote exit status dostať pomocou premennej prostredia $? (slide), ktorá vždy obsahuje exit status posledne ukončeného programu.

  • To si môžeme ukázať na príklade príkazu ls:
    • Ak vypíšeme obsah existujúceho priečinka, po vypísaní obsahu premennej $? dostaneme hodnotu 0:

    • Ak však necháme vypísať obsah neexistujúceho priečinku alebo priečinku, do ktorého nemáme povolený prístup, dostaneme inú hodnotu:

  • Toto viete s úspechom využiť vo vlastných skriptoch (ktoré nie sú predmetom záujmu tohto kurzu) a rozlične na vzniknutú situáciu reagovať. Často sa viete stretnúť s tzv. one-linermi v tvare:

  • Častokrát si však vystačíte aj len s dvoma hodnotami - s hodnotou 0, že aplikácia skončila v poriadku a s hodnotou 1, že sa aplikácia ukončila zle. Pre tieto dve hodnoty máme v knižnici stdlib.h zadefinované dve makrá (slide):
    • EXIT_SUCCESS
    • EXIT_FAILURE
  • Pozor však na jednu dôležitú vec - aj napriek tomu, že návratový typ funkcie main() a teda exit status je typu int, jedná sa o 8b hodnotu. Hodnoty, ktoré viete z funkcie main() vrátiť, môžu byť len z rozsahu 0255.

Standard Streams

  • obrázok
  • príklad s príkazom ls
  • stdin
  • stdout
  • stderr

Additional Resources