Funktionen

 

Um größere Programme zu strukturieren, teilt man sie in mehrere Unterfunktionen auf. Dies erhöht nicht nur die Lesbarkeit, sondern erlaubt es, Programmanweisungen, die mehrfach vorkommen, in Funktionen zusammenzufassen. Ein Programm besteht immer aus der Funktion "main", die als allererstes gestartet wird. Danach kann man von main aus andere Funktionen aufrufen. Ein einfaches Beispiel:

 

void func1(void)

{

    // Anweisungen in Funktion func1

    .

    .

}

 

void main(void)

{

    // die Funktion func1 wird zweimal aufgerufen

    func1();

    func1();

}

 

Parameterübergabe

 

Damit Funktionen flexibel nutzbar sind, kann man sie parametrisieren. Hierfür werden in der Klammer nach dem Funktionsnamen die Parameter für die Funktion durch Komma getrennt übergeben. Man gibt ähnlich wie in der Variablendeklaration erst den Datentyp und danach den Parameternamen an. Will man keinen Parameter übergeben, schreibt man void in die runden Klammern. Ein Beispiel:

 

void func1(word param1, float param2)

{

    Msg_WriteHex(param1);  // den ersten Parameter ausgeben

    Msg_WriteFloat(param2);  // den zweiten Parameter ausgeben

}

 

Wie lokale Variablen sind übergebene Parameter nur in der Funktion selber sichtbar.

 

Um die Funktion func1 mit den Parametern aufzurufen, schreibt man beim Aufruf die Parameter in der gleichen Reihenfolge, wie sie bei func1 definiert wurden. Bekommt die Funktion keine Parameter, läßt man die Klammer leer.

 

void main(void)

{

    word a;

    float f;

 

    func1(128,12.0);  // man kann numerische Konstanten übergeben ...

    a=100;

    f=12.0;

    func1(a+28,f); // oder aber auch Variablen und sogar numerische Ausdrücke

}

 

Man muss bei dem Aufruf einer Funktion immer alle Parameter angeben. Folgende Aufrufe wären unzulässig:

 

func1();        // func1 bekommt 2 Parameter!

func1(128);     // func1 bekommt 2 Parameter!

 

 

Rückgabeparameter

 

Es ist nicht nur möglich, Parameter zu übergeben, eine Funktion kann auch einen Rückgabewert haben. Den Datentyp dieses Wertes gibt man bei der Funktionsdefinition vor dem Namen der Funktion an. Möchte man keinen Wert zurückgeben, benutzt man void als Datentyp.

 

int func1(int a)

{

    return a-10;

}

 

Der Rückgabewert wird innerhalb der Funktion mit der Anweisung "return Ausdruck" angegeben. Hat man eine Funktion vom Typ void, so kann man die return Anweisung auch ohne Parameter anwenden, um die Funktion zu verlassen.

 

 

Referenzen

 

Da es nicht möglich ist, Arrays als Parameter zu übergeben, kann man auf Arrays über Referenzen zugreifen. Dafür schreibt man in der Parameterdeklaration einer Funktion ein eckiges Paar Klammern hinter den Parameternamen:

 

int StringLength(char str[])

{

    int i;

 

    i=0;

    while(str[i]) i++;  // wiederhole solange Zeichen nicht null

    return(i);

}

 

void main(void)

{

    int len;

    char text[15];

 

    text="hallo welt";

    len=StringLength(text);

}

 

In main wird die Referenz von Text als Parameter an die Funktion StringLength übergeben. Ändert man in einer Funktion einen normalen Parameter, so ist die Änderung außerhalb dieser Funktion nicht sichtbar. Bei Referenzen ist dies anders. Über den Parameter str kann man in StringLength den Inhalt von text ändern, da str nur eine Referenz (ein Zeiger) auf die Array Variable text ist

 

Man kann zur Zeit nur Arrays "by Reference" übergeben!

 

 

Zeigerarithmetik

 

In der aktuellen C-Control Pro Software ist auch Arithmetik auf einer Referenz (Zeiger) erlaubt, wie das folgende Beispiel zeigt. Die Arithmetik ist auf Addition, Subtraktion, Multiplikation und Division beschränkt.

 

void main(void)

{

    int len;

    char text[15];

 

    text="hallo welt";

    len=StringLength(text+2*3);

}

 

Die Zeigerarithmetik ist zur Zeit experimentell und kann eventuell noch Fehler enthalten.

 

 

Strings als Argument

 

Seit Version 2.0 der IDE kann man nun Funktionen mit einem String als Argument aufrufen. Die aufgerufene Funktion bekommt die Zeichenkette als Referenz übergeben. Da aber Referenzen im RAM stehen müssen, und vordefinierte Zeichenketten im Flashspeicher stehen, erzeugt der Compiler intern vor Aufruf der Funktion einen anonymen Speicherplatz auf dem Stack und kopiert die Daten aus dem Flash dorthin.

 

int StringLength(char str[])

{

...

}

 

void main(void)

{

    int len;

 

    len=StringLength("hallo welt");

}