Mail to Code: Tutorial

Lernt, wie man den Code für Rechenknechte schreibt.

English version English Version

Variablen


Typen von "Speicherzellen"

Im vorangegangenen Kapitel haben wir gelert, wie Zahlen oder Buchstaben in einem dualen Code gespeichert werden können. Da beide Formen der Informationsspeicherung 8 Bits, also ein Byte nutzen, muss in einem Programm festgelegt werden, wie dieses Byte denn nun zu interpretieren ist.
Außerdem werden 8 Bit Speicher nur für wenige Anwendungsfälle ausreichen. Wir müssen also mehr Bits (Bytes) für Zahlen- oder Buchstabenspeicher nutzbar machen.

16 / 32 / 64 Bit

In einem Byte können ja nur 28=256 Zahlen oder Buchstaben gespeichert werden. Wie schaffen Computer es also, mit Zahlen größer als 255 zu rechnen? Nun, dazu wird einfach mehr als nur ein Byte verwendet. In 16 Bits können schon 216=65.536 Zahlen, in 32 Bits 232=4.294.967.296 und in 64 Bits mehr 18 als Trillionen (eine Zahl mit 18 Nullen) Zahlen dargestellt werden. Das sollte für die meisten Anwendungen mehr als nur ausreichen

Ganzzahlige Variablen ohne Vorzeichen

Wie der Name zum Ausdruck bringt, können derartige Variablen nur ganzzahlige Werte speichern. In einem Programm wird durch die Anweisung:

unsigned int myVariable = 0;

festgelegt, dass die Bits in der Speicherzelle mit Namen "myVariable" als ganzzahlige, positive Zahlen zu lesen sind. Ferner wird dieser Variablen als Startwert "0" zugewiesen.
Wieviele Zahlen umfasst diese Speicherzelle aber denn nun?
Auch das muss natürlich festgelegt sein, dann abhängig von der Größe muss ja entsprechend Platz in dem Computerspeicher für diese Variable reserviert werden. Wird diese Größe nicht explizit angegeben, so reserviert der Compiller eine Standardgröße. Diese Standardgröße hängt davon ab, für welches Zielsystem, also für welchen Mikrocontroller der Code compilliert werden soll. Für 8-Bit ATmega Chips, die in diesem Tutorial bevorzugt verwendet werden sind das 16 Bit (=2 Byte). Somit können Zahlen von 0 bis 65.535 in myVariable gespeichert werden.
Benötigt man aber nur Zahlwerte von 0 bis 255 und möchte Arbeitsspeicher sparen, so kann man das durch die Anweisung:

uint8_t myVariable = 0;

Dadurch werden für myVariable lediglich 8 Bits (1 Byte) an Arbeitsspeicher verwendet und Sparsamkeit am richtigen Ende wollen wir uns in diesem Tutorial ja angewöhnen.
Muss es aus einem bestimmten Grund aber doch mehr sein, so kann man durch die Anweisung:

uint32_t myVariable = 0;

Platz für mehr als 4 Milliarden Zahlen reservieren. Ihr erkennt das System dahinter und könnt euch nun denken, wie man 64 Bit für eine vorzeichenlose, ganzzahlige Variable reserviert.

unsigned long myVariable = 0;

Genau wie bei der Angabe "unsigned int" ist auch die Größe und der Wertebereich von "unsigned long" nicht fest definiert und hängt davon ab, für welches Zielsystem der Code compilliert wird. Die Arduino IDE verwendet 32 Bits (4 Bytes), wenn 8-Bit Mikrocontroller als Zielsystem gewählt wurden. Die alternative Bezeichnung "uint32_t" macht für alle Systeme klar, dass 32 Bit, ganzzahlige Werte gemeint sind.

Ganzzahlige Variablen mit Vorzeichen

Rechnen kann man ja nun mit positiven und negativen Zahlen. Wird für eine Variable nicht explizit angegeben, dass darin nur positive Werte gespeichert werden sollen, so wird standardmäßig davon ausgegangen, dass sowohl positive als auch negative Werte gespeichert werden sollen. Mit der Anweisung:

int myVariable = 0;

wird von dem Compiller der Arduino IDE für 8-Bit Mikrocontroller Platz für 16 Bits (2 Bytes) reserviert. Der Wertebereich der in myVariable speicherbaren Zahlwerte liegt nun zwischen -32768 und 32767.
Auch hier kann man Speicherplatz sparen, indem man explizit angibt, nur 8 Bits (1 Byte) zu reservieren:

int8_t myVariable = 0;

Der Wertebereich liegt nun zwischen -128 und 127. Natürlich geht auch mehr mit:

int32_t myVariable = 0;

und Werten zwischen -2147483648 und 2147483647. Ihr erkennt das System?
Eine 32 Bit Banzzahl kann in der Arduino IDE für 8-Bit Mikrocontroller auch durch die Anweisung

long myVariable = 0;

definiert werden. Genau wie bei "int" gilt auch hier, dass die exakte Größe des Speicherplatzes abhängig vom Zielsystem ist. Wird das gleiche Programm in der Arduino IDE z.B. tür einen 32 Bit Microcontroller compilliert, so kann es sich dann auch um einen 64 Bit großen Zahlenspeicher handeln. Durch Verwendung von "int32_t" wird zweifelsfrei für alle Mikrocontroller eine 32 Bit (4 Byte) Variable definiert.

Buchstaben

Dass in einer Variablen Buchstaben und sonstige Zeichen gespeichert werden sollen, wird festgelegt durch die Anweisung:

