Beispiel 11: römischer Taschenrechner II

24.10.2016 01:31 Uhr
#include <iostream>

using namespace std;


int liesRoemisch();

int main()
{
int zahl1, zahl2, resultat, aktiv;
char aktion;

aktiv=1;
while (aktiv==1)
   {
   cout << "Bitte geben Sie eine römische Zahl ein: ";
   zahl1=liesRoemisch();
   
   cout << "Bitte geben Sie noch eine römische Zahl ein: ";
   zahl2=liesRoemisch();

   cout << "Was soll damit geschehen?" << endl << "(+-*/)" << endl;
   cin >> aktion;

   switch(aktion)
      {
   case '+':
      resultat=zahl1 + zahl2;
      break;
   case '-':
      resultat=zahl1 - zahl2;
      break;
   case '*':
      resultat=zahl1 * zahl2;
      break;
   case '/':
      resultat=zahl1 / zahl2;
      break;
   default:
      cout << "Was meinen Sie mit '" << aktion << endl << "'?" << endl;
      }

   cout << "Das Ergebnis lautet: " << resultat << endl;

   if (zahl1 == 0) aktiv=0;
   }

return 0;
}

int liesRoemisch(void)
{
char roemisch[10];
char roemischeZiffern[8] = "ivxlcdm";
int ziffernWert[7] = {1, 5, 10, 50, 100, 500, 1000};
int arabisch[10], stellen, resultat;
int j;

cin >> roemisch;
if (roemisch[0]=='0') return 0;

for (stellen=0; roemisch[stellen]!='\0'; stellen++)
    {
    for (j = 0; j < 7; j++)
        if (roemisch[stellen] == roemischeZiffern[j])
           {
           arabisch[stellen] = ziffernWert[j];
           break;
           }
    if (j == 7)
       cout << "Fehler!" << endl <<

               "In Ihrer Eingabe " << roemisch << " ist " << roemisch[stellen] <<
               " keine römische Ziffer.";
    }

for (j=1; j < stellen; j++)
    if (arabisch[j] > arabisch[j-1])
       {
       arabisch[j] -= arabisch[j-1];
       arabisch[j-1] = 0;
       }

resultat=0;
for (j=0; j < stellen; j++) resultat += arabisch[j];

return resultat;
}

Es ist wahrscheinlich offensichtlich, wieso die hier vorgestellte Lösung effektiver (und wesentlich besser lesbar) ist.

Funktionen

Wir merken uns zum Abschluß der zweiten Stunde:

  1. Ein Programm, das in C++ geschrieben ist, hat stets eine Funktion namens main, die aktiviert wird, wenn ein Benutzer das Programm auf dem Rechner aktiviert.
  2. Diese „Hauptfunktion“ hat aber ihrerseits das Recht, beliebig viele weitere Funktionen aufzurufen, die jeweils ganz bestimmte Aufgaben erfüllen.
  3. Man teilt ein Programm immer dann in mehrere Funktionen, wenn:
    • Eindeutig definierte Aufgaben immer wieder erfüllt werden müssen (wandle eine römische in eine arabische Zahl um).
    • Ein Programm unübersichtlich wird, weil Schleifen zu tief geschachtelt werden müssen oder Programmteile zu lang sind.

Ein Programm, das nicht am Bildschirm gelesen werden kann, sondern gedruckt werden muß um verstanden zu werden, ist nicht wirklich professionell.


#include <iostream>

using namespace std;


int liesRoemisch(void);

int main()
{
int zahl1, zahl2, resultat, aktiv;
char aktion;

aktiv=1;
while (aktiv==1)
   {
   cout << "Bitte geben Sie eine römische Zahl ein: ";
   zahl1=liesRoemisch();
   
   cout << "Bitte geben Sie noch eine römische Zahl ein: ";
   zahl2=liesRoemisch();

   cout << "Was soll damit geschehen?" << endl << "(+-*/)" << endl;
   cin >> aktion;

   switch(aktion)
      {
   case '+':
      resultat=zahl1 + zahl2;
      break;
   case '-':
      resultat=zahl1 - zahl2;
      break;
   case '*':
      resultat=zahl1 * zahl2;
      break;
   case '/':
      resultat=zahl1 / zahl2;
      break;
   default:
      cout << "Was meinen Sie mit '" << aktion << endl << "'?" << endl;
      }

   cout << "Das Ergebnis lautet: " << resultat << endl;

   if (zahl1 == 0) aktiv=0;
   }

return 0;
}

