Unterrichts- und Lernmaterial für Mikrocontroller
Unterrichts- und Lernmaterial fürMikrocontroller

1 - Funktionen erstellen

Eine Funktion ist nichts anderes als wieder verwendbarer Programmcode, der eine spezielle Aufgabe auszuführen hat. In diesem Abschnitt wird gezeigt, wie man Funktionen aufruft, ihnen Informationen übergibt (Parameterübergabe) und wie man Informationen von den Funktionen zurück bekommt (Rückgabewert).

Fangen wir mit einem einfachen Programm an, um die grundsätzlichen Dinge daran exemplarisch zu zeigen.

 

Programm mit einer Funktion
Aufgaben
  • Übertrage das Programm funktion1.c in den Editor und speichere es ab.
  • Starte das Programm mit Run with Terminal und überzeuge dich davon, dass die beiden Textzeilen "Dieser Text wurde über das Hauptprogramm ausgegeben." und  "Dieser wurde über die Funktion ausgegeben!" im Terminal erscheinen.

Programm funktion1.c

Abbildung 1 - (Courtesy of Parallax Inc.)

Terminalausgabe

Abbildung 2 - Terminalausgabe zum Programm funktion1.c

Wie arbeitet das Programm funktion1.c?

  • Zeile 3 mit einer forward declaration

Diese Programmzeile oberhalb des Hauptprogramms ist eine sogenannte Forward-Deklaration. Der Compiler PropGCC wird darauf hingewiesen, dass später im Programm eine Funktion mit dem Namen text1 erscheinen wird.

  • Zeilen 5 ... 9 Hauptprogramm main()

Im Hauptprogramm wird mit Zeile 7 gestartet, dem Funktionsaufruf der Funktion void text1(void). Die Funktion wird gesucht und die erste Befehlszeile dieser Funktion ausgeführt. Im Terminal erscheint der Text "Dieser Text wurde über die Funktion ausgegeben!", gefolgt von einer Pause von 1s. Sind alle Programmzeilen in der Funktion abgearbeitet, kehrt das Programm zum Funktionsaufruf im Hauptprogramm zurück und setzt seine Arbeit mit der auf den Funktionsaufruf folgenden Programmzeile seine Arbeit fort (Zeile 8). Ein weiterer Text erscheint im Terminal.

Abbildung 3 - Verzweigung bei einem Funktionsaufruf in einem Prop-C Programm

2 - Das Format einer Funktion

Der Bezeichner void links vom Funktionsnamen text1 bedeutet, dass die Funktion keinen Rückgabewert enthält. Der Bezeichner (void) rechts hinter dem Funktionsnamen text1 bedeutet, dass für die Funktion keine Parameterübergaben vorgesehen sind.

Die Funktion selbst besteht aus einem Befehlszeilenblock, der von geschweiften Klammern begrenzt wird. 

Abbildung 4 - Aufbau und Beschreibungsgrößen einer Funktion unter Prop-C

Der Vorteil von Funktionen ist, dass sie, einmal für ein Programm geschrieben, später auch in anderen Programmen eingesetzt werden können.

Mehrfache Nutzung einer Funktion im Programm
Aufgaben
  • Speicher das Programm funktion1.c unter dem neuen Namen funktion2.c ab.
  • Ändere die Programmzeilen nach Abb. 5 ab bzw. füge weitere hinzu.
  • Speichere das Programm erneut ab und starte es mit Run Project with Terminal. Überprüfe, ob das Programm den Text der Funktion drei mal hintereinander ausgibt.

Änderungen im Programm funktion1.c

Abbildung 5 - Änderungs- bzw. Zusatzzeilen im Programm funktion2.c

Terminalausgabe

Abbildung 6 - Terminalausgabe zum Programm funktion2.c

3 - Funktion mit Parameterübergabe

Häufig ist es notwendig, einer Funktion mit ihrem Aufruf im Hauptprogramm einen oder mehrere Parameter zu übergeben, damit sie ihre Aufgabe erledigen kann. Die Übergabewerte bezeichnen wir als Parameter.

Funktion mit Parameterübergabe
Aufgaben
  • Übertrage das Programm parameter1.c in den Editor und speichere es ab.
  • Versuche, bevor das Programm gestartet wird, Zeile für Zeile zu begründen, was das Programm machen wird.
  • Starte das Programm mit Run with Terminal und vergleiche deine Ergebnisse (Vorhersagen) mit der tatsächlichen Programmausführung.

Das Programm parameter1.c

Das Programm parameter1.c

Terminalausgabe

Abbildung 8 - Terminalausgabe zum Programm parameter1.c

Wie arbeitet das Programm parameter1.c?

In einer forward Deklaration wird die neue Funktion im Programm benannt (Zeile 3). Erinnern wir uns daran, dass das void vor dem Funktionsnamen darauf hinweist, dass die Funktion ohne Rückgabewert ist. Das (int a) in Klammern rechts vom Funktionsnamen weist darauf hin, dass die Funktion einen Variablenwert vom Typ int bei einem Funktionsaufruf erwartet.

Der Hauptteil des Programms startet mit dem Funktionsaufruf von wert(3); der Wert 3 wird damit der Funktion wert übergeben und dort in der Variablen a abgelegt. Die Ausführung der Funktion wert(3) schließt sich an, der Text der Funktion erscheint im Terminal und das Programm wird beendet.

 

