Zum Hauptinhalt springen

Programmiertechniken - Variablen

In der Informatik sind Variablen eine Art Platzhalter oder Container für Daten und Informationen. Der Inhalt einer Variable kann sich jederzeit ändern. Um eine Variable nutzen zu können, muss im Programmcode für jede Variable der Variablenname und der Datentyp (ob es sich um einen Text, Zahl, Buchstabe, etc. handelt) festgelegt werden. Diese Festlegung der Eigenschaften einer Variablen wird Deklaration bzw. Variablendeklaration genannt (von declarare lat. bekannt machen, bezeichnen).

Variablenname

Der Variablenname soll immer beschreiben, welche Funktion oder welchen Inhalt eine Variable hat. Es ist sinnvoll, für Variablen Begriffe wie wertSensorLinks oder pinRoteLED zu verwenden.

Variablennamen sollten immer mit einem Kleinbuchstaben beginnen. Die Nutzung eines Unterstrichs zum Trennen einzelner Wörter sollte vermieden werden. Stattdessen kann zur verbesserten Lesbarkeit bei zusammengesetzten Wörtern die Großschreibung verwendet werden. Statt zustand_motor_links sollte die Variable besser zustandMotorLinks genannt werden.

Datentypen

Variablen können für viele verschiedene Datentypen festgelegt werden. Der Datentyp gibt an, ob die Variable z.B. Zahlen oder Buchstaben beinhalten kann.

Die wichtigsten Datentypen beim Arduino:

  • bool: Speichert nur die logischen Zustände bzw. Werte true (1) oder false (0), also wahr oder falsch ab.
  • char: Zum Speichern einzelner Buchstaben wird der Datentyp char verwendet.
  • int und long: Gelten für ganzahlige Werte, wobei int einen deutlich kleineren Wertebereich hat (-32.768 bis 32.767)
  • unsigned int und unsigned long: Ähnlich wie int und long, allerdings können nur positive ganzzahlige Werte gesspeichert werden. Dadurch verdoppelt sich der Wertebereich der positiven Zahlen.
  • float und double: Werden für Fließkommazahlen (als Dezimalbrüche mit festgelegter Genauigkeit) verwendet. double weißt bei einigen Arduinoboards (nicht beim Arduino UNO) ein höhere Genauigkeit auf, benötigt allerdings auch doppelt soviel Speicher wie float.

Zusammenfassung einiger Datentypen

Die Größe der aufgelisteten Datentypen gilt nur bei einigen Arduino-Boards (Arduino-Uno, Arduino-Nano, ...)

Datentypkleinster Wertgrößter WertGröße in BitAnmerkungen
boolfalse (0)true (1)8logische Zustände
int- 32 76832 76716Ganze Zahlen
unsigned int06553516nur positive Ganze Zahlen
long- 2 147 483 6482 147 483 64732Ganze Zahlen
unsigned long04 294 967 29532nur positive Ganze Zahlen
float3,4E-383,4E+3832Fließkommazahlen
double3,4E-383,4E+3832bei ATMEGA Boards die selbe Genauigkeit wie float

Oft werden auch alternative Datentypen benutzt, die die Kompatibilität mit verschiedenen Mikrocontrollern verbessern sollen:

  • uint8_t , uint16_t, uint32_t, uint64_t: Speichern positive ganzzahlige Werte mit der angegeben Bitbreite (8, 16, 32, 64 bit)
  • int8_t , int16_t, int32_t, int64_t: Speichert positive und negative ganzzahlige Werte mit der angegeben Bitbreite (8, 16, 32, 64 bit)

Beispiele Deklaration

int pinRoteLed;   // nur ganzzahlige Werte
float fehlerwert; // Fließkommazahl (Dezimalbruch)

Zuweisung und Initialisierung

Nachdem eine Variable deklariert wurde, ist es möglich, ihr auch einen Wert zuzuweisen. Zuweisungen werden mit dem = Operator durchgeführt. Auch wenn es nicht immer ganz offensichtlich ist, sollte der = Operator nicht mit dem Gleichheitszeichen (=) in der Mathematik verwechselt werden. Das Gleichheitszeichen drückt aus, dass etwas gleich ist. Der Zuweisungs-Operator weist der Variable einen Wert zu. Dieser Unterschied wird später wichtig, wenn Vergleichsoperatoren wie zum Beispiel == verwendet werden.

Zuweisungen können getrennt von der Variablendeklaration durchgeführt werden. Wird einer Variable das erste Mal ein Wert zugewiesen, spricht man auch von der Initialisierung der Variable. Bevor eine Variable initialisiert wurde, ist der Wert der Variable unbekannt.

