Globálne premenné

variable scope

Premenné aj funkcie majú svoj rozsah platnosti, čiže oblasť, v ktorej fungujú a v ktorej nie. V prípade premennej, ktorá je deklarovaná (definovaná) pod premennou, ktorá ju volá pre ňu neexistuje. Viditeľnosť premennej môžeme označiť ako:

Globálna premenná - platí v celom programe. Umiestňuje sa mimo (nad) definíciu funkcie setup(). Môžu ich používať všetky funkcie definované pod nimi. K použitiu globálnych premenných sa vyhnite, pretože vedie k zlým návykom.

Lokálna premenná - je definovaná vo vnútri funkcie. Môže ich teda používať iba táto funkcia. Povedané inak, lokálna premenná platí iba medzi dvoma {}. Viaceré funkcie môžu mať lokálne premenné s tým istým menom, každá používa tú svoju. Ak má lokálna a globálna premenná to isté meno, lokálna premenná prekryje globálnu, funkcia teda používa svoju lokálnu premennú (bližšia košeľa ako kabát). Ak by som sa ale predsa len potreboval dostať ku globálnej premennej, tak je na to operátor rozšírenia platnosti ::.

int x;  // premennú "x" vidí akákoľvek funkcia v programe (globálna premenná)

void setup()
{
  // ...
}

void loop()
{
  int i;    // premenná "i" je viditeľná vo vnútri funkcie "loop" (lokálna premenná)
  float f;  // premenná "f" je viditeľná vo vnútri funkcie "loop" (lokálna premenná)
  // ...

  for (int j = 0; j <100; j++){
    // premenná "j" je viditeľná len tu v slučke for (lokálna premenná)
    // taktiež sú tu viditeľné aj premenné "x", "i" aj "f"
  }

 // premenná "j" už tu neexistuje
}

void mojaFunkcia() {
  int z;    // premenná "z" je viditeľná len vo vnútri funkcie "mojaFunkcia"
            // taktiež je tu viditeľná premenná "x"
  
// ... 
}

static

Ak pri lokálnej premennej použijeme špecifikátor static, premenná nezanikne ak vyskočíme z funkcie (z bloku {}), ale nestáva sa z nej globálna premenná, takže je platná len pre danú funkciu. Keby sme static neuviedli, tak by premenná zanikla pri najbližšom konci funkcie a znovu by sa inicializovala pri zavolaní funkcie.

void mojaFunkcia()  {
    static int x = 0;   // premenná "x" sa inicializuje len raz pri prvom spustení tejto funkcie
    x++;
}

// premenná "x" nezanikla a jej hodnota je zachovaná aj mimo funkcie 
// ale premenná "x" nieje viditeľná mimo tejto funkcie, nedá sa jej hodnota meniť

volatile

Deklarácia premennej typu volatile je direktíva pre kompilátor. Určuje, že si neželáme aby bola premenná v rámci optimalizácie nejak presúvaná v pamäti. Toto je dôležité ak existuje spôsob ako meniť túto premennú aj inak ako v programe, napríklad zvonka nejakým vstupom (prerušením - interrupts) z vonkajšieho hardware. Ak by program uloženie premennej nejak optimalizoval a nebola by počas celého programu tam kde mala, tak by vonkajší proces zapisoval hodnoty niekde úplne inde. Teda, čo je volatile s tým program nehýbe.

// prepína LED pri prerušení, pin zmení stav

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}

const

Vraví o tom, že premenná bude konštantná a teda sa nebude dať meniť počas behu programu. Táto premenná je "len pre čítanie". To znamená, že premenná môže byť použitá rovnako ako akákoľvek iná premenná svojho typu, ale jej hodnota nemôže byť zmenená. Dostanete chybu kompilátora, ak sa pokúsite priradiť akúkoľvek hodnotu premennej typu const. Je dôležité, že hneď pri deklarácii musí byť aj definovaná. Doporučované je deklarovať konštanty použitím const ako používať #define.

const float pi = 3.14;
float x;

// ....

x = pi * 2;    // použitie konštanty "pi" vo výpočte

pi = 7;        // chybný zápis - konštantu nieje možné modifikovať

const volatile je to aj konštanta a aj sa s ňou nehýbe v pamäti (a tak vonkajší proces môže vždy načítať hodnotu premennej a nemusí sa báť, že by ju nenašiel na tom mieste kde má byť. Zapisovať do nej (do konštanty) ale nemôže).


Diskusia a komentáre

Diskusia a komentáre