Lokale Variable

Die in der Funktion wert deklarierte Variabel a vom Typ int ist eine sogenannte lokale Variable. Sie wird nur innerhalb der Funktion benutzt und nur dafür wird vom Controller Speicher zur Verfügung gestellt. Es kann mehrere Funktionen geben, die alle die lokale Variable a enthalten, ohne dass es dabei Probleme geben muss.

Es ist möglich, im Kopf einer Funktion mehrere, durch Komma getrennte Parameter zu definieren. Das folgende Programm volumen.c enthält eine Funktion quader(int a, int b, int c), die das Volumen eines Quaders berechnet.

Abbildung 9 - Programm volumen.c

Terminalausgabe

Abbildung 10 - Terminalausgabe zum Programm volumen.c

4 - Funktion mit Parameterübergabe und Rückgabewert

Manche Funktionen geben, nachdem die Programmzeilen in ihr ausgeführt wurden, einen Wert an das aufrufende Programm zurück. Dies wäre zum Beispiel bei einer Funktion taster der Fall, die den Zustand eines Tasters überprüft und ihn an das Hauptprogramm zurück gibt.

Funktion mit Parameterübergabe und Rückgabewert
Aufgaben
  • Übertrage das Programm funktionParameterRueckgabewert.c in den Editor und speichere es ab.
  • Versuche, bevor das Programm gestartet wird, Zeile für Zeile zu begründen, was es machen wird.
  • Starte das Programm mit Run with Terminal und vergleiche deine Vorhersagen mit der tatsächlichen Programmausführung.

Das Programm funktionParameterRueckgabewert.c

Abbildung 11 - Programm funktionParameterRueckgabewert.c mit Terminalausgabe

Wie arbeitet das Programm?

Die Funktion addierer wird definiert durch int addierer(int a, int b). Die Parameter in Klammern bedeuten, dass der Funktion beim Aufruf zwei Werte vom Typ integer übergeben werden müssen. Der Bezeichner int vor dem Funktionsnamen weist darauf hin, dass auch der Rückgabewert vom Typ int ist.

Innerhalb des Hauptprogramms, in Zeile 7, wird der Rückgabewert der Funktion addierer der Variablen n vom Typ int zugewiesen und die Werte 25 und 17 an die Funktion addierer in Zeile 11ff übergeben. Dort werden sie addiert und das Ergebnis der lokalen Variablen c zugewiesen (Zeile 14). Dies ist der Rückgabewert der Funktion addierer.

5 - Globale Variablen

Manchmal ist es notwendig, dass mehrere Funktionen auf die gleichen Variablen zurückgreifen und mit ihnen arbeiten können. Diese gemeinsam genutzten Variablen bezeichnen wir als globale Variablen. Der Mehrkern Propeller Controller kann verschiedene Funktionen mit verschiedenen Cogs gleichzeitig ausführen (echtes Multitasking oder Processing). Die Funktionen werden parallel ausgeführt und benutzen globale Variable für den Informationsaustausch.

Das folgende Programm ist ein leicht verändertes Programm funktionParameterRueckgabewert aus Thema 4, bei dem alle lokalen Variablen gegen globale ausgetauscht wurden.

Programm globaleVariable.c

Abbildung 12 - Programm globaleVeriable.c mit Terminalausgabe

Wie arbeitet das Programm?

In der Definition der Funktion addierer durch void addierer(void) befindet sich kein Parameter oder ein Rückgabewert.

Die Variablen a, b und c werden in Zeile 4 als globale Variable definiert; da sie alle vom gleichen Typ sind, genügt es, die Typbezeichnung einmal zu setzen und die Variablennamen durch Komma getrennt aufzuzählen.

In den Zeilen 8 und 9 werden den beiden Variablen a und b Werte zugeordnet und anschließend die Funktion addierer aufgerufen, die das Ergebnis der Addition der globalen Variablen n zuordnet. Die print-Anweisung gibt die Summe schließlich im Terminal aus.

Was man weiß, was man wissen sollte!

Globale Variable benötigen mehr Speicherplatz, kann aber in bestimmten Fällen die Programmausführung beschleunigen. Lokal definierte Variable verlangsamen ein Programm, da das Initialisieren und das Löschen aus dem Speicher Zeit kosten. Werden in einem Projekt viele lokale Variable eingesetzt, kann das sehr viel Prozessorzeit kosten!

Globale und lokale Variable beschreiben jeweils den Anwendungsbereich (scope) und den Kontext, in dem sie genutzt werden können.

Kommentar schreiben

Kommentare

  • olaf (Sonntag, 10. Dezember 2017 08:35)

    wow...die mit Abstand beste Site, die ich bisher zu diesem Thema gesehen habe :-))
    Vielen Dank dafür. Hilft super beim Erklären!!

  • David Eisenblätter (Sonntag, 11. Februar 2018 13:38)

    Sehr schön erklärt, und zufällig heute, wo ich nochmal nach einer detailierten Gedankenstütze diesbezüglich gesucht habe!

    Vielen vielen Dank!

    David.

Bitte geben Sie den Code ein
* Pflichtfelder
Druckversion Druckversion | Sitemap
© Reinhard Rahner - Gettorf