Variablen

 

Variablen können verschiedene Werte annehmen, abhängig vom Datentyp mit denen sie definiert wurden. Eine Variablendefinition sieht folgendermaßen aus:

 

Typ Variablenname;

 

Möchte man mehrere Variablen des gleichen Typs definieren, so kann man mehrere Variablennamen durch Komma getrennt angeben:

 

Typ Name1, Name2, Name3, ...;

 

Als Typ sind erlaubt: char, unsigned char, byte, int, unsigned int, word ,float

 

Beispiele:

 

int a;

 

int i,j;

 

float xyz;

 

Integer Variablen lassen sich Zahlenwerte dezimal oder als Hexzahl zuweisen. Bei einer Hexzahl werden vor die Zahl die Buchstaben "0x" gesetzt. Binärzahlen können mit dem Prefix "0b" erzeugt werden. Bei Variablen mit vorzeichenbehaftetem Datentyp lassen sich negative Dezimalzahlen zuweisen, indem ein Minuszeichen vor die Zahl geschrieben wird.

 

Für Zahlen ohne Dezimalpunkt oder Exponent wird angenommen, das sie vom Typ Integer mit Vorzeichen sind. Um eine Zahl explizit als vorzeichenlosen Integer zu definieren, so ist ein "u" direkt hinter die Zahl zu schreiben. Damit eine Zahl als 32-Bit (long) Typ gekennzeichnet ist, so ist der Wert entweder größer 65535 oder es wird ein "l" hinter die Zahl gesetzt.

 

Beispiele:

 

char c;

word a;

int i,j;

 

c=5;

c='a';       // Bei einfachen Anführungszeichen wird der ASCII Wert übernommen

a=0x3ff;     // hexadezimalzahlen sind immer unsigned

x=0b1001;    // Binärzahl

a=50000u;    // unsigned

a=100ul;     // unsigned 32 Bit (dword)

i=15;        // default ist immer signed

j=-22;       // signed

 

Fließkommazahlen (Datentyp float) dürfen ein Dezimalpunkt und einen Exponenten beinhalten:

 

float x,y;

 

x=5.70;

y=2.3e+2;

x=-5.33e-1;

 

sizeof Operator

 

Mit dem Operator sizeof() kann die Anzahl der Bytes bestimmt werden, die eine Variable im Speicher belegt.

 

Beispiel:

 

int s;

float f:

 

s=sizeof(f);  // der Wert von s ist 4

 

 Bei Arrays wird auch nur die Bytelänge des Grunddatentyps zurückgegeben. Man muss den Wert mit der Anzahl der Elemente multiplizieren, um den Speicherverbrauch des Arrays zu berechnen.

 

 

Array Variablen

 

Wenn man hinter den Namen, bei der Variablendefinition in eckigen Klammern, einen Zahlenwert schreibt, so hat man ein Array definiert. Ein Array legt den Platz für die definierte Variable mehrfach im Speicher an. Bei der Beispieldefinition:

 

int x[10];

 

Wird für die Variable x der 10-fache Speicherplatz angelegt. Den ersten Speicherplatz kann man mit X[0] ansprechen, den zweiten mit x[1], den dritten mit x[2], ... bis x[9]. Man darf bei der Definition natürlich auch andere Indexgrößen wählen. Die Limitierung ist nur der RAM Speicherplatz des C-Control Pro.

 

Man kann auch mehrdimensionale Arrays deklarieren, in dem weitere eckige Klammern bei der Variablendefinition angefügt werden:

 

int x[3][4];     // Array mit 3*4 Einträgen

int y[2][2][2]; // Array mit 2*2*2 Einträgen

 

Arrays dürfen in CompactC bis zu 16 Indizes (Dimensionen) haben. Der Maximalwert für einen Index ist 65535. Die Indizes der Arrays sind immer nullbasiert, d.h., jeder Index beginnt mit 0.

 

 Nur wenn die Compiler Option "Array Index Grenzen prüfen" gesetzt ist, findet während des Programmlaufs eine Überprüfung statt, ob die definierte Indexgrenze eines Arrays überschritten wurde. Wird ansonsten der Index während der Programmabarbeitung zu groß, so wird auf fremde Variablen zugegriffen, und die Chance ist groß, daß das Programm "abstürzt".

 

 

Tabellen mit vordefinierten Arrays

 

Seit Version 2.0 der IDE können Arrays mit Werten vorbelegt werden:

 

byte glob[10] = {1,2,3,4,5,6,7,8,9,10};

flash byte fglob[2][2]={10,11,12,13};

 

void main(void)

{

    byte loc[5]= {2,3,4,5,6};

    byte xloc[2][2];

 

    xloc= fglob;

}

 

