-
Notifications
You must be signed in to change notification settings - Fork 2
/
funktionen.tex
79 lines (72 loc) · 2.97 KB
/
funktionen.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
\section{Funktionen}
Es gibt viele Quelltextabschnitte, die wiederholt benutzt werden.
Es ist sinnvoll, diese Abschnitte nicht ständig zu wiederholen.
Das erhöht einerseits die Lesbarkeit des Quelltextes.
Andererseits macht es Code weniger fehleranfällig, da der Abschnitt nur einmal getestet werden muss.
Dafür existiert das Konzept von Funktionen.
Eine Funktion haben wir schon kennen gelernt, nämlich die Funktion \verb|main|.
In C sind Funktionen Variablen sehr ähnlich.
Eine Funktion kann wie folgt deklariert werden
\begin{lstlisting}
Rueckgabetyp Funktionsname(Parameterliste);
\end{lstlisting}
Man spricht von einem sogenannten Funktionsprototypen.
Die Parameterliste besteht aus durch Kommata getrennte Variablendeklarationen
\begin{lstlisting}
Typ1 name1, Typ2 name2, ...
\end{lstlisting}
Der Rückgabetyp kann jeder C Typ (und jeder selbst definierte Typ sein).
Bei streng strukturierten Programmiersprachen wie C werden der Funktionsname, die Parameterliste und der Rückgabetyp zusammen als Signatur der Funktion bezeichnet.
Die Definition einer Funktion muss dann natürlich einen Block von Anweisungen enthalten, also
\begin{lstlisting}
Rueckgabetyp Funktionsname(Parameterliste)
{
Rueckgabetyp x;
Anweisung1;
Anweisung2;
...;
return (x);
}
\end{lstlisting}
Die in der Parameterliste deklarierten Variablen sind dann innerhalb dieses Blocks definiert und unter ihrem Namen sichtbar.
Außerdem sind alle \emph{global} deklarierten Variablen im Funktionsblock sichtbar.
Für den Funktionsnamen gelten die gleiche Regeln, wie für Variablennamen.
Als Beispiel für eine Funktion schreiben wir einen Abschnitt, der die Fakultät einer ganzen Zahl berechnet:
\begin{lstlisting}
unsigned long int Fakultaet(const unsigned int zahl)
{
unsigned long int fak = 1;
for (int i = 2; i <= zahl; i++)
{
fak *= i;
}
return (fak);
}
\end{lstlisting}
Der Rückgabetyp ist als \verb|unsigned long int| gewählt, da die Fakultaet immer positiv ist, aber auch sehr groß werden kann.
Funktionen sollten wohldefinierte Unterprobleme lösen.
Ihr Umfang hängt natürlich von der Komplexität dieser Unterprobleme ab.
Man sollte trotzdem versuchen, dass Funktionen nicht zu viel Quelltext enthalten.
Sonst kann man mit sehr großer Wahrscheinlichkeit den Quelltext noch weiter aufspalten.
Aufgerufen werden Funktionen dann im Prinzip wie folgt
\begin{lstlisting}
Funktionsname(Aktualparameterlist);
\end{lstlisting}
Die Aktualparameterlist enthält dabei Variablen aus dem aufrufenden Codeabschnitt.
Dabei muss die Reihenfolge in der Funktionsdeklaration eingehalten werden.
Der C Compiler überprüft dies strickt und bricht die Übersetzung ab, falls es nicht gegeben ist.
Beispielsweise obige Funktion zur Berechnung der Fakultät kann wie folgt im Hauptprogramm aufgerufen werden:
\begin{lstlisting}
#include <stdio.h>
int main()
{
int n = 20;
unsigned long int result;
result = Fakultaet(n);
// oder
result = Fakultaet(3);
printf("%lud", result);
return (0);
}
\end{lstlisting}
\endinput