Einsendung:

Wie rufe ich die Funktion richtig auf?

Bei der Lektion "else dem richtigen if zuordnen" unter dem Link Lösungsvorschlag steht folgende Funktion:

bool istSchaltjahr(int jahr)
{
   bool j;
   if(jahr%100==0)
      if(jahr%400==0)
         j=true;
      else
         j=false;
   else
      if(jahr%4==0)
         j=true;
      else
         j=false;
   return j;
};

Nun hatte ich mir gedacht, es wäre interessant, ein Programm zu haben, das einem sagt, wann ein Schaltjahr ist und wann nicht. Und da ich Anfänger bin, wäre dies vielleicht gleich eine gute Übung, um auf eine Funktion zuzugreifen (weil ich das Zugreifen auf Funktionen noch nicht so gut kann)....
Und kam dann zu folgenden Ergebnis:

#include <iostream.h>

int jahr;
bool j;
bool istSchaltjahr(int);

int main()
{
   cout<<"Geben Sie eine Jahreszahl ein: ";
   cin>>jahr;
   
   // ???
   
   j=istSchaltjahr(jahr);
   
   if(j==true)
      cout<<jahr<<" ist ein Schaltjahr"<<endl;
   else
      cout<<jahr<<" ist kein Schaltjahr"<<endl;
   
   // ???
   
   return 0;
}

bool istSchaltjahr(int jahr)
{
   if(jahr%100==0)
      if(jahr%400==0)
         j=true;
      else
         j=false;
   else
      if(jahr%4==0)
         j=true;
      else
         j=false;
   return j;
};

das Programm läuft zwar (bei richtiger Eingabe), aber ist das auch der beste Weg, um das Problem zu lösen (wenn man die Funktion erhalten will)? Muß man

bool j;

aus der Funktion nehmen? Gibt es da einen anderen Weg?

 Es war nicht der beste Weg. Es war eher der schlechteste. Der Speicher, der verwendet werden muß, um das Rechenergebnis der Funktion zurückzugeben, sollte nur der Funktion (hier der istSchaltjahr-Funktion) und dem Aufrufer (hier der main-Funktion) gehören. Wenn man das über globale Variablen löst (so heißen Variable, die in keinem Block stehen, sondern außerhalb eines jeden Blocks), dann kann einfach jede Funktion diese Werte verändern. Früher oder später wird es zu Konflikten kommen.

Vermeiden Sie globale Variablen!

Um diese Konflikte zu vermeiden, gibt es Rückgabewerte von Funktionen und das Wort "return". Die main-Funktion kennt ja den Typ des Rückgabewertes der istSchaltjahr-Funktion. Vor dem Aufruf reserviert die main-Funktion einfach so viel Speicher, daß die Rückgabe dort hineinpaßt. In der Funktion wird dann beim Wort return in diesen Speicher der Rückgabewert geschrieben. Es ist also fast nichts anderes, als Ihre Version mit der Variablen, nur daß der Speicher automatisch angelegt wird und keinen Namen (also keinen Variablennamen) hat.
Außerdem stört mich Ihre Zeile

bool istSchaltjahr(int);

Besser ist

bool istSchaltjahr(int jahr);

Als Mensch (nicht als Compiler) fällt es mir leichter, den Sinn des Übergabeparameters zu verstehen, wenn ich die Bedeutung kenne. Bei der zweiten Version ist einfach klarer, was der Parameter zu bedeuten hat.
Die gute Lösung lautet also (beachten Sie, daß die istSchaltjahr-Funktion noch die Originalversion ist):

#include <iostream.h>

bool istSchaltjahr(int jahr);

int main()
{
   int jahr;
   bool j;
   cout<<"Geben Sie eine Jahreszahl ein: ";
   cin>>jahr;
   
   j=istSchaltjahr(jahr);
   
   if(j==true)
      cout<<jahr<<" ist ein Schaltjahr"<<endl;
   else
      cout<<jahr<<" ist kein Schaltjahr"<<endl;
   
   return 0;
}

bool istSchaltjahr(int jahr)
{
   bool j;
   if(jahr%100==0)
      if(jahr%400==0)
         j=true;
      else
         j=false;
   else
      if(jahr%4==0)
         j=true;
      else
         j=false;
   return j;
};

Vielleicht ist es jetzt für Sie etwas verwirrend, daß die Variablen j und jahr in verschiedenen Funktionen vorkommen, und dabei sogar jeweils den gleichen Wert haben. Das ist in der Tat verwirrend, und man gewinnt fast den Eindruck, der ganze Aufwand mit Parameterübergabe und return hätte keinen Sinn.

Wenn man die Variablen etwas umnennt, dann kommt das Übergeben der Werte recht deutlich zum Ausdruck.

#include <iostream.h>

bool istSchaltjahr(int uebergabeJahr);

int main()
{
   int jahr;
   bool j;
   cout<<"Geben Sie eine Jahreszahl ein: ";
   cin>>jahr;
   
   j=istSchaltjahr(jahr);
   
   if(j==true)
      cout<<jahr<<" ist ein Schaltjahr"<<endl;
   else
      cout<<jahr<<" ist kein Schaltjahr"<<endl;
   
   return 0;
}

bool istSchaltjahr(int uebergabeJahr)
{
   bool rueckgabeJ;
   if(uebergabeJahr%100==0)
      if(uebergabeJahr%400==0)
         rueckgabeJ=true;
      else
         rueckgabeJ=false;
   else
      if(uebergabeJahr%4==0)
         rueckgabeJ=true;
      else
         rueckgabeJ=false;
   return rueckgabeJ;
};


Falls Ihnen Fehler im Text auffallen oder Sie Verbesserungsvorschläge haben, dann schicken Sie mir bitte eine Mail. Ich werde mich dann sofort darum kümmern.
[aktuelle Version] [inhalt] [index]      [Fehlerkorrektur, Verbesserungsvorschlag]

© Volkard Henkel <volkard@normannia.de>, last update: 08/25/00