Da bei der C-Control Pro Unit mehr Flash als RAM Speicher zur Verfügung steht, kann man mit dem flash Befehlswort Daten definieren, die nur im Flashspeicher stehen. Diese Daten können dann durch eine Zuweisung auf ein Array im RAM mit gleichen Dimensionen kopiert werden. Im Beispiel ist dies: "xloc= fglob". Diese Art der Zuweisung gibt es nicht in normalem "C".

 

 

Direkter Zugriff auf flash Array Einträge

 

Seit Version 2.12 ist es möglich auf einzelne Einträge in flash Arrays zuzugreifen:

 

flash byte glob[10] = {1,2,3,4,5,6,7,8,9,10};

 

void main(void)

{

    int a;

 

    a= glob[2];

}

 

 Eine Begrenzung bleibt bestehen: Nur normale Arrays die im RAM liegen, können als Referenz einer Funktion übergeben werden. Dies ist mit Referenzen auf flash Arrays nicht möglich.

 

 

Strings

 

Es existiert kein expliziter "String" Datentyp. Ein String basiert auf einem Array vom Datentyp char. Man muss die Größe des Arrays so wählen, daß alle Zeichen des Strings in das character Array passen. Zusätzlich wird Platz für ein Terminierungszeichen (dezimal Null) benötigt, um das Ende der Zeichenkette anzuzeigen.

 

Beispiel für eine Zeichenkette mit maximal 20 Zeichen:

 

char str1[21];

 

Als Ausnahme darf man char Arrays Zeichenketten zuweisen. Dabei wird die Zeichenkette zwischen Anführungszeichen gesetzt.

 

str1="Hallo Welt!";

 

Man darf spezielle Zeichen in Strings einbetten die mit einem "\" (Backslash) gestartet werden. Folgende Sequenzen sind definiert:

 

Sequenz

Zeichen/Wert



\\

\

\'

'

\a

7

\b

8

\t

9

\n

10

\v

11

\f

12

\r

13

 

 

 Man kann keinen String einem mehrdimensionalen Char Array zuweisen. Es gibt aber Tricks für Fortgeschrittene:

 

char str_array[3][40];

char single_str[40];

 

single_str="A String";

 

// kopiert single_str in den zweiten String von str_array

Str_StrCopy(str_array,single_str,40);

 

Dies funktioniert, da mit einem Abstand von 40 Zeichen hinter dem ersten String, in str_array der Platz für den zweiten String liegt.

 

 

Sichtbarkeit von Variablen

 

Werden Variablen außerhalb von Funktionen deklariert, so haben sie eine globale Sichtbarkeit. Das heißt, man kann sie aus jeder Funktion ansprechen. Variablendeklarationen innerhalb von Funktionen erzeugen lokale Variablen. Lokale Variablen sind nur innerhalb der Funktion erreichbar. Ein Beispiel:

 

int a,b;

 

void func1(void)

{

    int a,x,y;

    // globale b ist zugreifbar

    // globale a ist nicht zugreifbar da durch lokale a verdeckt

    // lokale x,y sind zugreifbar

    // u ist nicht zugreifbar da lokal zu Funktion main

}

 

void main(void)

{

    int u;

    // globale a,b sind zugreifbar

    // lokale u ist zugreifbar

    // x,y nicht zugreifbar da lokal zu Funktion func1

}

 

 

Globale Variablen haben einen definierten Speicherbereich, der während des gesamten Programmlaufs zur Verfügung steht.

 

Bei Programmstart werden die globalen Variablen mit null initialisiert. Lokale Variablen dagegen, sind beim Start der Funktion nicht initialisiert und können beliebige Werte haben!

 

Lokale Variablen werden, während der Berechnung einer Funktion, auf dem Stack angelegt. Das heißt, lokale Variablen existieren im Speicher nur während des Zeitraums, in der die Funktion abgearbeitet wird.

 

Wird bei lokalen Variablen der gleiche Name gewählt wie bei einer globalen Variable, so verdeckt die lokale Variable die globale Variable. Solange sich das Programm dann in der Funktion aufhält wo die namensgleiche lokale Variable definiert wurde, ist die globale Variable nicht ansprechbar.

 

 

Static Variablen

 

Man kann bei lokalen Variablen die Eigenschaft static vor den Datentyp setzen.

 

void func1(void)

{

    static int a;

}

 

Static Variablen behalten im Gegensatz zu normalen lokalen Variablen ihren Wert auch, wenn die Funktion verlassen wird. Bei einem weiteren Aufruf der Funktion hat die statische Variable den gleichen Inhalt wie beim Verlassen der Funktion. Damit der Inhalt einer static Variable bei dem ersten Zugriff definiert ist, werden statische Variablen wie globale auch bei Programmstart mit null initialisiert.