Funktionsprobleme eines kleinen Programms...



  • Moin,

    habe ein kleines winziges Programm geschrieben, welches die Flächenberechnung eines Quadrates und eines Rechtecks, sowie die Volumenberechnung eines Würfels ausführt.

    Es ist eine Win32-Konsolenanwendung und wurde in Microsoft Visual C++ 6.0.

    Und zwar habe ich folgendes Performance Problem, sofern man es dies als solches bezeichnen kann. Sobald ich den Benutzer abfrage, ob er einen weiteren durchlauf des programms wünscht oder einen sofortigen abbruch, muss es dieser erst immer zweimla hintereinander eingeben, bevor das Programm in seiner Funktion weiterspringt.

    Könnt Ihr mir an Hand des Codes mögliche Lösungsvorschläge leifern?

    // Programm liest die zu berechnenden Daten von der Tastatur ein
    // Man kann durch die Anwahl verschiedener Menuepunkte 
    // seine beliebige Berechnung heraussuchen
    
    #include <iostream.h>
    
    // Die zu berechnenden Variablen
    
    float hoehe   = 0.0f;
    float breite  = 0.0f;
    float laenge  = 0.0f;
    float flaeche = 0.0f;
    float volumen = 0.0f;
    
    // Steuerzeichen wurde durch Eingabe von NZ = NeueZeile ersetzt
    
    const char NZ = '\n';
    
    // Funktionsprototypen fuer die verschiedenen Aktionen waehrend des
    // Programmablaufs
    
    char Menueanwahl(void);
    float hoeheEinlesen(void);
    float breiteEinlesen(void);
    float laengeEinlesen(void);
    float quadratBerechnung(float breite);
    float rechteckBerechnung(float breit, float laenge);
    float volumenBerechnung(float breite, float hoehe);
    void Ausgabe1(float flaeche);
    void Ausgabe2(float flaeche);
    void Ausgabe3(float volumen);
    bool Fortsetzen(void);
    
    // Hauptprogrammdurchlauf beginnend mit Anwahl der verschiedenen
    // Menuepunkte
    
    void main(void)
    {
    	cout << "Welche Berechnung moechten Sie durchfuehren lassen?" << NZ;
    
    	cout << "<1> Flaechenberechnung eines Quadrates"              << NZ;
    
    	cout << "<2> Flaechenberechnung eines Rechteckes"             << NZ;
    
    	cout << "<3> Volumenberechnung eines Wuerfels"                << NZ;
    
    	do
    	{
    		Menueanwahl();
    	}
    	while(Fortsetzen());
    }
    
    // Funktionsaufrufe
    
    char Menueanwahl(void)
    {
    	int Eingabe;
    
    	cout << "Geben Sie einen der Menuepunkte durch Eingabe einer Zahl an." << NZ;
    
    	cin  >> Eingabe;
    
    	if(Eingabe == 1)
    	{
    		breite = breiteEinlesen();
    		flaeche = quadratBerechnung(breite);
    		Ausgabe1(flaeche);  
    	}
    	if(Eingabe == 2)
    	{
    		breite = breiteEinlesen();
    		laenge = laengeEinlesen();
    		flaeche = rechteckBerechnung(breite, laenge);
    		Ausgabe2(flaeche);
    	}
    	if(Eingabe == 3)
    	{
    		breite = breiteEinlesen();
    		hoehe  = hoeheEinlesen();
    		volumen = volumenBerechnung(breite,hoehe);
    		Ausgabe3(volumen);
    	}
    	if(Eingabe > 3)
    	{
    		cout << "Sie haben keinen gueltigen Menuepunkt angewaehlt, bitte versuchen Sie es nochmal." << NZ;
    
    		return Menueanwahl();
    	}
    	if(Eingabe < 1)
    	{
    		cout << "Sie haben keinen gueltigen Menuepunkt angewaehlt, bitte versuchen Sie es nochmal." << NZ;
    
    		return Menueanwahl();
    	}
    
    	return Fortsetzen();
    }
    
    float breiteEinlesen(void)
    {
    	cout << "Bitte geben Sie die Seitenlaenge in cm an." << NZ;
    
    	cin  >> breite;
    
    	return breite;
    }
    
    float hoeheEinlesen(void)
    {
    	cout << "Bitte geben Sie die Hoehe in cm an." << NZ;
    
    	cin  >> hoehe;
    
    	return hoehe;
    }
    
    float laengeEinlesen(void)
    {
    	cout << "Bitte geben Sie die Laenge in cm an." << NZ;
    
    	cin  >> laenge;
    
    	return laenge;
    }
    
    float quadratBerechnung(float breite)
    {
    	return breite * breite;
    }
    
    float rechteckBerechnung(float breite, float laenge)
    {
    	return breite * laenge;
    }
    
    float volumenBerechnung(float breite, float hoehe)
    {
    	return breite * breite * hoehe;
    }
    
    void Ausgabe1(float flaeche)
    {
    	cout << "Die Flaeche betraegt " << flaeche << "quadratzentimeter." << NZ;
    }
    
    void Ausgabe2(float flaeche)
    {
    	cout << "Die Flaeche betraegt " << flaeche << "quadratzentimeter." << NZ;
    }
    
    void Ausgabe3(float volumen)
    {
    	cout << "Das Volumen betraegt " << volumen << "kubikzentimeter." << NZ;
    }
    
    bool Fortsetzen(void)
    {
    	char JaNein ='j';
    
    	cout << "Weitere Berechnung durchfuehren?" << NZ;
    
    	cin  >> JaNein;
    
    	if('j' == JaNein)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    

    MfG
    casual



  • Mache folgendes:

    char Menueanwahl(void) // statt char void nehmen
    {
        int Eingabe;
    ....
        if(Eingabe > 3) 
        { 
    ...
            return Menueanwahl(); // return entfernen
        } 
        if(Eingabe < 1) 
        { 
    ...
            return Menueanwahl(); // return entfernen
        } 
    
        return Fortsetzen(); // Diese Zeile entfernen
    }
    


  • Außerdem sollte Menueanwahl sich nicht selbst aufrufen. Mach das mit einer Schleife.



  • Hallo,

    bin absoluter Neuling bei C++, also entschuldigt meine eventuelle unwissenheit 😉

    Warum wird denn die Menüauswertung nicht mit Switch/Case gemacht?
    Wäre das nicht praktischer?



  • Moin,

    also für mich sah der Aufwand ob nun case/switch Variante oder die der if Schleife gleich aus. Theoretisch hätte ich es natürlich auch damit lösen können.

    Danke schon mal an alle Antworten. Werde gleich mal die vorgeschlagene Modifikation einbauen...

    MfG
    casual



  • Moin,

    danke für den Vorschlag, funktioniert prima. Hatte nur einen Denkfehler und dabei etwas nicht beachtet.

    MfG
    casual



  • Also ich bin auch anfänger...aber das was ich bei dir grad gesehen hab ist, vielleicht finde nur ich das so,total schlechter Stil...
    Ich verstehe nicht warum du das nicht in eine klasse packst,und die Funktionen inline proggst...Es wird viel übersichtlicher,vorallem würde ich lieber switch/case für die Tastaturabfrage benutzen,und einen Destruktor kannst du für deine Ausgaben benutzen...Aber ich bin ja nur ein anfänger.vielleicht sehen die profis das etwas anders...



  • Und noch was...wer verwendet heute noch <iostream.h> woher hast du das denn?



  • Ich verstehe nicht warum du das nicht in eine klasse packst,und die Funktionen inline proggst...Es wird viel übersichtlicher,vorallem würde ich lieber switch/case für die Tastaturabfrage benutzen,und einen Destruktor kannst du für deine Ausgaben benutzen.

    @c++anfänger.: zeig doch mal konkret, wie du das machen würdest, damit wir alle etwas lernen. 😋



  • @c++anfänger:

    kannst ja alles in klassen packen und dann eine abstrakte basisklasse machen, von der du alle anderen klassen ableitest... dann kannste ja die abgeleiteten klassen durch basisklassenzeiger dynamisch machen.... zu guter letzt kannste ja dann noch die operatoren überladen... 😉

    die frage ist nur, ob casual das dann auch versteht!!! 🙄

    P.S.: Zeig uns doch mal deinen Stil... dann können mal die anderen dazu was sagen... 🕶



  • c++anfänger. schrieb:

    und einen Destruktor kannst du für deine Ausgaben benutzen...

    ???



  • interpreter schrieb:

    c++anfänger. schrieb:

    und einen Destruktor kannst du für deine Ausgaben benutzen...

    ???

    zu übersichtlich, gell?
    besser, man baut ein drittel der programmlogik in den copy-ctor einer excpetion-klasse und wirft die, sobald man eine primzahl über 1.0e9 findet. das zweite drittel stopft man in einen unexpected_handler, den man beizeiten aufrufen läßt, und den rest in einen new_handler, den man ja auch ganz leicht aufrufen lassen kann. je nach compiler kann man auch noch den pure virtual function call überladen und profiling stubs benutzen. um das menu jederzeit anzeigen zu können, bietet sich SEH (windows) an, mit nem handler, der auf division by zero reagiert und nach der menuanzeige direkt nach der aufrufstelle fortfährt. eingaben läßt man von nem schutzverletzungshandler erledigen und schreibt eingaben in ne globale variable.



  • Tach auch

    @volkard: Sach ma guter Mann sprechen sie unsere Sprache ? 😉
    Hab kein Wort verstanden 😮 ..... die Zeit möchte ich auch noch mal erleben wo ich sowas voll und ganz nachvollziehen kann. 😡
    Wie lange proggst du eigendlich schon ?

    cu



  • Moin,

    @ c++ anfänger: Klassen kann ich noch nicht Programmieren,tut mir echt leid, 🙄 das mit den isotream.h kann man auch anders machen, aber lass mich doch ersteinmal anfangen zu programmieren, dann kannste weiter meckern. Und wie du schon sagtest bist du auch anfänger, ich vielleicht noch ein bissel mehr, also bleibe mal ein bisschen auf dem Teppich. Denn ich erwarte wie jeder andere konstruktive kritik sei sie nun postov oder negativ. Bloß der Ton macht die Musik. Naja...

    @ Die Anderen, falls ich noch weitere Fragen dazu habe melde ich mich, ansonsten danke an alle Tipps bisher...

    @ leech: Hast vollkommen recht, würde es wohl zur Zeit nicht verstehen...

    MfG
    casual



  • @casual:Hey!,Tut mir leid wenn du noch nicht soweit bist...Ich wollt dich ja auch nicht dumm anmachen deswegen...Es tut mir leid,bin selber noch anfänger.

    #include <iostream>
    using namespace std;
    
    class Tuewas
    {
    private: 
      float eigenschaft1;
      float eigenschaft2;
      float eigenschaft3;
    public:
      void methode1(void)
      {}//Inline Funktion definieren
      void methode2(void)
      {}//Inline Funktion definieren
      float methode3(void);//Deklaration des Funtionsprototypen...
      Tuewas(float eigenschaft1=1,float eigenschaft2=2);//Konstruktor vars Initialisieren
      ~Tuewas(void);//Destruktor  
    };
    int main()
    {
    Tuewas tu;//ojekt tu vom typ Tuewas
    
    tu.methode3();
    }
    //Funktionsdefinitionen
    float Tuewas::methode3(void)
    {//funktionsdef.//}
    
    Tuewas::~Tuewas(void)//Destruktor
    {
    cout <<"Ausgabe1";
    cout <<"AUSGABE2";
    }
    

    Das war ein grobes Beispiel einer Inlineklasse...



  • Was ist denn das:

    **```cpp
    Tuewas(float eigenschaft1=1,float eigenschaft2=2);//Konstruktor vars Initialisieren

    Jetzt sagt mir nicht das sowas echt geht 😮



  • erstaunter schrieb:

    Was ist denn das:

    **```cpp
    Tuewas(float eigenschaft1=1,float eigenschaft2=2);//Konstruktor vars Initialisieren

    Jetzt sagt mir nicht das sowas echt geht 😮

    Wieso soll es so nicht gehen?Du kannst deine privaten Eigenschaften nur mit Methoden initialisieren...(so habs ich jedenfalls bis jetzt gelernt)und der Konstruktor ist eine Methode oder nicht? 🙂


Anmelden zum Antworten