[C++]Brauch Hilfe bei Funktionen



  • Hey Leute,

    ich habe gerade erst angefangen zu programmieren und habe grad Probleme mit einer Funktion.

    Ich habe das Problem, dass ich nicht weiß wie ich die Funktion iHighscoretest bei case s einfügen soll.

    Ich habe beides mit // Problem mit Funktion markiert.

    Ich hoffe ihr könnt mir weiterhelfen.

    Wenn ihr auch noch Lust habt mir zu schreiben was man einfacher oder besser schreiben kann bin ich gerne für Vorschläge offen.

    MfG Tamen

    #include <iostream>
    #include <Windows.h>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    using namespace std;
    
    #pragma comment (lib, "winmm.lib")
    int iSpielen (int iLevel);
    int iHighscoretest(int iHighscore[20], int Punkte);
    int main()
    {
    	char cAuswahl;
    	int iLevel = 5;
    	int i = 0;
    	int z = 1;
    	int Zähler = 0;
    	int iHighscore[20];
    	string h;
    	srand (timeGetTime ());
    
    		iHighscore[0] = 0;
    		iHighscore[1] = 0;
    		iHighscore[2] = 0;
    		iHighscore[3] = 0;
    		iHighscore[4] = 0;
    		iHighscore[5] = 0;
    		iHighscore[6] = 0;
    		iHighscore[7] = 0;
    		iHighscore[8] = 0;
    		iHighscore[9] = 0;
    		iHighscore[10] = 0;
    		iHighscore[11] = 0;
    		iHighscore[12] = 0;
    		iHighscore[13] = 0;
    		iHighscore[14] = 0;
    		iHighscore[15] = 0;
    		iHighscore[16] = 0;
    		iHighscore[17] = 0;
    		iHighscore[18] = 0;
    		iHighscore[19] = 0;
    
    ifstream lesen("Highscore.txt");
    
    	if(lesen.is_open())
    	{
    		while(lesen.good())
    		{
    
    				getline(lesen,h);
    				stringstream Str;
    				Str << h;
    				double d;
    				Str >> d;
    				iHighscore[i] = d;
    
    				++i;
    				++Zähler;
    
    		}
    		i = 0;
    		Zähler = 0;
    	}
    
    	Menue:
    	cout <<"Hauptmenue - Zahlenraten" << endl;
    	cout <<"                        " << endl;
    	cout <<"[S]: Neues Spiel starten" << endl;
    	cout <<"[L]: Level wechseln		" << endl;
    	cout <<"[H]: Highsocore anzeigen" << endl;
    	cout <<"[B]: Spiel beenden		" << endl;
    
    	cin >> cAuswahl;
    
    	switch(cAuswahl)
    	{
    		case 'S':
    		case 's':
    		{
    			int test;
    			int Punkte;
    			cout <<"Ein neues Spiel in Level " << iLevel <<" wird                     gestartet" << endl;
    			Punkte = iSpielen(iLevel);
    
    ////////////////////////////////////////////////////////////////////////////
    // Problem mit Funktion
                            iHighscoretest(iHighscore[20], Punkte);
    
    		Zähler=0;
    		i=0;
    
    		}break;
    
    		case 'L':
    		case 'l':
    		{	
    			system("cls");
    			cout << "Wähle ein Level für dein nächstes Spiel aus." << endl;
    			cout << "Dein derzeitiges Level ist: " << iLevel << endl;
    			cin >> iLevel;
    			getchar();
    			cout << "Du hast dein Level auf " << iLevel <<" geändert" << endl;
    			getchar();
    
    			system("cls");
    			goto Menue;
    
    		}break;
    
    		case 'H':
    		case 'h':
    		{
    
    			system("cls");
    			getchar();
    			cout <<"Die Highscoreliste: "	<< endl;
    			cout <<"                     "	<< endl;
    
    			while(Zähler <= 9)
    			{
    				if(Zähler < 9)
    				{
    					cout << Zähler + 1 << ".  " << iHighscore[i] << endl;
    				}
    				else 
    				{
    					cout << Zähler + 1 << ". " << iHighscore[i] << endl;
    				}
    
    				++Zähler;
    				++i;
    
    			}
    
    			getchar();
    			system("cls");
    			goto Menue;
    
    		}break;
    
    		case 'B':
    		case 'b':
    		{ 
    			system("cls");
    			getchar ();
    			cout <<" Das Spiel wird beendet." << endl;
    			getchar ();
    			return 0;
    
    		}break;
    
    		default:
    		{
    			system("cls");
    			getchar();
    			cout <<" Falsche Eingabe!" << endl;
    			getchar();
    
    			system("cls");
    			goto Menue;
    		}
    
    	}
    
    	getchar();
    	goto Menue;
    }
    
    int iSpielen (int iLevel)
    {
    	int Zufallszahl;
    	int Geratenezahl = 0;
    	int Bereich = iLevel*10;
    	int Versuche = 0;
    	int Punkte = 0;
    
    	Zufallszahl = (rand()%Bereich)+1;
    
    	while ( Zufallszahl != Geratenezahl)
    	{
    
    		cout <<"Errate die gesuchte Zahl (1 - " << Bereich <<" ) " << endl;
    		cin >> Geratenezahl;
    
    		Versuche++;
    
    		if( Zufallszahl < Geratenezahl)
    		{
    			cout << "Die gesuchte Zahl ist kleiner." << endl;
    		}
    
    		if( Zufallszahl > Geratenezahl)
    		{
    			cout <<"Die gesuchte Zahl ist groeßer" << endl;
    		}
    
    	}
    
    	cout <<"Herzlichen Gluekwunsch!!!" << endl;
    	cout <<"Du hast die gesuchte Zahl " << Zufallszahl <<" erraten" << endl;
    	Versuche++;
    
    	Punkte = Bereich - Versuche +1;
    	Punkte *= iLevel;
    
    	cout <<"Punkte: " << Punkte << endl,
    	getchar();
    	return Punkte;
    
    }
    
    /////////////////////////////////////////////////////////////////////////////
    ////////////Problem mit Funktion
    
    int iHighscoretest(int iHighscore[20], int Punkte)
    {	
    	int Zähler = 0;
    	int i = 0;
    
    	while(Zähler <= 9)
    	{
    
    		if( Punkte > iHighscore[i])
    		{
    			cout <<" Du bist auf dem " << i+1 <<". Platzt der Highscoreliste" << endl,
    			iHighscore[i+9] = iHighscore[i+8];
    			iHighscore[i+8] = iHighscore[i+7];
    			iHighscore[i+7] = iHighscore[i+6];
    			iHighscore[i+6] = iHighscore[i+5];
    			iHighscore[i+5] = iHighscore[i+4];
    			iHighscore[i+4] = iHighscore[i+3];
    			iHighscore[i+3] = iHighscore[i+2];
    			iHighscore[i+2] = iHighscore[i+1];
    			iHighscore[i+1]	= iHighscore[i];
    			iHighscore[i]	= Punkte;
    
    			string h;
    
    			ofstream schreiben;
    			schreiben.open("Highscore.txt");
    			schreiben << iHighscore[0] << endl;
    			schreiben << iHighscore[1] << endl;
    			schreiben << iHighscore[2] << endl;
    			schreiben << iHighscore[3] << endl;
    			schreiben << iHighscore[4] << endl;
    			schreiben << iHighscore[5] << endl;
    			schreiben << iHighscore[6] << endl;
    			schreiben << iHighscore[7] << endl;
    			schreiben << iHighscore[8] << endl;
    			schreiben << iHighscore[9] << endl;
    			schreiben.close();
    
    			goto Menue;	
    		}
    
    		Zähler++;
    		i++;
    	}			
    
    }
    


  • Hallo,

    bei einem Funktionsaufruf nur den Namen der Variablen als Parameter angeben:

    iHighscoretest(iHighscore, Punkte);
    

    (du solltest aber (Funktions-)Namen nicht mit "Ungarischer Notation" versehen, also besser einfach HighscoreTest).

    PS: Es gibt noch einiges an deinem Code zu verbessern, insbesondere wenn du demnächst Schleifen (for, while) erlernst.

    Die Initialisierung des Arrays (mit 0) kannst du aber einfacher haben:

    int iHighscore[20] = {}; // oder = { 0 };
    


  • Hallöchen,

    ich versuche mal dir behilflich zu sein.
    1. Reduziere bitte nächstes Mal deinen Code so weit wie möglich. Ich kann mir spontan nicht vorstellen, dass du 300 Zeilen posten musst, um dein Problem zu erläutern. Fehlermeldungen, falls vorhanden, sollten komplett gepostet werden. Schön Code-Tags verwendet hast du aber vorbildlich schonmal.

    1. goto wird als Sünde angesehen, da dadruch unter anderem der Programmablauf schnell sehr unübersichtlich wird, etwa wie Spaghetti, die auch noch nicht gerührt wurden und ohne Fett.

    3. Diese Notation, wo der (Rückgabe-)Typ im Funktions/Variablenamen enthalten ist, finde ich für C++ etwas unnötig. Kannst du getrost weg lassen (ist aber theoretisch ja Wurst).

    4. Die Verwendung von system() ist ebenfalls nicht zu empfehlen, da soweit ich weiß langsam und sicherheitskritisch. Da das aber alles nur zur Übung ist, kann man denke ich davon absehen.

    5. Wo wir vorhin schon bei Problembeschreibung waren, ich finde deine etwas lückenhaft. Ich will aber mal ganz nachsichtig und nett sein, und alles erraten was da schiefläuft.

    6. Mal zum Thema Array initialisieren. Das würde ich anders machen. Ganz naiv auf jeden Fall mit einer Schleife. Außerdem sind "magische Konstanten", also namenslose Zahlen, nicht gut. Das hat mehrere Gründe, die man im Internet nachlesen kann, ich will hier keinen Bestseller schreiben:

    constexpr int size = 20;
    int highscores[size];
    for (int i = 0; i != size; ++i)
        highscores[i] = 0;
    // geht eventuell noch kürzer, ist aber nicht unbedingt *verständlicher*
    

    Jetzt gibt es aber in der C++ Standardbibliothek ein Array, dass alle Vorteile der eingebauten "rohen" arrays mit sich bringt, und gleichzeitig alle Nachteile verschwinden lässt. Hört sich toll an, oder? Ist es eigentlich auch. Es gibt was nettes dass sich C++Referenz nennt, auch auf englisch, da kann man die ganzen STL sachen nachlesen.

    7. Variablen so local wie möglich definieren. Ist viel klarer, was wohin gehört. Achso, einzelne Buchstaben als Variablenamen sind auch nicht empfehlenswert, abgesehen von den "standard" Teilen wie i, j in for-Schleifen.

    8. Das nette an den C++ streams, ist dass sie sich zu einem Boolean evaluieren lassen, welcher wiederspiegelt in welchem Zustand sich der Stream befindet (e.g. good, bad, fail, ...). Somit lässt sich das Lesen aus einer Datei wiefolgt besser machen. Außerdem holst du dir eine Zeile aus der Datei, wandelst sie in einen stringstream und ließt dann einen double daraus. Wieso nicht gleich die double's aus der Datei lesen? Außerdem, was passiert mit deinem Programm, wenn in der Datei mehr Einträge sind, als in das Array passen? Das führt dann vermutlich zu "undefined behaviour" (out-of-range access), etwas, dass man in C++ unbedingt vermeiden möchte. Ich sprach vorher von std::array, aber eigentlich ist man mit std::vector in vielen Fällen besser bedient, das ist im Prinzip ein dynamisches array.

    vector<int> daten;
    int input;
    ifstream ist("foo.txt");
    while (ist >> input)
        daten.push_back(input);
    // oder
    while (getline(infile, str))
        // ...
    

    Solltest du am Ende der Datei angelangen, oder die Einleseoperation fehlschlagen, so terminiert die while-Schleife.

    9. Bei endl muss man aufpassen. Es tut mehr als der Name verspricht! Wenns wirklich nur eine neue Zeile sein soll, ist man mit '\n' gut bedient. Ist aber auch nur halb so wild, für Übungsfälle.

    10. Ich schwafel hier die ganze Zeit rum, ich will jetzt aber eigentlich mal zu deinem Problem kommen. Mir ist aufgefallen, dass du versuchst ein C-Style Array als Funktionsparameter zu übergeben. Eine der von mir vorhin angesprochenen Nachteile ist, dass C-Style Arrays bei der kleinsten Provokation in einen Pointer auf das erste Element "umgewandelt" werden. Damit man dann weiß, wann man aufzuhören hat, müsste man auch noch die Größe mitliefern (zumindest bei einem int array). All das geht mit std::vector leichter:

    // mit C-Style arrays:
    constexpr int size = 10;
    int myArr[size];
    //...
    void verarbeiteArray(int* arr, int sz)
    {
        for (int i = 0; i != sz; ++i)
            machwas mit arr[i];
    // ....
    }
    verarbeiteArray(myArr, size);
    
    // mit vector
    std::vector<int> bla;
    bla.size();  // Anzahl der Elemente
    // Als Funktionsparameter:
    void foo(const std::vector<int>& vec)
    {
        for (int i = 0; i != vec.size(); ++i)
           machwas mit vec[i];  // für range-check: vec.at(i)
        // oder
        for (const auto& elem : vec)
            machwas mit elem
    // ...
    }
    // Sollen die Elemente verändert werden, kann man natürlich nicht mit const übergeben
    

    Das const bewirkt kurz gesagt, dass wir die Elemente in vec nicht verändern können, das & führt dazu, dass vec per Referenz übergeben wird, was ähnlich ist wie ein Pointer, andererseits aber doch einige Unterschiede hat. Kurz gesagt, verhindern wir dadurch eine Kopie von vec anzufertigen, was bei einer Anzahl von 1Mio Elementen etwas peinlich wäre.

    11. Die highscores in die richtige Reihenfolge bringen geht auch einfacher, und muss zusätzlich auch nicht gewartet werden, wenn man mal mehr als nur 10 Highscores speichern möchte. Eine option wäre einfach absteigend zu sortieren. Dass kan die standard template library (STL) auch ganz nett, mit std::sort

    vector<int> highscores;
    // highscores füllen
    sort(highscores.begin(), highscores.end(), greater<int>());
    

    puh, langsam wirds ausführlich....

    12. Achja, genau, wir wollten diese gotos loswerden. Normalerweise mag ich do-while-Schleifen nicht, aber ich denke für ein simples Menü ist sie doch verwendbar:

    do {
    sagen was Sache ist (print Menü)
    Eingabe lesen
    Eingabe überprüfen/verarbeiten
    } while (Programm nicht beendet werden soll)
    

    Das mag nicht die Beste Variante sein, um sowas zu realisieren, aber ich hab grad nix besseres zur Hand. Musst halt suchen, z.B. nach "C++ console menu".

    langsam nimmt das ganze Gestalt an...

    13. Die '{' '}' in case labels werden nur bennötigt, wenn du innerhalb eine neue Variable definieren möchtest. Ansonsten kann man die getrost weg lassen.

    14. In der Funktion spielen zählst du zwar die Versuche, aber machst irgendwie nichts damit. Soll da später noch was dazu kommen?

    15. Der int Rückgabetyp bei highscoretest ist mir ebenfalls ein Rätsel. Wenn nichts zurückgegeben werden soll, gibt es void.

    Ich bin eigentlich dabei das Programm nett umzuschreiben, aber ich habe keine Zeit dafür. Ich empfehle ein gutes C++ Buch, man findet welche hier im Forum oder auf StackOverflow.

    Ich möchte das bisher geschriebene trotzdem posten, auch wenn es nicht komplett ist und mein Deutsch teils nicht so prickelnd ist. Soll nicht alles umsonst gewesen sein.

    Alle Angaben ohne Gewähr, sollte ich etwas falsches gesagt haben korrigiert mich bitte. Ich hoffe, dass ich dir irgendwie helfen konnte.

    LG

    Anhang;
    Bücher:
    https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
    https://www.c-plusplus.net/forum/251551
    C++Ref:
    std::vector, header <vector>
    std::array, header <array>
    std::greater, header <functional>
    std::sort, header <algorithm>



  • HI nur um es Richtig zu stellen.
    Wie initialisieren ich eine Variable unter C++11 ein Beispiel zum ausprobieren.
    Es scheint auch als hast Du ein sehr altes Buch da wie hier schon erwähnt Arrays im C Style nicht gut sind.
    Der Vector in C++ macht vieles einfacher.

    LG

    #include <iostream>
    
    using namespace std;
    
    int main ()
    {  
    	const int laenge{20};// Anzahl der Elemente
    	int array [laenge]{};
    
    //für die Ausgabe -------------	
    	for (size_t i=0;i <laenge;++i)
    	cout << " i = "<< i << " "<<array [i]<<endl;
    }
    


  • Hey,

    ich bedanke mich erstmal bei euch und insbesodere bei HarteWare für die ausführliche Antwort.

    Wie ihr schon bemerkt habt bin ich wirklich noch neu beim programmieren um genau zu sein ca. 1 Woche und deswegen sieht mein Code für euch wahrscheinlich ziemlich chaotisch aus.

    Bisher habe ich auch den Plan verfolgt das Programm irgendwie zum Laufen zu bringen und erst nacher nach effizenteren Methoden zu suchen, dabei bin ich dann auch auf mein Problem gestoßen.

    Deswegen bin ich dankbar für die Verbesserungsvorschläge, die ich zwar noch nicht alle verstehe, aber ich mich morgen mit befassen werde.

    Bevor ich zu den Punkten von HarteWare komme, schreib ich noch kurz wie meine Lernmethode ist:

    - Ich guck mir Tutorials auf Youtube an und versuche die Themen, so weit wie möglich, in mein kleines Spiel einzubauen.

    - Dazu suche ich dann im Internet nach Problemlösungen, die in den Videos nicht thematisiert werden wie z.B String in int "umwandeln.

    Wie auch schon HarteWare geschrieben hat sollte ich mir ein Buch anschaffen um C++ vernünftig lernen zu können.
    Meine Frage ist jetzt noch ob ihr gute Lernmethoden habt die mir weiterhelfen könnten.

    Jetzt komme ich auch endlich mal zu den Punkten:

    1. Ja, da hast du Recht. Es wäre wirklich nicht nötig gewesen den ganzen Code zu posten. Ich werde ihn nächstes Mal auf das wesentliche beschränken.

    2. "goto" kannt ich noch aus einer Taschenrechnerprogrammiersprache und war auch recht einfach umzusetzen, aber wenn du meinst, dass das unvorteilhaft ist, werde ich es versuche umzuschreiben.

    3. Das verstehe ich Leider nicht ganz. Meinst du damit z.B da "i" bei "iHighscore"? Darüber wurde im Tutorial gesagt, dass man damit so früh wie möglich anfangen sollte, weil man dann bei großen scripts schneller erkennt welchen Datentyp die Variable hat. Das ist bei so einem kleinen Programm natürlich nicht nötig.

    4. Das verstehe ich auch nicht.

    5. Ja stimmt, versuche ich nächstes Mal besser zu beschreiben.

    6. Bisher hatte ich noch nicht constexpr oder for, aber das sind relativ einfach aus und verstehe es auch.

    7. Ok, das leuchtet mir ein und versuche ich demnächst umzuschreiben.

    8. Ok Vektoren hatte ich bis jetzt auch nicht aber da werde ich mich mal reinarbeiten.

    9. Ok werde ich demnächst dann mit "\n\" machen. Ich fande "endl" einfach strukturierter und wusste nicht, dass es da Unterschiede gibt.

    10. Deine Erläuterung ist verständlich, ich muss mir nur noch den Code morgen näher angucken, den ich noch nicht ganz verstehe.

    11. Die Methode kannte ich nicht noch nicht, macht es aber um einiges kürzer.

    12. Obwohl ich do -while schon hatte bin ich darauf nicht gekommen. Schöne Möglichkeit.

    13. Bringt es irgendwelche Nachteile die {} trotzdem zu schreiben?

    14. Ich berechne mit den Versuchen die Punktzahl in der Funktion Spielen.

    15.Ich habe es auch schon mit void versucht, aber das hat mein Problem auch nicht gelöst. Aber es ist verständlich, dass int hier unsinnig ist.

    Ich werde mir wohl wirklich ein C++ Buch zulegen.
    Hat irgendjemand eine bestimmte Empfehlung für einen Anfänger.

    Außerdem frage ich mich ob C++ die richtige Sprache für den Einstieg ist.
    Ich persönlich finde sie bis jetzt nicht so schwer und bin für die kurze Lernzeit auch sehr zufrieden mit meine Resultaten. Außerdem macht es mir Spaß in C++ zu programmieren aber ich habe auch kein Vergleich zu anderen Sprachen, da ich mit C++ angefangen habe.

    Ihr könnt mir ja kurz schreiben , ob C++ die absolut falsche Einsteigersprache ist, wenn das nicht der Fall ist würde ich mit C++ weitermachen.

    Zum Schluss bedanke ich mich nochmal für die Hilfe, die überraschend ausführlich ist.

    MfG Tamen


  • Mod

    Tamen schrieb:

    Ich werde mir wohl wirklich ein C++ Buch zulegen.
    Hat irgendjemand eine bestimmte Empfehlung für einen Anfänger.

    Bücher und Tutorials zu C++

    Außerdem frage ich mich ob C++ die richtige Sprache für den Einstieg ist.
    Ich persönlich finde sie bis jetzt nicht so schwer und bin für die kurze Lernzeit auch sehr zufrieden mit meine Resultaten. Außerdem macht es mir Spaß in C++ zu programmieren aber ich habe auch kein Vergleich zu anderen Sprachen, da ich mit C++ angefangen habe.

    Ihr könnt mir ja kurz schreiben , ob C++ die absolut falsche Einsteigersprache ist, wenn das nicht der Fall ist würde ich mit C++ weitermachen.

    C++ ist sicherlich eine der schwersten Programmiersprachen überhaupt (abgesehen von ein paar Scherzsprachen, die extra möglichst unverständlich sein sollen), aber ich würde nicht sagen, dass dies bedeutet, dass sie für absolute Neueinsteiger ungeeignet wäre. Bloß eben schwerer als viele der Alternativen.



  • Von C++ YouTube Tutorials ist meines Erachtens nach prinzipiell erstmal abzuraten.

    Bücherlinks wurden nun schon ausreichend gepostet. Spezielle Bücher empfehlen möchte ich persönlich jetzt nicht.

    3. Das verstehe ich Leider nicht ganz. Meinst du damit z.B da "i" bei "iHighscore"?

    Nennt sich meines Wissens nach "hungarian notation". Kannst gern mal googeln. Persönlich finde ich es überflüssig, jedem nach seinem Geschmack.

    endl hat noch einen bestimmten Unterschied, der mit "flushen" "buffer leeren" usw. zu tun hat, wovon ich nur 50% verstehe und deshalb bewusst nicht näher darauf eingehen wollte. Da bist du bei einem der C++Gurus hier besser bedient 😃

    Obwohl ich do -while schon hatte bin ich darauf nicht gekommen. Schöne Möglichkeit.

    Schöner als goto vermutlich schon.

    13. Bringt es irgendwelche Nachteile die {} trotzdem zu schreiben?

    Im Prinzip nein.

    14. Ich berechne mit den Versuchen die Punktzahl in der Funktion Spielen.

    Mein Fehler, hab ich übersehen 🙄

    Ihr könnt mir ja kurz schreiben , ob C++ die absolut falsche Einsteigersprache ist, wenn das nicht der Fall ist würde ich mit C++ weitermachen.

    C++ ist geil, es ist auch teils schwer, man kommt oft an Hürden, man kapiert einen Großteil nicht, aber nach und nach kommt immer mehr dazu (ich würde weiter machen, mit Buch). Sollte es trotzdem mal irgendwo haken, gibt es ja dieses wundervolle Forum voller Experten (ich zähle mich selbst nicht dazu!)
    Du könntest dir ja mal Python anschauen, wenn du mal etwas anderes ausprobieren möchtest.


Log in to reply