Neuling braucht Hilfe :P



  • Hey Leute,

    Ich bin ganz neu im Forum, daher hoffe ich mal, dass der Thread hier richtig aufgemacht ist.

    Ich habe ganz frisch angefangen mit C++, indem ich mir erstmal einen 2 Stündigen Youtube Crashkurs angeschaut habe, um überhaupt erstmal zu wissen, ob ich denn wirklich Lust habe mich mit C++ bzw. generell Programmieren zu beschäftigen.

    Habe mir dann einfach mal als Projekt vorgenommen einen Taschenrechner zu programmieren, da man ihn ja mit einer recht einfach Technik, wenn auch nicht so schön, schreiben kann.

    Nun habe ich folgendes Problem vorerst mein Quellcode:

    #include <iostream>
    
    using namespace std;
    
    void addition();
    void subtraktion();
    void division();
    void multiplikation();
    
    int main(void)
    
    {
    	int Auswahl;
    
    		cout<< "Herzlich Willkommen, bitte wählen sie eine der vier Optionen" << endl;
    		cout<< "Addition" << endl;
    		cout<< "Subtraktion" << endl;
    		cout<< "Multiplikation" << endl;
    		cout<< "Division" << endl;
    		cin>> Auswahl;	
    
    	if (Auswahl == 1)								// Hier kommen die if Bedingungen für die Operatoren
    	{
    	void addition();	
    	}
    
    	else if (Auswahl == 2)
    	{
    	void subtraktion();
    	}
    
    	else if (Auswahl == 3)
    	{
    	void multiplikation();
    	}
    
    	else if (Auswahl == 4)
    	{
    	void division();
    	}
    
    	else 
    	{
    	 cout<< "Die Eingabe war leider falsch. Bitte drücken Sie die Zahlen 1-4 für die oben aufgelisteten Optionen!";
    	}
    
    	void addition();												//Hier der Code für die jeweiligen Operatoren
    	{
    	float zahl1, zahl2;
    	cout<< "Geben Sie Zahl 1 ein" << endl;
    	cin>> zahl1;
    	cout<< "Geben Sie Zahl 2 ein" << endl;
    	cin>> zahl2; 
    	cout<<"Das Ergebnis lautet " << zahl1 + zahl2 << endl;
    	}
    
    	void subtraktion();
    	{
    	float zahl1, zahl2;
    	cout<< "Geben Sie Zahl 1 ein" << endl;
    	cin>> zahl1;
    	cout<< "Geben Sie Zahl 2 ein" << endl;
    	cin>> zahl2; 
    	cout<<"Das Ergebnis lautet " << zahl1 - zahl2 << endl;
    	}
    
    	void multiplikation();
    	{
    	float zahl1, zahl2;
    	cout<< "Geben Sie Zahl 1 ein" << endl;
    	cin>> zahl1;
    	cout<< "Geben Sie Zahl 2 ein" << endl;
    	cin>> zahl2; 
    	cout<<"Das Ergebnis lautet " << zahl1 * zahl2 << endl;
    	}
    
    	void division();
    	{
    	float zahl1, zahl2;
    	cout<< "Geben Sie Zahl 1 ein" << endl;
    	cin>> zahl1;
    	cout<< "Geben Sie Zahl 2 ein" << endl;
    	cin>> zahl2; 
    	cout<<"Das Ergebnis lautet " << zahl1 / zahl2 << endl;
    	}
    	cin.sync();
        cin.get();
        return 0;
    
    }
    

    Wenn ich das Programm ausführe klappt soweit alles. Das einzige Problem ist jedoch, dass wenn ich zum Beispiel die Addition eingebe, nach dem Ergebnis sofort die Subtraktion startet und ich wieder eine Zahl eingeben soll.

    Habe bis jetzt nichts gefunden, was die Ursache dafür sein könnte. Wie kann sich der Wert Auswahl in meinem Fall einfach so ändern?

    Und mich würde noch interessieren: Geht mein Quellcode von der Ordentlichkeit so? Oder was kann man besser machen?

    Habt Gnade mit mir. Wie gesagt ich bin ein ganz frischer Neuling 😃

    Vielen Dank,

    Grüße,

    sakamalaka



  • Du hast bei den Funktionsdefinitionen am Ende in main() jeweils ein Semikolon, und damit nicht das was du möchtest.

    Normal ist es aber auch, dass du die Funktionen addition() subtraktion() usw. nicht in main() selbst definierst, sondern außerhalb, hier z.B. korrigiert:

    int main(void)
    {
        int Auswahl;
    
        cout<< "Herzlich Willkommen, bitte wählen sie eine der vier Optionen" << endl;
        ... 
        cin>> Auswahl; 
    
        if (Auswahl == 1)                               // Hier kommen die if Bedingungen für die Operatoren
        {
            void addition();
        }
        else if (Auswahl == 2)
        {
            void subtraktion();
        }
    
        ...
    }
    
    void addition()
    {
        float zahl1, zahl2;
        cout<< "Geben Sie Zahl 1 ein" << endl;
        cin>> zahl1;
        cout<< "Geben Sie Zahl 2 ein" << endl;
        cin>> zahl2;
        cout<<"Das Ergebnis lautet " << zahl1 + zahl2 << endl;
    }
    


  • Huch, das void ist natürlich auch nicht richtig, jetzt aber:

    //Forward-Deklaration
    void addition();
    void subtraktion();
    void division();
    void multiplikation();
    
    int main(void)
    {
        int Auswahl;
    
        cout<< "Herzlich Willkommen, bitte wählen sie eine der vier Optionen" << endl;
        ... 
        cin>> Auswahl; 
    
        if (Auswahl == 1)                               // Hier kommen die if Bedingungen für die Operatoren
        {
            addition();  //Funktionsaufruf
        }
        else if (Auswahl == 2)
        {
            subtraktion(); //Funktionsaufruf
        }
    
        ...
    }
    
    void addition() //Funktionsdefinition
    {
        float zahl1, zahl2;
        cout<< "Geben Sie Zahl 1 ein" << endl;
        cin>> zahl1;
        cout<< "Geben Sie Zahl 2 ein" << endl;
        cin>> zahl2;
        cout<<"Das Ergebnis lautet " << zahl1 + zahl2 << endl;
    }
    
    ...
    


  • Oh man.. Vielen Dank. Das man die Funktionen nicht in die Main schreibt hätte ich mir denken können! das mit dem void wäre mir niemals aufgefallen, aber ist natürlich komplett logisch 😃

    Vielen vielen Dank für die schnelle Antwort.

    Sieht der Quelltext denn so an sich okay geordnet aus oder ist das unzumutbar für einen Informatiker? 😃



  • Unzumutbar 😉

    Mach dich mal über Einrückungsstil schlau: https://de.wikipedia.org/wiki/Einrückungsstil

    Deine Rechenfunktionen unterscheiden sich in einem Zeichen.
    Da kannst du auslagern oder zusammenfassen.

    Versuch mal Funktionen als solche zu benutzen. Denen kann man Werte übergeben und auch zurück bekommen.



  • Das Kernstück Deines Programms ist eine Fallunterscheidung nach der Grundrechenart. Noch präziser: das Einzige, worin sich Deine Funktionen addition(), subtraktion() usw. voneinander unterscheiden, ist die auf zahl1 und zahl2 ausgeführte Operation. Schau Dich nach den Schlüsselwörtern switch und case um (und default und break); das wird Deinen Code stark vereinfachen.

    Allgemein gilt: Wann immer Du denselben Code mehrfach schreibst (bzw. kopierst und einfügst), gibt es einen Weg, ihn zu verkürzen.

    Dein Design ist prozedural und erinnert eher an C als C++.

    Ideal wäre, den Benutzer so lange Zahlen (oder irgendwelche Zeichenketten wie "asdf") eingeben zu lassen, bis er eine im Sinne Deines Programms gültige Auswahl trifft. Stichwort: Schleife als Kontrollstruktur. Schlüsselwörter: while, do-while, for. Welcher Schleifentyp ist hier optimal?

    cin.sync() solltest Du zumindest so, wie Du es in den Code eingebaut hast, nicht benötigen.

    Ich schätze, cin.get() verwendest Du, um Die Konsole offenzuhalten? Öffne stattdessen lieber gesondert ein Konsolenfenster und führe Dein Programm darin aus. Ich weiß noch, dass man das in früheren Windows-Versionen recht bequem via Rechtsklick bei gedrückt gehaltener Shift-Taste im Explorer auswählen konnte: "Kommandozeile öffnen" o.Ä. Die Konsole sollte Dir dann nicht mehr unterm Hintern wegflutschen, sobald die Ausführung des Programms beendet ist.

    Alternativ kannst Du Dir zum Entwickeln eine IDE anschaffen, die hält Dir meiner Erfahrung nach die Konsole von sich aus offen.

    Als weiterführende Aufgabe, die Du aber derzeit noch ruhig zurückstellen kannst, empfehle ich Dir, einen Taschenrechner nach umgekehrt polnischer Notation zu programmieren.



  • Vielen Dank für die beiden Antworten!

    @DirkB werde ich mir auf jeden Fall anschauen und versuchen umzusetzen. Wird dann ja doch ganz anders gemacht.^^

    @Shamshir vielen Dank erstmal für den allgemeinen Tipp, sowas ist gut zu wissen!
    In dem Tutorial kamen auch switch und case dran, ich denke damit kriege ich auch endlich meine umsetzung hin, dass der Benutzer direkt 5 / 4 eingeben kann und es als Division erkannt wird oder?
    Ich wollte allerdings erstmal mit if und else anfangen einfach um Quellcode zu schreiben und die Notationen der jeweiligen Befehle zu verinnerlichen.

    Im Endeffekt ist dein Beitrag perfekt für mich, da mein Ziel ist, den Taschenrechner immer weiter zu optimieren, was den Quellcode und die Benutzung angeht. Ich denke so habe ich den größten Lernerfolg aus solch einem Projekt.

    cin.sync() habe ich gelernt ist dafür da, dass nach der cin zahl2 eingabe das Enter drücken wieder gelöscht wird, da es sonst noch in einem Zwischenspeicher ist und cin.get() auslösen kann. Deshalb habe ich es dort reingeschrieben.^^

    cin.get() verwende ich so wie du es vermutet hast. Das ist auch ein guter Tipp, werde ich versuchen!

    Polnische Notation werde ich mir auf jeden Fall irgendwann anschauen, wenn ich den Taschenrechner so fertig habe, dass ich zufrieden bin!

    Vielen Dank für die Beiträge! Haben mir sehr geholfen! 🙂



  • sakamalaka schrieb:

    Polnische Notation werde ich mir auf jeden Fall irgendwann anschauen, wenn ich den Taschenrechner so fertig habe, dass ich zufrieden bin!

    Nenene,

    sakamalaka schrieb:

    umgekehrt polnischer Notation

    und das solltest du dir durchaus mal vorher ansehen.
    Das macht die Umsetzung um einiges leichter.
    Die Bedienung davon ist etwas gewöhnungsbedürftig, aber in Forschung/Entwicklung durchaus gängig.



  • sakamalaka schrieb:

    In dem Tutorial kamen auch switch und case dran, ich denke damit kriege ich auch endlich meine umsetzung hin, dass der Benutzer direkt 5 / 4 eingeben kann und es als Division erkannt wird oder?

    Das ist noch etwas komplizierter. switch-case ist grundsätzlich nur die Vereinfachung einer verschachtelten if/else-if/.../else-Fallunterscheidung, die Du als solche schon richtig angewandt hast.

    Die Eingabe des Benutzers solltest Du Dir als endliche Zeichenkette von nicht vorhersehbarer Länge vorstellen. Diese Zeichenkette müsste Dein Taschenrechner messerscharf zerlegen, sodass jede Teilkette in eine von vier Kategorien fällt: Zahl (Operand), Operator, Leerzeichen und Quark. (Einen Ausdruck, der Quark enthält, bräuchte sich der Taschenrechner z.B. nicht einmal genauer anschauen.) Das gelänge Dir z.B. mit Stringstreams; das ist aber schon ein etwas fortgeschritteneres Thema als z.B. Schleifen.

    Eine weitere Komplikation ergäbe sich aus der Priorität von Operatoren ("Punkt- vor Strichrechnung") und arithmetischen Klammern: eine ganze Menge Terme kannst Du nicht einfach von links nach rechts schnurgerade durcharbeiten. Und wie erkennst Du, ob alle Klammern ordnungsgemäß wieder geschlossen wurden usw.? -- Das grenzt schon an erste Übungen, einen C++-Compiler zu schreiben (Stichwort: formale Grammatik). 🤡 -- Unter anderem auch daher meine Empfehlung mit der umgekehrten polnischen Notation, bei der dieses Problem nicht auftritt.



  • @Shamshir

    Das gelänge Dir z.B. mit Stringstreams; das ist aber schon ein etwas fortgeschritteneres Thema als z.B. Schleifen.

    Ist verständlich und da lasse ich erstmal die Finger von! 😃 Und auch die Komplikation mit größeren Termen traue mir noch lange nicht zu, alleine zu bewältigen 😃

    Switch + cases habe ich gestern ziemlich schnell einführen können und diese funktionieren auch einwandfrei!

    Ideal wäre, den Benutzer so lange Zahlen (oder irgendwelche Zeichenketten wie "asdf") eingeben zu lassen, bis er eine im Sinne Deines Programms gültige Auswahl trifft. Stichwort: Schleife als Kontrollstruktur. Schlüsselwörter: while, do-while, for. Welcher Schleifentyp ist hier optimal?

    Bezüglich der Kontrollschleife habe ich mir ebenfalls Gedanken gemacht und es lange mit einer while Schleife probiert. Habe mich am Ende allerdings von der Theorie dafür entschieden eine do/while Schleife an den Anfang zu setzen, bis eine der 4 Optionen gewählt wird.

    do{
    		cout<< "Herzlich Willkommen, bitte wählen sie eine der vier Optionen" << endl;
    		cout<< "1 -> Addition" << endl;
    		cout<< "2 -> Subtraktion" << endl;
    		cout<< "3 -> Multiplikation" << endl;
    		cout<< "4 -> Division" << endl;
    		cin>> Auswahl;	
    	  } 
    while ( Auswahl <1 && Auswahl >4);
    

    Allerdings habe ich wohl irgendwo einen Denkfehler, da diese Schleife nicht so lange ausgeführt wird bis eine der Zahlen 1-4 gewählt wird.

    Ich denke es ist relativ zwecklos weiter zu machen ohne mir erstmal ein Buch über c++ oder so zu holen, da ich merke, dass es bei mir an vielen kleinen Dingen hackt.

    Genauso habe ich versucht die Funktionen
    so zu ändern, dass nicht in jeder Funktion Zahlen eingegeben werden müssen, sondern man einmal in der main die zahlen eingibt.

    Allerdings sind dort genauso kleine Probleme aufgetreten, die ich mir nicht erklären kann.

    Ich könnte die Liste jetzt noch ein wenig weiter führen, aber ich merke, dass mir doch noch einige Sachen in den Grundlagen fehlen(z.B. wann benutze ich welchen Datentyp, wieso erkennt das Programm bei einem float keine Kommazahlen, usw.).^^



  • du musst auch schreiben

    while(auswahl<'1'&&auswahl>'4')
    

    . oder du gibst dem cin bekannt, dass du ausdrücklich eine zahl einlesen willst.

    Ich denke es ist relativ zwecklos weiter zu machen ohne mir erstmal ein Buch über c++ oder so zu holen, da ich merke, dass es bei mir an vielen kleinen Dingen hackt.

    doppelt unterstrichen und fett gedruckt! ich würde dir c/c++ von ulrich kaiser empfehlen, weil da echt gute übungsaufgaben drin sind, die es z.t. sehr in sich haben.



  • Logik-Fehler:

    while(auswahl<1 && auswahl>4)
    

    ergibt immer 'false' 😉



  • HansKlaus schrieb:

    ich würde dir c/c++ von ulrich kaiser empfehlen,

    An einem Buch mit "C/C++" im Titel würde ich doch große Zweifel haben.



  • manni66 schrieb:

    HansKlaus schrieb:

    ich würde dir c/c++ von ulrich kaiser empfehlen,

    An einem Buch mit "C/C++" im Titel würde ich doch große Zweifel haben.

    der titel soll vermutlich aussagen, dass in dem buch sowohl c als auch c++ behandelt wird. jedenfalls denke ich, dass es zumindest für den einstieg sehr gut geeignet ist.
    dass theoretische informatiker mit schwerpunkt weiterentwicklung von c oder c++ oder leute, die etwas aus dem compiler "herauskitzeln" wollen, ihre freude daran haben werden, bezweifle ich allerdings auch.
    ist halt mehr was für die praxis und zum "losprogrammieren", weil da die wichtigsten anwendungsfälle der programmierung behandelt werden, für alles andere gibts dann bestimmt wirklich bessere bücher.



  • HansKlaus schrieb:

    der titel soll vermutlich aussagen, dass in dem buch sowohl c als auch c++ behandelt wird. jedenfalls denke ich, dass es zumindest für den einstieg sehr gut geeignet ist.

    Ja, es ist so ein typisches "erst C, dann C++" Buch und daher gerade als Einstieg völlig ungeeignet.



  • naja man lernt damit halt das programmieren.
    andere bücher erklären alles ganz toll und bieten dann keine möglichkeit, das gelernte durch übungen zu verfestigen. vielleicht auch nicht unbedingt besser.



  • Was man nicht gelernt hat, kann man auch nicht in Übungen verfestigen.



  • das stimmt.
    aber eine frei programmierbare enigma, die ihre einstellungen auf der platte speichert und wieder abruft (wahllos herausgegriffene übungsaufgabe aus dem buch) ist etwas für das man nicht unbedingt die neuen elemente aus c++ 14 gegenüber bspw. c++ 06 braucht, die grundsätzlichen methoden der programmierung sollte man dafür aber schon beherrschen, und die bekommt man in dem buch dann doch beigebracht.



  • 1. Wenn man jetzt anfängt zu lernen sollte es auch aktuelles C++ sein
    2. es sollte C++ und nicht C sein



  • das ist eine übungsaufgabe aus dem c++-teil, genau genommen aus dem teil, in dem eine einführung in klassen stattfindet. mit vererbung ging es also noch gar nicht los.

    aber das buch war ja auch nur meine empfehlung. 😉

    edit: mein prof hat uns zu anfang des semesters erzählt, dass wir c++ 06 lernen würden (c++ 11 ist ein wahlmodul für besonders interessierte), weil in den meisten unternehmen aus kostengründen weiterhin mit 06 programmiert wird und das auch erst einmal eine weile so bleiben wird, und der umstieg auf 11 oder 14 dann nicht sooo wild ist. 🙄


Anmelden zum Antworten