Definiowanie zmiennych w programowaniu polega na określeniu rodzaju danych, jakie zmienna ma przechowywać, oraz nadaniu jej nazwy. Dzięki temu możemy zapisywać wartości w pamięci, a następnie łatwo je odczytywać i modyfikować w trakcie działania programu.
Definiowanie i inicjalizowanie zmiennych – instrukcja
Definiowanie zmiennych w Arduino obejmuje kilka kroków:
1. Wybór Typu Zmiennej: Najpierw należy wybrać odpowiedni typ zmiennej w zależności od rodzaju danych, które ma przechowywać, np. int dla liczb całkowitych, float dla liczb zmiennoprzecinkowych, boolean dla wartości logicznych, czy String dla ciągów znaków. W przypadku typów liczbowych kluczowe jest dokładne przemyślenie minimalnych i maksymalnych wartości, jakie zmienna może osiągnąć, aby upewnić się, że wybrany typ danych będzie odpowiedni do przechowywania wszystkich możliwych wartości, jakie zmienna może przyjąć w trakcie działania programu. Natomiast dla ciągów znaków, takich jak String, należy uwzględnić maksymalną długość tekstu, jaki zmienna może przechowywać, oraz pamięć, jaką to wymaga. Więcej informacji o wyborze typu zmiennej można znaleźć w rozdziale: Zmienne i wartości.
Doradca Typów Zmiennych Liczbowych
2. Definicja zmiennej: polega na zapisaniu typu zmiennej i nadaniu jej nazwy.

Przykładowo wyrażenie int liczba; (Rys.1):
- definiuje zmienną całkowitą typu int (zmienna może być używana w zakresie wartości od -32 768 do 32 767),
- nadaje jej nazwę “liczba” (nazwa może być dowolna, pod warunkiem że nie zawiera spacji ani polskich znaków),
- a cała definicja kończy się znakiem średnika (
;).
Dobrą praktyką jest nadawanie zmiennym jasnych i opisowych nazw, co zwiększa czytelność i zrozumiałość kodu. Na przykład, jeśli zmienna ma przechowywać wartość temperatury, lepiej nadać jej nazwę int temperatura; zamiast ogólnej i nieczytelnej, jak int x;. Dzięki temu od razu wiadomo, jakie dane reprezentuje zmienna.
3. Inicjalizacja Zmiennej (opcjonalnie): Można zainicjalizować zmienną, przypisując jej początkową wartość już w momencie definicji. Nie jest to jednak obowiązkowe — zmienną można definiować bez przypisywania jej wartości, a zainicjować ją później w kodzie.

