|
Eine der wichtigsten Herangehensweise bei der Programmierung von Computern / Mikrocontrollern ist das Aufteilen des Programms in Haupt- und Unterprogramme. Unterprogramme dienen dafür, öfters wiederkehrende Aufgabenstellungen in einem Programm (und nur diese) zu bearbeiten. Unterprogramme werden in C als function bezeichnet. Zu jedem C-Compiler gehört ein Softwarepaket, den sogenannten Standardbibliotheken, die bereits eine Vielzahl von Funktionen zur Verfügung stellen (bspw. die Bibliothek math, die Funktionen für mathematische Aufgaben zur Verfügung stellt). Eine gute Unterteilung eines Programms in sinnvolle, selbst erstellte Funktionen sollte in jedem Programm stattfinden, damit dieses gut wartbar und an evtl. geänderte Anforderungen anpassbar ist. Grundsätzlich gibt es 2 Arten von Funktionen:
Beispiel für eine Funktion ohne Rückgabewert: /* ---------------------------------------------------------- example_f01.c Beispiel zur Verwendung von Funktionen ---------------------------------------------------------- */ #include "smallio.h" /* ------------------------------------------ tu_etwas eine eigene Funktion ------------------------------------------ */ void tu_etwas(void) // die Funktion heisst "tu_etwas" { printf("\n\r Ich tu ja schon was...\n\r"); } /* ------------------------------------------ main auch "main" ist eine Funktion, sie ist die Hauptfunktion des Programmes ------------------------------------------ */ int main(void) { smallio_init(); tu_etwas(); // Aufruf der eigenen Funktion } Das Beispiel macht nicht wirklich viel, es verdeutlich jedoch den Aufruf einer Funktion. Hat die Funktion wie im Fall oben keinerlei weitere Funktionsargumente, so ist als Parameter für die Funktion das Schluesselwort void (für "nichts") anzugeben. Funktionen können optional ein oder mehrere Funktionsparameter enthalten, die innerhalb der Funktion ausgewertet werden. Für jeden Funktionsparameter ist der Datentyp anzugeben. Ein solcher Funktionsparameter ist, wenn nicht durch const eingeschränkt, auch als Variable innerhalb der Funktion verwendbar. Werden Parameter angegeben, wird beim Funktionsaufruf Speicher für diese Parameter reserviert, die innerhalb der Funktion als Variable verwendet werden können. Nach Beendigung der Funktion wird dieser Speicher wieder freigegeben. Gleiches gilt für Variable, die innerhalb einer Funktion angelegt werden (es sei denn, sie sind als static definiert). Für diese Variable wird beim Aufruf ebenfalls Speicher reserviert, der bei Beendigung der Funktion wieder frei gegeben wird. Beispiel: /* ---------------------------------------------------------- example_f02.c Beispiel zur Verwendung von Funktionen ---------------------------------------------------------- */ #include "smallio.h" void print_add(uint16_t z1, uint16_t z2) { uint16_t ergeb; ergeb= z1 + z2; printf("\n\r %d + %d = %d \n\r", z1, z2, ergeb); } /* ------------------------------------------ main ------------------------------------------ */ int main(void) { uint16_t zahl; // Variable, nur gueltig fuer main smallio_init(); zahl= 42; print_add(zahl, 119); // Aufruf der eigenen Funktion }Funktion mit Rückgabewert Bei Funktionen, die ein Ergebnis zurück geben sollen, muss anstelle von void der Datentyp angegeben werden, den er zurueckliefern soll. Im nachfolgenden Beispiel ist dieses: int16_t addiere(int16_t zahl1, int16_t zahl2)Das Ergebnis, das eine solche Funktion zurückliefert, wird durch die Angabe von return wert;Beispiel: /* ---------------------------------------------------------- example_f03.c Beispiel zur Verwendung von Funktionen mit Rueckgabewert ---------------------------------------------------------- */Erklärungen: Mit addiere wird eine Funktion definiert (programmiert), die zwei Zahlen miteinander addiert und die Summe hiervon als Rückgabewert der Funktion liefert. Im Hauptprogramm main sind Variable z1, z2 und summe definiert. z1 und z2 werden Werte zugewiesen und diese Variable der Funktion addiere als Funktionsparameter übergeben. Das Ergebnis der Funktion wird der Variable summe zugewiesen und ein anschliessendes printf gibt das Ergebnis der Addition aus. Ein zweiter Aufruf von addiere erfolgt dieses mal nicht mit Variablen, sondern mit konstanten Werten. Auch diese werden von der Funktion addiere verarbeitet (und anschliessend ausgegeben). |
|
Wird einer Funktion anstelle eines Wertes (value) die Speicheradresse (reference) einer Variable übergeben (nicht die Variable selbst) die den Wert beinhaltet, so wird der Aufruf einer solchen Funktion als "call by reference" bezeichnet. Die Übergabe der Speicheradresse wird mittels Zeigervariable (Pointer) vorgenommen. Das nachfolgende Beispielprogramm beinhaltet zwei "call by reference" Funktionen:
Beispielprogramm:
/* ----------------------------------------------------------
example_f04.c
Beispiel fuer "call by reference"
---------------------------------------------------------- */
#include "smallio.h"
void myprint(char *mytext) // mytext beinhaltet Adresse des Textes
{
char ch;
while(*mytext) // wiederhole solange, bis das Zeichen
{ // auf das *mytext zeigt > 0 ist und
// somit keine Endekennung ist.
ch= *mytext;
putchar(ch);
mytext++; // Zeiger auf naechstes Element zeigen
// lassen
}
}
void searchreplace(char search, char replace, char *mytext)
{
while(*mytext)
{
if (*mytext == search) // bei Uebereinstimmung des Zeichens
{
*mytext = replace; // an dieselbe Stelle das Ersatz-
} // zeichen setzen
mytext++; // naechstes Element
}
}
int main(void)
{
char mytext_dt[] = "Mein Name ist Hase\n\r";
char meldung[] = "\n\rErsetze Buchstaben a durch einen Punkt .\n\n\r";
smallio_init();
myprint(&mytext_dt[0]); // myprint-Funktion wird die Adresse von
// mytext_dt mit dem ersten Element ueber-
// geben.
myprint(&meldung[0]); // dto. mit Meldungstext
searchreplace('a','.', &mytext_dt[0]);
myprint(&mytext_dt[0]);
}
Ausgabe:
Mein Name ist Hase Ersetze Buchstaben a durch einen Punkt . Mein N.me ist H.se |