int liesRoemisch(void)
{
char roemisch[10];
char roemischeZiffern[8] = "ivxlcdm";
int ziffernWert[7] = {1, 5, 10, 50, 100, 500, 1000};
int arabisch[10], stellen, resultat;
int j;

cin >> roemisch;
if (roemisch[0]=='0') return 0;

for (stellen=0; roemisch[stellen]!='\0'; stellen++)
    {
    for (j = 0; j < 7; j++)
        if (roemisch[stellen] == roemischeZiffern[j])
           {
           arabisch[stellen] = ziffernWert[j];
           break;
           }
    if (j == 7)
       cout << "Fehler!" << endl <<

               "In Ihrer Eingabe " << roemisch << " ist " << roemisch[stellen] <<
               " keine römische Ziffer.";
    }

for (j=1; j < stellen; j++)
    if (arabisch[j] > arabisch[j-1])
       {
       arabisch[j] -= arabisch[j-1];
       arabisch[j-1] = 0;
       }

resultat=0;
for (j=0; j < stellen; j++) resultat += arabisch[j];


return resultat;
}

Return

Inhaltlich ersetzt der Wert, den eine Funktion mit Hilfe der Returnanweisung an das aufrufende Programm zurückgibt, den Namen der Funktion an der Stelle, an dem sie durch Nennung ihres Namens, gefolgt von einem Klammerpaar, aufgerufen wird.


#include <iostream>

using namespace std;


int liesRoemisch(void);

int main()
{
int zahl1, zahl2, resultat, aktiv;
char aktion;

aktiv=1;
while (aktiv==1)
   {
   cout << "Bitte geben Sie eine römische Zahl ein: ";
   zahl1=liesRoemisch();
   
   cout << "Bitte geben Sie noch eine römische Zahl ein: ";
   zahl2=liesRoemisch();

   cout << "Was soll damit geschehen?" << endl << "(+-*/)" << endl;
   cin >> aktion;

   switch(aktion)
      {
   case '+':
      resultat=zahl1 + zahl2;
      break;
   case '-':
      resultat=zahl1 - zahl2;
      break;
   case '*':
      resultat=zahl1 * zahl2;
      break;
   case '/':
      resultat=zahl1 / zahl2;
      break;
   default:
      cout << "Was meinen Sie mit '" << aktion << endl << "'?" << endl;
      }

   cout << "Das Ergebnis lautet: " << resultat << endl;

   if (zahl1 == 0) aktiv=0;
   }

return 0;
}


int liesRoemisch(void)
{
char roemisch[10];
char roemischeZiffern[8] = "ivxlcdm";
int ziffernWert[7] = {1, 5, 10, 50, 100, 500, 1000};
int arabisch[10], stellen, resultat;
int j;

cin >> roemisch;
if (roemisch[0]=='0') return 0;

for (stellen=0; roemisch[stellen]!='\0'; stellen++)
    {
    for (j = 0; j < 7; j++)
        if (roemisch[stellen] == roemischeZiffern[j])
           {
           arabisch[stellen] = ziffernWert[j];
           break;
           }
    if (j == 7)
       cout << "Fehler!" << endl <<
               "In Ihrer Eingabe " << roemisch << " ist " << roemisch[stellen] <<

               " keine römische Ziffer.";
    }

for (j=1; j < stellen; j++)
    if (arabisch[j] > arabisch[j-1])
       {
       arabisch[j] -= arabisch[j-1];
       arabisch[j-1] = 0;
       }

resultat=0;
for (j=0; j < stellen; j++) resultat += arabisch[j];

return resultat;
}

Regeln für Funktionen

Für die Verwendung von Funktionen gelten folgende formalen Regeln:

  1. Eine Funktion muß vor Ihrer Verwendung deklariert werden. Dazu wird, genau wie bei einer Variablendefinition, zunächst der Datentyp des Werts angegeben, den die Funktion zurückgibt. Auf den Funktionsnamen folgt ein Klammerpaar, zwischen dem beschrieben wird, welche „Argumente“ die Funktion akzeptiert (was uns demnächst näher beschäftigen wird). Steht dort das Schlüsselwort „void“, heißt dies, daß die Funktion keine Argumente akzeptiert. Wie jede Deklaration wird auch die einer Funktion durch ein Semicolon abgeschlossen.
  2. Bei ihrer Verwendung wird der Name der Funktion genauso geschrieben, wie bei Ihrer Deklaration – und zwischen den Klammern müssen Parameter stehen, die mit der Deklaration übereinstimmen. Stand dort „void“, muß das Klammerpaar leer bleiben.
  3. Bei ihrer Definition werden zunächst die Angaben aus der Deklaration wiederholt; an Stelle des schliessenden Semicolon steht hier jetzt jedoch ein Paar geschweifter Klammern, zwischen denen der Rumpf der Funktion steht.