Funktionen

Werbung
Kapitel 2
Funktionen
Mit Funktionen kann man in C++-Programmen bestimmte Aufgaben erledigen. Mit
der Funktionsdefinition gibt man an, was die Funktion tun soll. Eine Funktion kann
nicht aufgerufen werden, solange sie nicht deklariert wurde. Funktionen geben entweder einen Wert oder void (das heißt kein Rückgabetyp) zurück. Funktionen gliedern
sich in Kopf und Rumpf. Der Kopf besteht aus dem Rückgabetyp, dem Namen der
Funktion und den Parametern. Ein typischer Funktionskopf sieht folgendermaßen
aus:
int sum(int a, int b)
Der Name der Funktion samt Parameter wird auch als Signatur bezeichnet. Der
Rumpf einer Funktion besteht aus einer öffnenden geschweiften Klammer, einer beliebigen Zahl von Anweisungen, und einer schließenden geschweiften Klammer. Funktionen können einen Wert mit Hilfe der return Anweisung zurückgeben. Falls man
keine return Anweisung vorsieht, liefert die Funktion automatisch void zurück. Folgende Funktion add.cc liest zwei Werte ein und gibt die Summe der beiden Zahlen:
1: #include<iostream>
2: using namespace std;
3:
4: int add(int x, int y);
5:
6: int main()
7: {
8:
int a, b, c;
9:
cout << "Bitte geben Sie zwei Zahlen ein: " << endl;
10:
cin >> a;
11:
cin >> b,
12:
c = add(a,b);
13:
cout << "Die Summe von " << a << " und " << b << " ist " << c << endl;
14:
return 0;
1
15:
16:
17:
18:
19:
20:
}
int add(int x, int y)
{
return (x+y);
}
Die Funktionsdeklaration steht in Zeile vier. Die Funktionsdefinition steht in den Zeilen 18 bis 20. Die Funktionsdefiniton und -deklaration müssen bis auf das Semikolon
identisch sein, sonst erhält man einen Compilerfehler. Die Anweisungen innerhalb
des Rumpfes der Funktion müssen mit einem Semikolon abgeschlossen sein.
Variablen, die in Funktionen deklariert sind, heißen lokale Variablen. Sie existieren
nur innerhalb der Funktion. Variablen, die außerhalb aller Funktionen definiert sind,
heißen globale Variablen. Sie sind in jeder Funktion sowie in main verfügbar. Lokale
Variablen verdecken globale: Bei Variablen mit gleichem Namen wird bei Aufruf
dieser Variablen zuerst in der lokalen Ebene gesucht. Im Allgemeinen vermeidet man
globale Variablen.
Funktionsargumente müssen nicht alle vom selben Typ sein.
Es ist auch möglich, Funktionen als Parameter zu übergeben.
Die an eine Funktion übergebenen Werte sind lokal. Das demonstriert folgendes
Programm swap_wert.cc.
#include <iostream>
void swap(int x, int y);
int main()
{
int x = 5, y = 10;
std::cout << "Vor der Vertauschung x: " << x << " y: " << y << std::endl;
swap(x,y);
std::cout << "Nach der Vertauschung x: " << x << " y: " << y << std::endl;
return 0;
}
void swap (int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
2
Die Ausgabe lautet:
Vor der Vertauschung x: 5 y: 10
Nach der Vertauschung x: 5 y: 10
Die Funktion swap legt lokale Kopien der Werte an und vertauscht nur diese Kopien.
Nach Rückehr aus der Funktion void in die Funktion main werden diese lokalen
Kopien gelöscht. In main ist kein Unterschied festzustellen.
2.1
Rückgabewerte
Funktionen geben entweder einen Wert oder void zurück. Das Schlüsselwort hierfür
ist return, gefolgt von dem zurückzugebenden Wert. Dieser Wert kann auch ein
Ausdruck sein, der einen Wert liefert.
return 1;
return (x>1);
Der Wert in der zweiten Anweisung ist 1, falls x größer als 1 ist, sonst 0. Alle Anweisungen, die nach return stehen, werden nicht mehr ausgeführt.
2.2
Standardparameter
Falls man eine Funktion
int function (int x)
deklariert hat, so muss diese Funktion tatsächlich eine Integer-Variable übernehmen,
damit man keinen Compilerfehler erhält. Man kann allerdings auch mit Standardoder Defaultparametern arbeiten. Dies bedeutet, dass die Funktion einen Standardparameter verwendet, falls man keinen anderen Wert bereitstellt.
int function (int x=50)
Falls man diese Funktion ohne Argument aufruft, benutzt sie den Standardwert 50.
Die Funktionsdefinition ändert sich hierdurch nicht. Man kann allen Parametern
einer Funktion oder einem Teil davon Standardwerte zuweisen. Die Regeln hierfür
sind wie folgt: Der Funktion int function (int x, int y, int z) kann für y nur
ein Standardwert zugeordnet werden, wenn man für z einen Standardwert festgelegt
hat. An x lässt sich nur dann ein Standardwert zuweisen, wenn sowohl y als auch z
Standardwerte haben.
3
2.3
Funktionen überladen
Es ist in C++ möglich, mehrere Funktionen mit demselben Namen zu erzeugen, die
sich nur in der Parameterliste (durch unterschiedliche Typen oder eine andere Anzahl
an Parametern) unterscheiden.
int function (int x, int y);
int function (double x, double y);
int function (int x);
Ein Überladen bezüglich des Rückgabetyps ist nicht möglich. Das Überladen von
Funktionen bezeichnet man auch als Funktionspolymorphie.
2.4
Inline Funktionen
Normalerweise springt der Compiler beim Aufruf einer Funktion zu den Anweisungen
der Funktion und geht bei Rückkehr aus dieser Funktion in die nächste Zeile der
aufrufenden Funktion. Das bedeutet für den Prozessor zusäzlich Arbeit. Falls man
oft Funktionen benutzt, die nur aus wenigen Zeilen bestehen, empfielt sich daher eine
andere Technik. Man definiert diese Funktion als inline. Dann erzeugt der Compiler
keine Funktion im engeren Sinn, sondern kopiert den Code für die Inline-Funktion
direkt in die aufrufende Funktion. Die Sprünge des Compilers fallen weg und es ist
so, als hätte man die Anweisungen der Funktion direkt in die aufrufende Funktion
geschrieben. Dadurch wird die Datei größer. Generell kommen nur Funktionen als
inline in Frage, die sehr klein sind (wenige Anweisungen). Die Deklaration einer
Inline-Funktion schreibt sich:
inline int function (int);
Die Deklaration einer Funktion als inline ist nur eine Empfehlung an den Compiler,
die dieser auch ignorieren kann.
2.5
if-Anweisung
Wie in anderen Programmiersprachen kann man in C++ auch die if-Anweisung
verwenden. Die Syntax ist
if (Ausdruck1)
Anweisung1;
Solange Ausdruck1 wahr ist, wird die Anweisung ausgeführt. Auch die else-Anweisung
kann verwendet werden:
4
if (Ausdruck1)
Anweisung1;
else
Anweisung2;
Auch kompliziertere if-else-Anweisungen sind möglich, allerdings müssen Aneisungen über mehrere Zeilen in geschweiften Klammern stehen.
if (Ausdruck1)
{
if (Ausdruck2)
Anweisung1;
else
{
if (Ausdruck3)
Anweisung2;
else
Anweisung3;
}
}
else
Anweisung4;
2.6
switch-Anweisung
Mit der switch-Anweisung lassen sich Verzweigungen in Abhängigkeit von mehreren
unterschiedlichen Werten aufbauen. Die Synatx einer allgemeinen switch-Anweisung
lautet:
switch (Ausdruck)
{
case Wert1: Anweisung;
break;
case Wert2: Anweisung;
break;
...
case WertN: Anweisung;
break;
default:
Anweisung;
}
Ausdruck ist jeder gültige C++-Ausdruck, Anweisung jede beliebige C++-Anweisung.
switch wertet Ausdruck aus und vergleicht das Ergebnis mit den Werten hinter
5
case. Stimmt kein Wert überein, wird die Anweisung hinter default ausgeführt.
Die Auswertung erfolgt nur auf Gleichheit. Falls die break-Anweisung am Ende eines case-Zweigs fehlt, führt das Programm den nächsten case-Zweig aus.
2.7
2.7.1
Schleifen
while
Eine while-Schleife wiederholt eine Folge von Anweisungen, solange die Startbedingung wahr ist.
while(Ausdruck)
{
Anweisung1;
Anweisung2;
}
Falls das Programm zu Anfang der while-Schleife zurückkehren soll, noch bevor alle
Anweisungen abgearbeitet sind, benutzt man die continue-Anweisung. Die breakAnweisung führt zum Austritt aus der while-Schleife und die Programmausführung
setzt sich nach der schließenden Klammer fort.
2.7.2
for
Die for-Schleife hat drei Anweisungen. In der ersten Anweisung wird üblicherweise
die Zählervariable initialisiert. Die zweite Anweisung testet eine Bedingung und die
dritte Anweisung inkrementiert oder dekrementiert normalerweise die Zählervariable.
Eine typische for-Schleife sieht wie folgt aus:
for (int i=0; i<10; i++)
{
cout << "i= " << i << endl;
}
Man kann auch mehrere Variablen in einer Schleife initialisieren und inkrementieren:
for (int i=0; j=0; i<10; i++, j++)
{
cout << "i= " << i << " j: " << j << endl;
}
6
2.8
Statische Variablen
Statische Variablen sind mit globalen Variablen vergleichbar. Sie werden nur beim
ersten Aufruf der Funktion durch ihre Definition initialisiert. Das Beispiel static.cc
verdeutlicht dies:
#include<iostream>
using namespace std;
void f(int a)
{
while(a>0)
{
static int n = 0;
int x = 0;
cout << "n == " << n++ << "; x == " << x++ << endl;
a--;
}
}
int main()
{
f(3);
}
mit der Ausgabe
n == 0; x == 0
n == 1; x == 0
n == 2; x == 0
Die Variable n wird nur einmal initialisiert, die Variable x hingegen a-mal.
2.9
Typcast
Zum Typcast dienen die Operatoren static_cast, dynamic_cast und const_cast.
Die Syntax (für alle Operatoren gleich) ist
static_cast<Typ>(Ausdruck)
Beim Aufruf der Operatoren wird Ausdruck geprüft und in Typ umgewandelt. static_cast
castet zwischen elementarenDatentypen und Klassen. dynamic_cast castet Zeiger
oder Referenzen auf miteinander verwandte ploymorphe Klassen. Dieser Cast wird
im Gegensatz zum statischen Cast zur Laufzeit ausgeführt. const_cast dient zur
Entfernung der Konstantheit eines Typs.
7
Herunterladen