Programmieren
 
 
 
 
 
C-Grundkurs
 
 
 
 
 
.. Beispiel: Satz von Pythagoras (mit bedingter Compilierung)
 
 

 
 
 
 
 
Aufgabe:
Diese Version des Programms 'Satz von Pythagoras' wurde so vorbereitet, dass sie durch eine einfache Änderung im Quelltext sowohl für DOS-Rechner als auch für IPC@CHIP-Rechner compiliert werden kann. Die jeweils unterschiedlichen Programmteile werden durch eine bedingte Compilation in das Maschinenprogramm übernommen, oder eben nicht.
Das Geheimnis hierzu sind die Präprozesordirektiven #ifdef, #ifndef, #endif und #define. Das folgende Beispiel zeigt, wie sie zur bedingten Compilation eingesetzt werden können.
 

 

 

 

 


 

// pythagoras.cpp
// --------------  Version 20.11.2007
//                 Model: small
//                 Fliesskommaemulation ein (beim IPC@CHIP)
//                 Schwarzer, www.GoBlack.de

// Funktion zur Berechnung der Hypotenusenlänge nach dem Satz von
// Pythagoras


// Wählen Sie für welchen Rechner DOS oder IPC@CHIP die
// Compilation durchgeführt werden soll. Setzen Sie ..
// #define DOS    .. für DOS-Rechner, und
// #define IPC    .. für IPC@CHIP-Rechner
 
#define DOS                     // Compilation für DOS-Rechner



// Einbinden von Headerdateien mit Bibliotheksfunktionen
#include <conio.h>             // für getch() wenn benötigt
#include <stdio.h>             // für printf()
#include <math.h>              // für sqrt()


// Einbinden einer eigenen Headerdatei, die sich im gleichen
// Verzeichnis wie der Quelltext befindet. Zwischen den
// Gänsefüsschen muss eine Pfadangabe stehen, wenn sich die Datei
// nicht im gleichen Verzeichnis wie der Quelltext befindet.

#include "fstrgin.h"

//                                  fstrgin.h zum Kopieren ansehen
// ===============================================================

// Deklarationen von eigenen Funktionen
double pythagoras(double, double);
void   setStdio  (char kanal);


// Definition der Fkt. pythagoras()
// Berechnet die Länge der Hypotenuse in einem rechtwinkligen
// Dreieck.
// Übergaben: Länge der Katheten a und b
// Rückgabe:  Länge der Hypotenuse

double pythagoras( double a, double b)
{ 
 return(sqrt(a*a + b*b));    // Rückgabe von Wurzel aus a²+b²
}


#ifdef IPC                  // nur übersetzen bei IPC 

// Definition der Fkt. setStdio()
// Schaltet beim IPC@CHIP den Fokus auf dieses Programm, bzw. das
// Betriebssystem. Beispiel Inlineassembler
// Übergabe: Kanal 1,2,3
// Rückgabe: keine

void setStdio (char kanal)
{
  asm { mov ah, 11h         // SoftINT: A0h, Fkt 11h
        mov al, kanal       // nur bei IPC@CHIP
        int 0A0h
      }
}
#endif

// main()
// Testprogramm für die Funktion Pythagoras auf IPC@CHIP Rechnern
// Mit Eingaben über ein Terminalprogramm auf dem PC

void main(void)
{
  double kath1;                 // Deklaration von kath1
  double kath2;                 // Deklaration von kath2
  double hypo;                  // Deklar. Von hypotenuse
  
  #ifdef IPC                    // nur übersetzen bei IPC 
  setStdio(2);                  // Fokus auf dieses Programm
  #endif

  char txtbuf[60];              // ein Textbuffer für 60 Bytes

  printf("\r\nKathete1= ");     // Eingabeaufforderung Kathete1
  fstrgin(txtbuf, 10, FLT,"");  // Eingaben in txtbuf[] sammeln 
  kath1= atof(txtbuf);          // ASCII-Code zu Zahl wandeln

  printf("\r\nKathete2= ");     // Eingabeaufforderung Kathete2
  fstrgin(txtbuf, 10, FLT,"");  // Eingaben in txtbuf[] sammeln 
  kath2= atof(txtbuf);          // ASCII-Code zu Zahl wandeln


  hypo = pythagoras (kath1, kath2);   // Aufruf der Funktion

  printf ("\r\nHypotenuse = %f", hypo);

  #ifdef IPC                    // nur übersetzen bei IPC 
  setStdio(3);                  // Fokus auf das Betriebssystem
  #endif
  
  #ifdef DOS                    // nur übersetzen bei DOS
  getch();                      // auf Tastendruck warten
  #endif
}

 


 

 

Die Ausgabeabfolge des obigen Beispiels sieht wie folgt aus:

Kathete1= _          Eingabe max. 10 Zeichen
Kathete2= _          Eingabe max. 10 Zeichen
Hypotenuse =         Ergebnis

 

 
 
 
 
Bemerkungen
Der IPC@CHIP-Rechner und PC-Computer unterscheiden sich bezüglich ihres Betriebssystems voneinander. Das obige Programm hält Programmteile vor, die für die Lauffähigkeit des Programms auf dem einen bzw. dem anderen Rechnern benötigt werden.
So ist es bei PCs sinnvoll, das DOS-Fenster am Ende des Programms durch eine Tastaturabfrage über getch() geöffnet zu halten, was bei IPC@CHIP -Rechnern nicht notwendig ist.
Die IPC@CHIP -Rechner dagegen sind multitaskfähig und würden Eingaben an ihr Betriebssystem und nicht an das Benutzerprogramm richten, wenn ihr Eingabestrom nicht durch setStdio() auf das Benutzerprogramm umgesschaltet würde.

Durch die Präprozessordirektive #define kann im Kopf des Programms die Definition der Literale DOS oder IPC vorgenommen werden. Diese Definition kann folgend durch #ifdef abgefragt werden.
Ist nun das Literal DOS definiert, betrachtet der Compiler alles was zwischen #ifdef IPC bis #endif steht nicht, und übersetzt weder die Funktion setStdio(), noch deren Aufrufe. Nur bei #ifdef DOS verhält er sich anders. Das Literal DOS wurde ja definiert und der Compiler sieht die Zeile getch(). So übersetzt er sie und das Programm ist in DOS-Fenstern lauffähig.

Wurde IPC definiert drehen sich die Verhältnisse um. Nun wird getch() nicht gesehen, dafür aber alle Programmteile die zur Lauffähigkeit auf dem IPC beitragen.
 
 
 
 
www..de