Czy są źli? Może. Problem z globalnymi polega na tym, że mogą być one dostępne i modyfikowane w dowolnym momencie przez dowolną wykonywaną funkcję lub fragment kodu, bez ograniczeń. Może to prowadzić do sytuacji, które, powiedzmy, są trudne do prześledzenia i wyjaśnienia. Pożądane jest zatem zminimalizowanie ilości globali, jeśli to możliwe, przywrócenie tej wartości do zera.
Czy można tego uniknąć? Prawie zawsze tak. Problem z Arduino polega na tym, że zmuszają cię do tego dwufunkcyjnego podejścia, w którym zakładają ciebie setup()
i ciebie loop()
. W tym konkretnym przypadku nie masz dostępu do zakresu funkcji wywołującej tych dwóch funkcji (prawdopodobnie main()
). Gdybyś to zrobił, byłbyś w stanie pozbyć się wszystkich globali i zamiast tego użyć miejscowych.
Wyobraź sobie następujące:
int main() {
setup();
while (true) {
loop();
}
return 0;
}
To prawdopodobnie mniej więcej tak wygląda główna funkcja programu Arduino. Zmienne, których potrzebujesz zarówno w funkcji, jak setup()
i w loop()
funkcji, byłyby wówczas najlepiej zadeklarowane w zakresie main()
funkcji niż w zakresie globalnym. Można je następnie udostępnić dwóm pozostałym funkcjom, przekazując je jako argumenty (w razie potrzeby używając wskaźników).
Na przykład:
int main() {
int myVariable = 0;
setup(&myVariable);
while (true) {
loop(&myVariable);
}
return 0;
}
Pamiętaj, że w tym przypadku musisz również zmienić podpis obu funkcji.
Ponieważ może to nie być wykonalne ani pożądane, widzę naprawdę tylko jeden sposób na usunięcie większości globali z programu Arduino bez modyfikowania struktury programu wymuszonego.
Jeśli dobrze pamiętam, możesz doskonale używać C ++ podczas programowania dla Arduino, a nie C. Jeśli nie znasz (jeszcze) OOP (Object Oriented Programming) lub C ++, może to trochę przyzwyczaić się i trochę czytanie.
Moją propozycją byłoby utworzenie klasy Program i utworzenie pojedynczej globalnej instancji tej klasy. Klasę należy uznać za plan dla obiektów.
Rozważ następujący przykładowy program:
class Program {
public:
Program();
void setup();
void loop();
private:
int myFirstSampleVariable;
int mySecondSampleVariable;
};
Program::Program() :
myFirstSampleVariable(0),
mySecondSampleVariable(0)
{
}
void Program::setup() {
// your setup code goes here
}
void Program::loop() {
// your loop code goes here
}
Program program; // your single global
void setup() {
program.setup();
}
void loop() {
program.loop();
}
Voilà, pozbyliśmy się prawie wszystkich globali. Funkcje, w których chcesz zacząć dodawać logikę aplikacji, to funkcje Program::setup()
i Program::loop()
. Funkcje te mają dostęp do zmiennych składowych specyficznych dla instancji, myFirstSampleVariable
a mySecondSampleVariable
tradycyjne setup()
i loop()
funkcje nie mają dostępu, ponieważ zmienne te zostały oznaczone jako prywatne. Ta koncepcja nazywa się enkapsulacją lub ukrywaniem danych.
Nauczenie cię OOP i / lub C ++ jest trochę poza zakresem odpowiedzi na to pytanie, więc zatrzymam się tutaj.
Podsumowując: globałów należy unikać i prawie zawsze można drastycznie zmniejszyć ich liczbę. Również podczas programowania dla Arduino.
Co najważniejsze, mam nadzieję, że moja odpowiedź będzie dla ciebie przydatna :)