char myVariable = 'a';

In dem vorangegangenen Kapitel haben wir gelernt, dass im ASII-Code lediglich 127 unterschiedliche Zeichen festgelegt sind, die locker in 8 Bits (1 Byte) passen. Es macht daher keinen Sinn, einer Variablen vom Typ char (Englich character) mehr als 8 Bit Speicherplatz zuzuweisen.
Als Anfangswert wird durch obige Anweisung der Variablen der Buchstabe 'a' zugewiesen.

Zahlen mit Nachkommastellen

Divisionen können als Ergebnis nicht ganzzahlige Werte ergeben. Wird dieses Ergebnis einer als ganzzahlig definierten Variablen zugewiesen, so werden die Nachkommastellen schlicht verworfen. Oftmals ist das nicht weiter Tragisch, es kann aber zu völlig unerwünschten Resultaten im Programm führen. In dem folgenden Programmabschnitt wird die Variable "letsCalc" mit dem Wert "4" initialisiert, dann durch 8 geteilt, und als Letztes wieder mit 8 multipliziert:
1
2
3
int8_t letsCalc = 4;
letsCalc = letsCalc / 8;
letsCalc = letsCalc * 8;
    
Nach Zeile 2 sollte die Variable letsCalc den Wert 0.5 haben, da es sich laut Definition aber um eine ganzzahlige Zahl handeln muss, wird die Nachkommastelle schlicht verworfen und letsCalc ist somit "0".
In der dritten Zeile wird letsCalc mit 8 multipliziert, was erneut als Ergebnis "0" ergibt. Erwarten würden wir aber, dass
4 / 8 * 8 = 4
ergibt. Beim Programmieren ist also die korrekte Wahl des Variablentyps unbedingt zu beachten!

In späteren Kapiteln beschäftigen wir uns etwas intensiver mit Kalkulationen.

Einige gebräuchliche Variablentypen

Typbezeichnung Bits Bytes Wertebereich Bemerkung
uint8_t 8 1 0
bis
255
Ganzzahlige Werte ohne Vorzeichen
byte 8 1 0
bis
255
Gleichbedeutend mit uint8_t
uint16_t 16 2 0
bis
65 535
Ganzzahlige Werte ohne Vorzeichen
uint32_t 32 4 0
bis
4 294 967 295
Ganzzahlige Werte ohne Vorzeichen
uint64_t 64 8 0
bis
18 446 744 073 709 551 615
Ganzzahlige Werte ohne Vorzeichen
unsigned int ??? ??? 0
bis
???
Ganzzahlige Werte ohne Vorzeichen
Wertebereich und Speicherplatz hängen davon ab, für welches Zielsystem compilliert wird.
Die Arduino IDE verwendet uint16_t für 8-Bit Zielsysteme.
unsigned long ??? ??? 0
bis
???
Ganzzahlige Werte ohne Vorzeichen
Wertebereich und Speicherplatz hängen davon ab, für welches Zielsystem compilliert wird.
Die Arduino IDE verwendet uint32_t für 8-Bit Zielsysteme.
 
int8_t 8 1 -128
bis
127
Ganzzahlige Werte mit Vorzeichen
gleichbedeutend mit:
signed int8_t
uint16_t 16 2 -32768
bis
-32767
Ganzzahlige Werte mit Vorzeichen
gleichbedeutend mit:
signed int16_t
uint32_t 32 4 -2147483648
bis
2147483647
Ganzzahlige Werte mit Vorzeichen
gleichbedeutend mit:
signed int32_t
int64_t 64 8 -9 223 372 036 854 775 808
bis
9 223 372 036 854 775 807
Ganzzahlige Werte mit Vorzeichen
gleichbedeutend mit:
signed int64_t
unsigned int ??? ??? 0
bis
???
Ganzzahlige Werte mit Vorzeichen
Wertebereich und Speicherplatz hängen davon ab, für welches Zielsystem compilliert wird.
Die Arduino IDE verwendet int16_t für 8-Bit Zielsysteme.
Gleichbedeutend mit:
signed int
unsigned long ??? ??? 0
bis
???
Ganzzahlige Werte mit Vorzeichen
Wertebereich und Speicherplatz hängen davon ab, für welches Zielsystem compilliert wird.
Die Arduino IDE verwendet int32_t für 8-Bit Zielsysteme. Gleichbedeutend mit:
signed long
 
float 32 4 -3.4028235 * 1038
bis
-3.4028235 * 1038
Kommazahlen
In der Arduino IDE gleichbedeutend mit:
double
double 32 4 -3.4028235 * 1038
bis
-3.4028235 * 1038
Kommazahlen
In der Arduino IDE gleichbedeutend mit:
float
 
char 8 1 0
bis
255
Speicher für einen Buchstaben oder sonstiges ASCII-Zeichen
Ein char kann im Programm aber auch als ganzzahliger Wert (uint8_t) für Rechenoperationen behandelt werden. Dennoch sollten in einem char nur ASCII-Zeichen gespeichert werden.







Du findest diese Seite klasse?

Gummibärchen als Nervennahrung beim Programmieren und der Betrieb dieses Servers verschlingen mein Geld.
Helft mit einer Motivationsspritze, dieses Projekt am Laufen zu halten.

Klick hier oder scan den QR Code, um eine Spende zu überweisen.



Vielen Dank!

Fragen? Anregungen? Fehler gefunden?
Kontakt per E-mail: question@h1i1.de