Przykładowo wyrażenie int liczba = 10; (Rys.2):
- definiuje zmienną całkowitą typu int (zmienna może być używana w zakresie wartości od -32 768 do 32 767),
- nadaje jej nazwę “liczba” (nazwa może być dowolna, pod warunkiem że nie zawiera spacji ani polskich znaków),
- inicjalizuje ją wartością początkową 10,
- a cała definicja kończy się znakiem średnika (
;).
W Arduino wartość zmiennej niezainicjowanej, czyli takiej, której nie przypisano początkowej wartości, jest nieokreślona. Oznacza to, że może przechowywać dowolną wartość znajdującą się wcześniej w przydzielonej jej pamięci. Aby zapewnić bezpieczeństwo i przewidywalne działanie programu, zaleca się zawsze inicjalizować zmienne przed ich użyciem.
4. Zakres i Umiejscowienie Zmiennej:
W programowaniu Arduino, duże znaczenie ma zrozumienie zakresu i umiejscowienia zmiennych, ponieważ wpływa to na sposób ich działania, dostępność oraz zużycie pamięci.
W naszym przypadku zmienne mogą być zdefiniowane jako globalne lub lokalne, w zależności od ich przeznaczenia i zakresu użycia. Decyzja, czy zmienna będzie lokalna, czy globalna, wpływa na organizację kodu, jego czytelność oraz efektywność działania programu.
Poniżej przedstawiono kluczowe różnice między zmiennymi globalnymi a lokalnymi oraz ich zastosowania (Tab. 1).
| Cecha | Zmienne globalne | Zmienne lokalne |
|---|---|---|
| Definicja | Definiowanie poza wszystkimi funkcjami, w tym poza setup() i loop() – najczęściej na początku programu. | Definiowanie wewnątrz funkcji lub bloków kodu. |
| Dostępność | Dostępne w całym programie, we wszystkich funkcjach i blokach kodu. | Dostępne tylko w obrębie funkcji lub bloku kodu, w którym zostały zadefiniowane. |
| Żywotność | Trwają przez cały czas działania programu. | Istnieją tylko podczas wykonywania funkcji lub bloku kodu, w którym zostały zdefiniowane. |
| Zastosowanie | Używane do przechowywania danych współdzielonych między różnymi funkcjami, np. stany urządzenia, liczniki. | Używane do przechowywania danych tymczasowych, potrzebnych tylko w określonej części programu. |
| Zalety | Umożliwiają łatwy dostęp do danych w całym programie. | Pozwalają łatwiej zarządzać kodem, ograniczając ryzyko wystąpienia konfliktów nazw. Mogą optymalnie wykorzystywać pamięć SRAM. |
| Wady | Mogą prowadzić do konfliktów nazw i zmniejszają czytelność kodu. Mogą nieoptymalnie zużywać ograniczoną pamięć SRAM. | Dane są niedostępne poza funkcją lub blokiem kodu, co może wymagać przekazywania argumentów między funkcjami. |
Sama nazwa “zmienna globalna” wskazuje na to, że jest ona dostępna w całym programie, natomiast “zmienna lokalna” oznacza, że jej zakres ogranicza się do funkcji lub bloku kodu, w którym została zdefiniowana. Blok kodu to wydzielona grupa instrukcji otoczona nawiasami klamrowymi {}.
Przykłady
Przykład 1: Definicja zmiennej globalnej o nazwie liczba bez inicjalizacji (Kod_001):
Powyżej przedstawiono sposób definicji zmiennej globalnej na samym początku programu. Zmienna liczba została zdefiniowana, ale nie zainicjalizowana, co oznacza, że jej wartość początkowa jest niewiadoma i może zawierać dowolne dane pozostałe w pamięci. Jest dostępna w całym programie, ale dopiero poniżej linii jej definicji.
Przykład 2: Zmienna globalna o nazwie liczba z inicjalizacją – wartość początkowa 10 (Kod_002):
Powyżej przedstawiono przykład definicji i inicjalizacji zmiennej globalnej liczba z wartością początkową 10. Jest dostępna w całym programie, ale dopiero poniżej linii jej definicji.
Przykład 3: Zmienna globalna o nazwie liczba z inicjalizacją, dostępna tylko w pętli loop (Kod_003):
Powyżej przedstawiono przykład definicji i inicjalizacji zmiennej globalnej liczba z wartością początkową 10. Zmienna jest dostępna w całym programie, ale dopiero poniżej linii jej definicji. W tym przypadku funkcja setup() nie ma dostępu do zmiennej, ponieważ została zdefiniowana dopiero po tej funkcji. Natomiast funkcja loop() oraz wszystkie funkcje znajdujące się poniżej definicji zmiennej mogą z niej korzystać.
Przykład 4: Zmienna lokalna o nazwie liczba dostępna tylko w setup (Kod_004):
Powyżej przedstawiono przykład definicji i inicjalizacji zmiennej lokalnej liczba w funkcji setup() z wartością początkową 10. Zmienna ta jest dostępna wyłącznie w obrębie funkcji setup() i nie może być używana ani w funkcji loop(), ani w żadnej innej części programu. Po zakończeniu działania funkcji setup() zmienna liczba przestaje istnieć, a jej wartość (10) zostaje utracona.
Przykład 5: Zmienna lokalna dostępna tylko w loop (Kod_005):
Powyżej przedstawiono przykład definicji i inicjalizacji zmiennej lokalnej liczba w funkcji loop() z wartością początkową 10. Zmienna ta jest dostępna wyłącznie w obrębie jednej iteracji funkcji loop() i nie może być używana poza nią. Przy każdej kolejnej iteracji pętli loop() zmienna liczba jest tworzona od nowa, a jej wartość początkowa zawsze wynosi 10. Po zakończeniu danej iteracji zmienna przestaje istnieć, a jej pamięć zostaje zwolniona.
Przykład 6: Zmienna lokalna dostępna tylko w bloku kodu (Kod_006):
Powyżej przedstawiono przykład definicji i inicjalizacji zmiennej lokalnej liczba wewnątrz bloku kodu znajdującego się w funkcji loop(). Zmienna liczba jest dostępna wyłącznie w obrębie tego bloku (czyli między klamrami { }) i nie może być używana poza nim. Przy każdej iteracji funkcji loop() zmienna liczba jest tworzona od nowa, a jej wartość początkowa wynosi 10. Po zakończeniu wykonania bloku zmienna przestaje istnieć, a jej pamięć zostaje zwolniona.
Przykład 7: Definicja zmiennej globalnej o nazwie liczba z późniejszą inicjalizacją wartości (Kod_008):
Powyżej przedstawiono definicję zmiennej globalnej o nazwie liczba. Przy definiowaniu zmiennej nie jest wymagana jej inicjalizacja – wartość można przypisać później, np. w funkcji setup(). W naszym przykładzie w funkcji setup() zmiennej liczba przypisano wartość 10.
Przykład 8: Błędna kolejność definicji inicjalizacji zmiennej globalnej o nazwie liczba (Kod_008):
W tym przykładzie kompilator zgłosi błąd, ponieważ zmienna liczba została użyta w funkcji setup() (w naszym przypadku w celu przypisania wartości 10) przed jej definicją. W Arduino (C++) wszystkie zmienne muszą być zdefiniowane przed ich użyciem w kodzie, w tym również przed inicjalizacją wartości.
Przykład 9: Błędne użycie zmiennej lokalnej o nazwie liczba poza jej zakresem (Kod_009):
W powyższym przykładzie zmienna liczba została zdefiniowana jako zmienna lokalna wewnątrz bloku kodu w funkcji loop(). Zmienna ta jest dostępna wyłącznie w obrębie tego bloku (czyli między { }), a po jego zakończeniu przestaje istnieć. Próba przypisania wartości 10 do zmiennej liczba poza tym blokiem powoduje błąd, ponieważ zmienna nie jest widoczna w tym zakresie kodu. Aby naprawić błąd, zmienna liczba powinna zostać zdefiniowana w szerszym zakresie, np. jako zmienna lokalna dla całej funkcji loop() lub jako zmienna globalna.
Przykład 10: Błędna definicja zmiennej lokalnej o tej samej nazwie co zmienna globalna (Kod_010):
Powyżej przedstawiono przykład, w którym zmienna globalna liczba została zdefiniowana na początku programu, ale w funkcji setup() zdefiniowano zmienną lokalną o tej samej nazwie.
Zmienna lokalna “przykrywa” zmienną globalną w swoim zakresie, co oznacza, że wszystkie operacje na zmiennej liczba w obrębie funkcji setup() odnoszą się wyłącznie do zmiennej lokalnej.
Zmienna globalna pozostaje niezmieniona i zachowuje swoją pierwotną wartość (w tym przypadku jest niezainicjalizowana, więc jej wartość jest niewiadoma). W funkcji loop() odwołania do liczba dotyczą zmiennej globalnej, która nie przyjmuje już wartości 10. Kompilator nie zgłasza błędu, ale takie użycie może prowadzić do trudnych do wykrycia błędów logicznych w programie.
Uwaga praktyczna: Dla bardziej rozbudowanych projektów, możesz stosować konwencje nazewnictwa, takie jak dodawanie sufiksu (np. _g dla zmiennych globalnych, _l dla zmiennych lokalnych), aby łatwiej odróżnić zmienne globalne od lokalnych. Czyli napisać: liczba_l lub liczba_g. Dzięki temu kod staje się bardziej czytelny i zrozumiały, a ryzyko niejednoznaczności zostaje zminimalizowane.
Wyświetlanie wartości zmiennej na porcie szeregowym
Aby wyświetlić wartość zmiennej liczba w porcie szeregowym w Arduino, musimy zainicjalizować komunikację szeregową w funkcji setup() za pomocą polecenia Serial.begin() np. z prędkością 9600 bps. Następnie możemy użyć instrukcji Serial.println(liczba) do wysyłania wartości zmiennej. Wartość zmiennej podajemy w nawiasie instrukcji Serial.println() bez użycia cudzysłowów.
Użyjemy kodu z przykładu 2 (kod_002), do którego w symulacji (Symulacja_1) dopiszemy dodatkowo dwie linie.
W tym przypadku wartość zmiennej liczba wynosząca 10 pokaże się w monitorze portu szeregowego symulatora. Wartość wyświetlona zostanie jednokrotnie, ponieważ instrukcja Serial.println() znajduje się w funkcji setup(), która uruchamia się tylko raz podczas startu programu.
Asystent Arduinowo_AI
Asystent Arduinowo_AI zgłębił powyższy zakres wiedzy i z przyjemnością wszystko Ci wyjaśni.
Zdobądź więcej wiedzy!
Przejdź do kolejnych materiałów naszego kursu: Znaki i teksty.