home

7. Abend

Druckversion dieser Seite

 

Ziele

  • Wir sind ab heute Abend in der Lage Unterprogramme zu definieren. Solche Unterprogramme werden Funktionen genannt und enthalten Code, den wir von verschiedenen Orten aus aufrufen werden.

Funktionen

Funktionen sind kleine Unterprogramme. Häufig verwendeter Code kann in Funktionen gepackt werden um ein Programm effizienter und übersichtlicher zu gestalten. Ein einfaches Beispiel zeigt uns auch gleich die Anwendung und Definition von Funktionen.

Nehmen wir an, dass wir ein Programm schreiben, dass häufig geometrische Berechnungen anstellt. Wir müssen an verschiedenen Stellen eine Kreisfläche aus einem Radius berechnen.

main.cpp

#include <iostream> using namespace std; // Um eine Funktion zu verwenden // müssen wir dem Compiler bekannt // machen, wie diese Funktion // heisst und was sie für einen // Rückgabetypen double KreisFlaeche(double Radius); // Eine Funktionsdeklaration beginnt // mit dem Rückgabetypen, hier : double // danach der Funktionsname // hier : KreisFlaeche // In Klammern stehen dann die // Parameter die der Funktion übergeben // werden. Danach ein Semikolon ! // main ist auch eine Funktion ! int main() { char weiter = 'j'; while('j' == weiter) { cout << "Bitte Radius eingeben : "; double r = 0.0; cin >> r; // die neue Variable ergebnis // erhält den Wert, der in der // Funktion KreisFlaeche berechnet // wird double ergebnis = KreisFlaeche(r); cout << endl; cout << "Die Kreisflaeche betraegt : "; cout << ergebnis << endl; cout << "weiter ? "; cin >> weiter; } return 0; } // Konstante für PI const double PI = 3.14159; // Hier wird die Funktion, die wir // oben deklariert haben nun // definiert double KreisFlaeche(double Radius) { double flaeche = Radius * Radius * PI; return flaeche; }

Um zu zeigen, wie wir diese Funktion weiterverwenden können machen wie eine zusätzliche Funktion, die eine Ringfläche berechnet.

main2.cpp

#include <iostream> using namespace std; // Funktionsprototypen double KreisFlaeche(double Radius); double RingFlaeche(double InnenRadius, double AussenRadius); int main() { char weiter = 'j'; while('j' == weiter) { cout << "[1] fuer Kreis" << endl; cout << "[2] fuer Ring" << endl; int wahl = 0; cin >> wahl; double ergebnis = 0.0; switch(wahl) { case 1: { double r = 0.0; cin >> r; ergebnis = KreisFlaeche(r); } break; case 2: { double ri = 0.0; double ra = 0.0; cin >> ri; cin >> ra; ergebnis = RingFlaeche(ri, ra); } break; default: break; } cout << endl; cout << "Das Ergebnis betraegt : "; cout << ergebnis << endl; cout << "weiter ? "; cin >> weiter; } return 0; } // Konstante für PI const double PI = 3.14159; // Hier wird die Funktion, die wir // oben deklariert haben nun // definiert double KreisFlaeche(double Radius) { double flaeche = Radius * Radius * PI; return flaeche; } double RingFlaeche(double InnenRadius, double AussenRadius) { // Ringfleache mit Verwendung der // KreisFlaeche-Funktion double flaeche = KreisFlaeche(AussenRadius) - KreisFlaeche(InnenRadius); return flaeche; }

Parameterübergabe

Eine Funktion kann Parameter erhalten. Da sind Werte, die der Funktion übergeben werden können und in der Funktion zur Verfügung stehen. Ein Parameter hat auch einen Datentypen sowie ein Name, den der Parameter in der Funktion hat. Dieser Name ist nur in der Funktion gültig ! Hier ein kleines Beispiel um dies zu verdeutlichen :


#include <iostream>

using namespace std;

// Funktionsprototypen
void AusgabeEinesInt(int einInt);

int main()
{
    int test = 5;

    // Hier wird der Wert
    // der Variable test
    // an die Funktion übergeben
    AusgabeEinesInt(test);

    // Hier wird direkt der
    // Ganzzahlwert 99 an die
    // Funktion übergeben
    AusgabeEinesInt(99);

    return 0;
}

void AusgabeEinesInt(int einInt)
{
    // Hier in der Funktion
    // heisst der Wert der an
    // die Funktion übergeben wurde
    // immer einInt !
    cout << einInt << endl;
}

Rückgabewert

Wie wir bereits gesehen haben, kann bei einer Funktion, die eine Berechnung irgendeiner Art anstellt das Ergebnis dieser Berechnung als Rückgabewert verwendet werden. Die allgemeine Form sieht dabei etwa so aus :


Variable = Funktion(Parameter);

Hat eine Funktion einen Rückgabewert muss der Datentyp der bestimmt werden. So hat im Beispiel oben die Funktion "KreisFlaeche" den Rückgabetyp double. Die Zeile bedeutet also, dass der Variable der Wert zugewiesen wird, den die Funktion zurückgibt. Es gibt jedoch Funktionen, die keinen sinnvollen Rückgabewert haben. Diese Funktionen haben den Rückgabetypen void (Leer). Hier ein Beispiel für eine Funktion, die sinnvollerweise keinen Rückgabetypen hat :


