Solars C++ Kurs
Programmieren leicht erlernt
Funktionen

Funktionsdeklaration

Bisher haben wir in diesem Kapitel zwar viel neues Gelernt, aber dabei nicht unser ursprüngliches Rechenprogramm weiterentwickelt.

Das war nötig, da die neuen Themen doch recht kompliziert waren und sich besser an sehr kurzen Programmen erklären ließen. Da es jetzt wieder etwas einfacher wird, werden wir nun wieder ein Rechenprogramm erstellen.

Bei diesem Programm sollen zwei Zahlen als Argument übergeben werden. Das Programm soll die Summe daraus errechnen. Das berechnen und die Ausgabe vom Ergebnis soll eine Funktion übernehmen. Das Programm soll keine Kommastellen kennen, also nur mit Integern rechnen.

Kompilieren sie folgenden Quelltext und speichern sie das kompilierte Programm als RECHNE.EXE ab.

main.cpp
#include <iostream.h>
#include <stdlib.h>

void ScppkPlus( int nZahl1, int nZahl2 )
{
  cout << nZahl1 + nZahl2;
}

int main( int argc, char * argv[], char * envp[] )
{
  int nZahl1;
  int nZahl2;

  if ( argc != 3 )
  {
    cout << "Bitte geben sie 2 Zahlen als Parameter an.\n";
    cout << "z.B.  Rechne 12 8\n";
  }
  else
  {
    nZahl1 = atoi( argv[ 1 ] );
    nZahl2 = atoi( argv[ 2 ] );
    cout << "\n" << nZahl1 << " + " << nZahl2 << " = ";
    ScppkPlus( nZahl1, nZahl2 );
  }
  return 0;
}

Dieses Programm ist jetzt noch ziemlich Fehleranfällig. Deshalb bauen wir jetzt eine Funktion ein, welche testet, ob das Ergebnis überhaupt gültig ist.

Um das herauszufinden, berechnen wir die Aufgabe parallel mit double-Variablen. Das Ergebnis übergeben wir an die neue Funktion, welche die Gültigkeit der Zahl überprüft. Der Datentyp double kann sich selbst auf ungültig setzen wenn das Ergebnis sich nicht als double speichern läßt. Danach achten testen wir das Ergebnis noch darauf, ob es in den Wertebereich eines Integers fällt und ob es zu groß oder klein ist.

Hier das dementsprechend veränderte Programm:

main.cpp
#include <iostream.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>



int nScppkIntegertest( double dZahl )
{
  int nReturn = 0;
  if ( _finite( dZahl ) )
  {
    if ( dZahl > INT_MAX )
    {
      cout << "Error (Das Ergebnis ist zu gross)\n";
    }
    else if ( dZahl < INT_MIN )
    {
      cout << "Error (Das Ergebnis ist zu klein)\n";
    }
    else
    {
      nReturn = 1;
    }
  }
  else
  {
    cout << "Error (Das Ergebnis ist nicht definiert)\n";
  }
  return nReturn;
}



void ScppkPlus( int nZahl1, int nZahl2 )
{
  double dErgebnis;
  double d1 = 0;

  dErgebnis = (double) nZahl1 + (double) nZahl2;
  if ( nScppkIntegertest( dErgebnis ) )
  {
    cout << nZahl1 + nZahl2;
  }
}



int main( int argc, char * argv[], char * envp[] )
{
  int nZahl1;
  int nZahl2;

  if ( argc != 3 )
  {
    cout << "Bitte geben sie 2 Zahlen als Parameter an.\n";
    cout << "z.B.  Rechne 12 8\n";
  }
  else
  {
    nZahl1 = atoi( argv[ 1 ] );
    nZahl2 = atoi( argv[ 2 ] );
    cout << "\n" << nZahl1 << " + " << nZahl2 << " = ";
    ScppkPlus( nZahl1, nZahl2 );
  }
  return 0;
}

Jetzt soll das Programm nicht nur x+y sondern auch gleich x-y ausgeben. Damit das funktioniert brauchen wir nur eine neue Funktion einfügen und das Hauptprogramm leicht abändern.

Um nicht jedesmal das gesamte Programm hier wiederzugeben, werde ich ab jetzt häufig einen Teil des Quellcodes weglassen, wenn nur ein bereits benutzter Quellcode leicht geändert wird.
Wenn ich einen Teil auslasse, kennzeichne ich die Lücke mit drei untereinander liegenden Punkten. Der Quellcode welcher sich dort befindet braucht nicht geändert zu werden.
Vor und nach den Änderungen lasse ich etwas Quelltext stehen, damit man die Stelle, welche geändert werden soll finden kann. Den geänderten Quelltetxt selbst stelle ich in fetter Schrift da, damit man ihn direkt als solchen erkennen kann.

Ändern sie main.cpp bitte folgendermaßen ab:

main.cpp
#include <iostream.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>



void ScppkMinus( int nZahl1, int nZahl2 )
{
  double dErgebnis;
  double d1 = 0;

  dErgebnis = (double) nZahl1 - (double) nZahl2;
  if ( nScppkIntegertest( dErgebnis ) )
  {
    cout << nZahl1 - nZahl2;
  }
}



int nScppkIntegertest( double dZahl )
{

.
.
.

  else
  {
    nZahl1 = atoi( argv[ 1 ] );
    nZahl2 = atoi( argv[ 2 ] );
    cout << "\n" << nZahl1 << " + " << nZahl2 << " = ";
    ScppkPlus( nZahl1, nZahl2 );
    cout << "\n" << nZahl1 << " - " << nZahl2 << " = ";
    ScppkMinus( nZahl1, nZahl2 );
  }
  return 0;
}

Wenn sie versuchen diesen Quelltext zu kompilieren, wird der Compiler eine Fehlermeldung ausgeben.

Wenn wir in ScppkMinus die Funktion nScppkIntegertest benutzen, muß diese Funktion dort auch bekannt sein. Das ist sie in diesem Fall aber nicht, da nScppkIntegertest erst weiter unten steht.

Bei einem Programm mit 3 Funktionen mag es ja noch möglich sein, diese in die richtige Reihenfolge zu bringen. Aber stellen sie sich diese Arbeit mal bei einem Programm mit mehreren tausend Funktionen vor!

Dieses Problem läßt sich ganz leicht lösen. Man deklariert die Funktionen vor dem Gebrauch einfach. Eine Funktion deklarieren heißt soviel wie 'Die Funktion bekannt machen'.

Eine Funktionsdeklaration besteht aus der Kopfzeile der Funktion mit einem abschließendem Semikolon.

Die Funktion

int nScppkFunktion( int nUebergabeparameter )
{
  return nUebergabeparameter;
}

würde in der Deklaration folgendermaßen aussehen:

int nScppkFunktion( int nUebergabeparameter );

Die Deklaration sollte dabei vor allen Funktionen stehen.

Ändern sie das Programm folgendermaßen ab, und kompilieren sie es dann:

main.cpp
#include <iostream.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>



void ScppkMinus( int nZahl1, int nZahl2 );
int nScppkIntegertest( double dZahl );
void ScppkPlus( int nZahl1, int nZahl2 );
int main( int argc, char * argv[], char * envp[] );



void ScppkMinus( int nZahl1, int nZahl2 )
{

.
.
.

Es ist zwar nicht nötig die Funktion main zu deklarieren, da sie niemals von uns selbst aufgerufen wird, aber es schadet auch nicht. Durch die Deklaration aller Funktionen am Anfang des Quelltextes ist es egal, in welcher Reihenfolge die Funktionen benutzt werden, und das Programm läßt sich wieder kompilieren.