Definiowanie i inicjalizowanie zmiennych



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.

Rysunek przedstawia deklarację zmiennej  w postaci int liczba;. Elementy składające się na tę deklarację zostały opisane za pomocą czerwonych strzałek i żółtych etykiet. Typ zmiennej int oznacza, że zmienna będzie przechowywać liczby całkowite. Słowo liczba to nazwa zmiennej, która będzie używana w kodzie. Instrukcja kończy się średnikiem ;, który sygnalizuje zakończenie deklaracji. Czerwone strzałki i żółte opisy zostały dodane ręcznie w celu wyjaśnienia struktury deklaracji zmiennej.
Rys.1. Przykład definicji zmiennej w Arduino IDE.

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.

Rysunek przedstawia przypisanie wartości do zmiennej w postaci int liczba = 10;. Typ zmiennej int oznacza, że zmienna przechowuje liczbę całkowitą. Nazwa zmiennej liczba to identyfikator, który będzie używany w programie. Liczba 10 jest wartością przypisaną zmiennej podczas deklaracji. Średnik ; kończy instrukcję. Czerwone strzałki i żółte opisy zostały dodane ręcznie, aby podkreślić i wyjaśnić poszczególne elementy składni.
Rys.2. Przykład definicji zmiennej wraz z inicjalizacją w Arduino IDE.

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).

Tab. 1. Porównanie zmiennych globalnych i lokalnych w Arduino.
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):

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):

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):

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):

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):

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):

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):

Kod_007

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):

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):

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):

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.

Symulacja_1

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.