int auszeitRoteLed;    // Variablendeklaration (Wert der Variable ist unbekannt)
auszeitRoteLed = 1000; // Zuweisung und Initialisierung

auszeitRoteLed = 300; // eine erneute Zuweisung überschreibt alten Wert

Da jede Variable deklariert und auch initialisiert werden muss, kann das auch in einer Programmzeile gemacht werden.

float fehlerWert  = 3.1415; // Deklaration und erste Zuweisung
// also Initialisierung in einer Zeile
int pinLED = 12; // Initialisierung eines Integer-Wertes
char einBuchstabe = `b`; // Initialisierung eines char-Datentypes

Einfache Rechenoperationen

Mit Variablen können nicht nur Werte gespeichert werden, sondern mit ihnen können auch verschiedene Rechenoperationen (z.B. Addition +, Subtraktion -, Multiplikation *, Division /) durchgeführt werden.

int a = 6;
int b = 3;
int c;

c = a - b; // c: 3
c = a + b; // c: 9
c = a * b; // c: 18
c = a / b; // c: 2

Nicht immer soll das Ergebnis einer Rechenoperation in einer neuen Variable gespeichert werden. In diesem Fall kann das Ergebnis auch direkt den alten Wert der Variable überschreiben.

int i = 1;
i = i + 1; // i: 2

int a = 6;
i = i + 6; // i: 2 + 6 = 8

Gültigkeitsbreich (Scope)

Kann auf eine Variable im gesamten Programm zugegriffen werden, handelt es sich um eine globale Variable. Existiert eine Variabel nur in Teilen des Programms, handelt es sich um lokale Variablen.

Ob ein Variable global oder lokal ist, hängt davon ab, wo sie deklariert wurde.

Lokale Variablen

Variablen, die in einem Programmabschnitt deklariert wurden, der durch zwei geschweifte Klammern { ... } begrenzt ist, sind lokale Variablen. Bisher kennen Sie nur die void loop() bzw. void setup() Funktionen, welche einen durch geschweifte Klammern begrenzten Bereich aufweisen. Deklarieren Sie also eine Variable innerhalb dieser Funktionen, existieren Sie auch nur innerhalb dieser Funktionen. Wird die Funktion beendet, verschwindet auch die Variable.

Lokale Variablen sollten immer mit einem kleinen l beginen: lMessWert, lZaehler.

Globale Variablen

Wird eine Variable außerhalb von geschweiften Klammern { ... } deklariert, so ist die Variable global. Sie wird solange existieren, wie das Programm läuft und es kann aus dem gesamten Programmcode darauf zugegriffen werden.

Beispiel

https://wokwi.com/projects/387887766346532865

int pinLed = 12; // globale Variable
int zaehlerGlobal = 0;

void setup(){ // Geschweifte Klammern { } geben immer einen
// Gültigkeitsbereich (Scope) an.
int lZaehlerSetup = 0; // lokale Variable
pinMode(pinLed,OUTPUT); // kann die globale Variable pinLed nutzen
Serial.begin(9600);
}

void loop(){
int lZaehlerLoop = 0;

zaehlerGlobal = zaehlerGlobal + 1;
//lZaehlerSetup = lZaehlerSetup + 1; // lZaehlerSetup existiert hier NICHT!!
lZaehlerLoop = lZaehlerLoop + 1;

Serial.print("zaehlerGlobal: ");
Serial.print(zaehlerGlobal); // zaehlerGlobal: 1, 2, 3, ...
Serial.print(", lZaehlerLoop: ");
Serial.println(lZaehlerLoop); // lZaehlerLoop: 1, 1, 1, ...
// (Wurde immer wieder neu initialisiert.)
}
Aufgaben - Programmieren
  1. Erläutern Sie den Unterschied zwischen einer Deklaration, einer Zuweisung und einer Initialisierung einer Variablen. Geben Sie jeweils ein Beispiel an.
  2. Mit welchen Datentypen lässt sich die Zahlen 1, 2.0, 14.35 , -2365, 67542 , und -34543 speichern. Testen Sie Ihre Vermutungen mit einem Program und dem seriellen Monitor
    int zahl1 = 2365;
    Serial.print("int(2365): ");
    Serial.println(zahl1);
  3. Lassen Sie mit dem seriellen Monitor und Serial.println() fortlaufend alle durch 8 teilbaren Zahlen ausgeben.