void SagHallo() { cout << "Hallo" << endl; }

Diese Funktion hat auch keine Parameter... wären doch alle Funktionen so einfach... In der Funktion selber wird, falls es einen Rückgabewert gibt, dieser mit return zurückgegeben. Dieses return muss nicht einmal am Ende der Funktion stehen, wie wir im folgenden Beispiel sehen :

main3.cpp

// Diese Funktion findet heraus // ob der Benutzer die Funktion // noch einmal ausführen will bool Wiederholen() { cout << "Funktion wiederholen ?" << endl; string antwort; cin >> antwort; if(antwort == "Ja") { // Entscheidung ist // getroffen, also // Rückgabe von true return true; } else { return false; } }

Sichtbarkeit von Variablen

Variablen, die wir in unserem Code irgendwo deklarieren sind nicht überall sichtbar, das heisst wir können sie nicht von überall her ansprechen. Dies ist insbesondere bei Funktionen wichtig und soll darum an dieser Stelle vertieft werden.

Globale Variablen

Globale Variablen werden ausserhalb jeglicher Funktion definiert und sind darum grundsätzlich in jeder Funktion "sichtbar".


int eineGlobaleVariable = 0; void eineFunktion() { eineGlobaleVariable = 33; } int main() { eineGlobaleVariable = 99; // Funktion aufrufen eineFunktion(); return 0; }

Die Variable "eineGlobaleVariable" wird ausserhalb von jeglicher Funktion definiert, also hier ausserhalb der Funktion "eineFunktion" sowie ausserhalb der Funktion "main" ! In beiden Funktionen können wir darauf zugreifen. VERMEIDET GLOBALE VARIABLEN ! Es ist zum Beispiel in der main-Funktion nicht unbedingt klar, dass der Aufruf der Funktion "eineFunktion" auch gleich die Variable "eineGlobaleVariable" verändert. Solche sogenannten "Seiteneffekte" sollten tunlichst vermieden werden, da sie eine gefährliche Fehlerquelle darstellen.

Im allgemeinen ist aber eine Variable nur innerhalb der umschliessenden geschweiften Klammern sichtbar :


{ int a = 0; // ab hier ist die Variable sichtbar // .... } // ab hier ist die Variable nicht mehr sichtbar !
main4.cpp

void Funktion() { int lokaleVariable = 0; // hier ist lokaleVariable sichtbar } // hier ist lokaleVariable nicht mehr sichtbar! int main() { int i = 55; if(i < 100) { int test = 0; // test nur innerhalb der // if Klammern } else { int test = 666; // dieses "test" ist nur // im else Block sichtbar } return 0; }

Zu den Übungen

  Im Buch gibt es einige Übungen (zum Beispiel Kapitel 8 Aufgabe 4), die zwei Makros verwenden um Zeichen an einem bestimmten Ort auszugeben oder den Bildschirm zu löschen. Die zwei Makros heissen: CLS und LOCATE. Leider funktionieren diese nicht unter Windows2000. Aber Hilfe naht : Hier findet ihr die beiden Dateien "Console.h" und "Console.cpp". Kopiert diese Dateien in das Verzeichnis, wo ihr Euer Projekt drin habt und nehmt diese Dateien im Visual-Studio in das Projekt auf.
Die Verwendung ist wie folgt : Macht den Datentyp Console in eurem main.cpp bekannt indem ihr die Datei Console.h includiert (#include). Im main erzeugt ihr eine Variable vom Datentyp Console :
 

int main()
{
Console dieConsole;
...
}
  Um den Bildschirm zu löschen ruft ihr dann auf :
 

dieConsole.Clear();
  Um an eine bestimmte Bildschirmstelle zu springen ruft ihr auf :
 

dieConsole.Locate(x, y);
  Wir werden zusammen die Übung 4 zu Kapitel 8 ansehen, da es einige Punkte zu beachte gibt und es auch etwas zu sehen gibt. Hier vorerst die Datei.

Zu der Prüfung

  Die Prüfung wird den Stoff aus dem Buch bis und mit Kapitel 10 beinhalten. Um Euch einen Eindruck von möglichen Fragen zu geben hier einen Ausschnitt aus der Prüfung vom letzten Jahr. Es wird zusätzlich einige Programmabschnitte geben, die ihr einfach verstehen müsst. Die Frage wird dann lauten : was gibt dieses Programm aus ?
  Hier noch zwei weitere typische Aufgaben :
  1. Wandle folgende switch-case Anweisung in die entsprechend if-else Anweisung !
 

void funktion() { int i; cin >> i; switch(i) { case 0: cout << "Null eingegeben" << endl; break; case 1: cout << "Eins eingegeben" << endl; break; default: cout << "Irgendwas eingegeben" << endl; break; } }
  2. Wandle folgende while-Schleife ein eine for-next Schleife um !
 

void hallo() { int i = 0; while(i < 5) { cout << "Hallo" << endl; ++i; } }