Solars C++ Kurs
Programmieren leicht erlernt
Funktionen

Mehrere CPP Dateien

Wenn das Programm aus einer einzigen CPP-Quelldatei compiliert wird, hat dies für den Entwickler vor allem zwei Nachteile:

Alleine der erste Grund sollte ausreichen, unsere CPP-Datei in zwei verschiedene CPP-Dateien aufzuteilen. In eine Datei kommt das eigendliche Programm und in die andere Datei alle mathematischen Funktionen.

Als erstes ist eine neue Datei zu erstellen. In diese Datei kopieren wir alle mathematischen Funktionen und fügen alle benötigten Header ein:

scppkMath.cpp
#include <iostream.h>
#include <limits.h>
#include <float.h>
#include "main.h"
#include "scppkMath.h"



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

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



int nScppkIntegertest( double dZahl )
{
  int nReturn = 0;
  if ( _finite( dZahl ) )
  {
    if ( dZahl > INT_MAX )
    {
      cout << SCPPK_STR_ERROR_ZUGROSS;
    }
    else if ( dZahl < INT_MIN )
    {
      cout << SCPPK_STR_ERROR_ZUKLEIN;
    }
    else
    {
      nReturn = 1;
    }
  }
  else
  {
    cout << SCPPK_STR_ERROR_UNDEFINIERT;
  }
  return nReturn;
}



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

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


Es ist sinnvoll zu jeder CPP-Datei eine eigene Header-Datei zu erstellen. Diese Headerdatei sollte alle Funktionsdeklarationen enthalten, welche für die CPP-Datei benönigt werden:

scppkMath.h
#ifndef __scppkMath_h__
#define __scppkMath_h__

void ScppkMinus( int nZahl1, int nZahl2 );
int nScppkIntegertest( double dZahl );
void ScppkPlus( int nZahl1, int nZahl2 );

#endif


Da die mathematischen Funktionen in eine eigene Datei verlagert wurden, müssen diese natürlich aus dem Hauptprogramm entfernt werden.
Damit diese Funktionen dem Hauptprogramm dennoch bekannt sind, sollten man die Headerdatei scppkMath.h mit einbinden:

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



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

  if ( argc != 3 )
  {
    SCPPK_OUT_HILFE
  }
  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;
}


In der Headerdatei des Hauptprogramms bleiben dann nur noch die definierten Texte zurück:

main.h
#ifndef __main_h__
#define __main_h__

#define SCPPK_STR_ERROR_ZUGROSS "Error (Das Ergebnis ist zu gross)\n"
#define SCPPK_STR_ERROR_ZUKLEIN "Error (Das Ergebnis ist zu klein)\n"
#define SCPPK_STR_ERROR_UNDEFINIERT "Error (Das Ergebnis ist \
  nicht definiert)\n"
#define SCPPK_OUT_HILFE \
  cout << "Bitte geben sie 2 Zahlen als Parameter an.\n";\
  cout << "z.B.  Rechne 12 8\n";

#endif


Nachdem die Dateien alle geändert wurden, sollte das Programm kompiliert werden.
Wenn sie mit einem Compiler mit einer IDE arbeiten, müssen sie die neue CPP-Datei erst zu ihrem Projekt hinzufügen. (Falls dies nicht bereits beim Anlegen der Datei geschah.)
Wenn sie mit einem Kommandozeilen-Compiler wie DJGPP arbeiten, kompilieren sie das Programm bitte so, wie im Kapitel 'Compiler - DJGPP 2' besprochen.

Jetzt ist der Quelltext zwar schon auf zwei verschiedene CPP-Dateien verteilt, scppkMath ließe sich dennoch nicht einfach in ein anderes Projekt einbinden, da in dieser Datei noch die Headerdatei main.h eingebunden wird, welche ausschließlich zu diesem Projekt gehört.
Deshalb entfernen wir das #include "main.h" aus scppkMath.cpp:

scppkMath.cpp
#include <iostream.h>
#include <limits.h>
#include <float.h>
#include "scppkMath.h"



void ScppkMinus( int nZahl1, int nZahl2 )

.
.
.


Ohne die Headerdatei kennt scppkMath.cpp die Defines aus main.h nicht mehr. Deshalb müssen diese aus main.h heraus nach scppkMath.h verschoben werden. Bei dieser Gelegenheit können wir scppkMath.h ein bischen Ordnen, so das die Headerdatei etwas übersichtlicher wird:

scppkMath.h
#ifndef __scppkMath_h__
#define __scppkMath_h__

///
/// Texte
///

#define SCPPK_STR_ERROR_ZUGROSS \
"Error (Das Ergebnis ist zu gross)\n"

#define SCPPK_STR_ERROR_ZUKLEIN \
"Error (Das Ergebnis ist zu klein)\n"

#define SCPPK_STR_ERROR_UNDEFINIERT \
"Error (Das Ergebnis ist \
nicht definiert)\n"

///
/// Funktionen
///

void ScppkMinus( int nZahl1, int nZahl2 );
void ScppkPlus( int nZahl1, int nZahl2 );

///
/// Intern genutzte Funktionen
///

int nScppkIntegertest( double dZahl );

#endif


Das in main.h übrig gebliebene Define wird jetzt umformuliert, damit nur noch Text und keine Befehle mehr übrigbleiben. Damit sind die Defines mit den Texten jetzt einheitlich, und würden es später z.B. Übersetzern, welche mit C++ nichts weiter zu tun haben, einfacher machen.

main.h
#ifndef __main_h__
#define __main_h__

#define SCPPK_STR_HILFE \
"Bitte geben sie 2 Zahlen als Parameter an.\n\
z.B.  Rechne 12 8\n"

#endif


Nachdem das Define in der Headerdatei so geändert wurde, muß der dazugehörige Code in main.cpp natürlich angepaßt werden:

main.cpp
.
.
.

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

  if ( argc != 3 )
  {
    cout << SCPPK_STR_HILFE;
  }
  else
  {

.
.
.


Jetzt lässt sich das Programm wieder kompilieren. Die Funktionsweise des Programms ist exakt die Selbe wie im Kapitel 'Headerdateien'. Die Programmteile sind jedoch besser geordnet, und manche Teile können in anderen Programmen auf einfache Art wiederverwertet werden.

Beim erstellen von mehreren Quellcode-Dateien für ein Programm sollte man folgende Dinge beachten:
Wenn diese Regeln eingehalten werden, und der Quellcode gut kommentiert wird, sollte man selbst in riesigen Projekten immer den Überblick behalten können.
Wenn zudem die Headerdateien gut kommentiert sind, kann man die Funktionen selbst dann noch Problemlos wiederverwerten, wenn man ihre Funktionsweise schon lange vergessen hat.