Lekce 4 - Proměnné - Datové typy a deklarace
V předchozím kvízu, Kvíz - Úvod do programování Arduina - Vývojářské nástroje, jsme si ověřili nabyté zkušenosti z předchozích lekcí.
V tomto tutoriálu programovacího jazyka pro Arduino se již začneme věnovat vlastnímu jazyku. Je odvozený od jazyka Wiring a jmenuje se jednoduše Arduino language. Wiring patří do rodiny jazyků C a konkrétně je odvozený od C++. Zaměříme se na proměnné, jejich datové typy a deklarace. V závěru si povíme, jak kód správně komentovat.
Jazyk Arduino
Při psaní kódu je třeba dbát na několik pravidel. Každý řádek s voláním funkce nebo deklarace proměnné je zakončený středníkem. Nedává se pouze na konce řádků s příkazy if, else, for, atd. Středník není ani za složenými závorkami. Výjimkou je víceřádková deklarace 2D pole. Bloky kódu pak ohraničuje právě tento typ závorek. Syntaxe jazyka je velmi jednoduchá a zcela bez problému jí budeme velmi brzy skvěle rozumět.
Proměnné
Ze základní matematiky známe pojem proměnná. Je to symbol nebo písmeno (např. X), které reprezentuje nějakou hodnotu. Proměnná je v informatice naprosto totéž. Je to místo v paměti, kam si můžeme uložit nějaká data (číslo, text nebo nějaký složitější objekt). Toto místo má podle typu proměnné vyhrazenou určitou velikost, kterou proměnná nesmí přesáhnout. Máme hned několik typů proměnných podle toho, jaký typ dat obsahují.
Datové typy
Každá proměnná musí být konkrétního datového typu, který odpovídá druhu a velikosti ukládané informace. Používání správných a nejvíce úsporných datových typů přichází s praxí. Čím více člověk programuje, tím lépe se v těchto detailech orientuje. Konkrétní datové typy, které lze používat v jazyce Arduino, jsou:
char (8 bit) | Znak, nabývá hodnoty právě jednoho ASCII znaku (-128 až 127) |
byte (8 bit) | Je schopen uložit jedno 8 bitové číslo v rozmezí (0 až 255) |
boolean (8 bit) | Jednoduchá logika True(1)/False(0) |
int (16 bit) | Nabývá hodnot celého čísla od (-32 768 až 32 767) |
unsigned int (16 bit) | Podobně jako int, jen se záporné hodnoty "přelijí" do kladných, tedy uloží hodnoty (0 až 65 535) |
long (32 bit) | Uchovává číslo v rozsahu (-2 147 483 648 až 2 147 483 647) |
unsigned long (32 bit) | Uloží číslo v rozsahu (0 - 4 294 967 295) |
float (32 bit) | Desetinné číslo (-3.4028235E38 to 3.4028235E38) |
double (64 bit) | Desetinné číslo s dvojnásobnou přesností |
word (16 bit) | Stejné jako unsigned int (0 až 65535) |
string | Datový typ, ve kterém můžeme uchovat textový řetězec |
Pojmenování proměnných
Název proměnné je velice podstatná část ukládané informace. Hodnota, které proměnná může nabýt, je její druhou polovinou. Existují poměrně striktní pravidla pro to, aby se název proměnné dal vůbec považovat za platný. Základním pravidlem při tvorbě proměnných je, že nepoužíváme diakritiku. V identifikátoru proměnné by to způsobilo chybu po nahrání programu. Co se pak týče obsahu dané proměnné (text, pole), tam už diakritiku můžeme používat libovolně. Další důležitou věcí je, že název proměnné by nikdy neměl začínat číslem, případně jiným symbolem (například podtržítkem). Poslední, čeho bychom se měli vyvarovat, je kombinace více jazyků. Z hlediska přehlednosti programu je lepší používat pouze jeden preferovaný jazyk.
Takto vypadá rozdíl mezi špatně a správně vytvořenou proměnnou:
✗ Špatně
float průměr; string zpráva = "Výsledek";
✓ Správně
float prumer; string zprava = "Výsledek";
Pojmenovávat proměnné je důležité také z hlediska správného významu a srozumitelnosti. Chceme tím dosáhnout dobré orientace v programu, a to nejen pro nás, ale i pro každého, kdo se na kód podívá. Názvy musí být intuitivní. Musí správně zastupovat, co námi definovaná proměnná obsahuje. Základní rozdíly mezi špatně a dobře pojmenovanými proměnnými jsou zde:
✗ Špatně
int x;
string text2;
✓ Správně
string text_displej;
int motor_brana;
Je zcela zřejmé, která verze je lépe pochopitelná. A to i když se ke svému kódu vrátíme třeba po deseti letech.
Názvy víceslovných proměnných
Pokud pro přehlednost potřebujeme název proměnných vyjádřit více
slovy, máme v podstatě dvě základní možnosti. Můžeme použít styl
camelCase - každé nové slovo v proměnné začíná velkým písmenem
(motorBrana
), nebo stylu snake_case - s použitím podtržítka
mezi jednotlivými slovy v názvu proměnné (motor_brana
). Názvy
víceslovných proměnných nesmí obsahovat mezery. Níže můžeme vidět
způsob, jakým lze proměnné zapsat v tomto smyslu správně nebo
špatně:
✗ Špatně
int senzorvchod; int motor brana;
✓ Správně
int senzorVchod; int motor_brana;
Vždy používáme pouze jeden z těchto stylů a ve zdrojovém kódu je nekombinujeme.
Deklarace proměnných
Než proměnné začneme používat, musíme je deklarovat. Pokud se do nedeklarované proměnné rovnou pokusíme něco uložit, kompilátor nám vynadá. Možností deklarace je hned několik:
// První způsob - konstanty, neměnitelné proměnné #define hodnota 10 // Druhý způsob - klasické proměnné int hodnota = 10; // proměnná má nastavený typ int a hodnotu 10 int hodnota; // proměnná typu int bez přiřazené hodnoty string mujText = "nějaký text"; // proměnná typu string s textovým obsahem
#define
je jeden ze zvláštních příkazů, které se
zpracují ještě před samotnou kompilací programu. Říká se jim příkazy
preprocesoru a ještě si o nich budeme povídat. Takto definované konstanty
nemají svůj přesně daný typ a jejich hodnotu nelze změnit.
Pokud proměnnou deklarujeme, nepřiřadíme jí hodnotu a poté ji
vyvoláme, tak nenastane chyba. Program se bude tvářit, že
je v ní 0 (v případě int
, float
, a podobně). Na
druhou stranu není dobré s tím počítat, protože ve skutečnosti může
být tato hodnota náhodná. Pokud se jedná o typ string
- tam se
bude nacházet prázdný řetězec.
Proměnným pak můžeme nastavovat různé hodnoty:
vstup = Serial.read();
pocet = 10;
Když budeme chtít hodnotu pocet
zvýšit nebo snížit o
hodnotu v proměnné zmena
, máme dvě možnosti:
pocet = pocet + zmena; // analogicky potom platí: pocet = pocet - zmena;
Jednodušší je napsat totéž, ale tímto způsobem:
pocet += zmena; // analogicky potom platí: pocet -= zmena;
Používání komentářů
V programování myslíme komentářem text, který je součástí programu,
ale nepočítá se do jeho výsledného kompilovaného kódu. Nejčastěji
slouží k určitému objasnění syntaxe - programátor si dělá v programu
komentáře buď proto, aby se v něm sám lépe vyznal, nebo aby se v něm
vyznal kdokoliv jiný, kdo do programu nahlédne. Tvorba komentářů je různá
závisle na jazyce. Rodina jazyků C, z níž vychází i jazyk Arduino, nám
dává dvě možnosti, jak komentář vytvořit. Jednořádkový komentář
vytvoříme pomocí dvou lomítek //
umístěných před text
komentáře. To znamená, že od této značky až do konce řádku bude text
považován za komentář a nebude součástí kompilovaného kódu:
float obvod = 5; //první způsob komentování - používáme komentář pouze pro jeden řádek
Druhým způsobem je vložit před námi napsaný text lomítko a
hvězdičku, za text poté hvězdičku a lomítko ( /* ... */
).
Tímto způsobem můžeme okomentovat libovolný počet řádků v programu.
Když symbol hvězdičky a lomítka za text nevložíme, komentujeme celý kód. Ten proto nebude kompilován a celý kód se tak stane jedním velkým komentářem.
Podívejme se na malý příklad:
/* Fukce provádí něco strašného, ale nic nevrátí */ void slozitaFunkce() {} /* Tuto funkci nepotřebujeme int slozitaFunkce() { return 10 } */
Tím bychom tuto lekci uzavřeli, v těch následujících už si vyzkoušíme i jednoduchý kód sami naprogramovat.
Následující lekce, Podmínky v Arduinu, nám ukáže možnosti větvení programu pomocí podmínečných výrazů a reakcí na ně.