Hilfe bei c++ Aufgaben



  • Danke für die Antworten. Da ich nicht verstanden habe wie das mit dem FillArray funktioniert, habe ich die Aufgabe erstmal ohne gelöst. Es sieht auch etwas unprofessionell aus, aber für den Anfang finde ich es gut 😉
    Kann mir bitte jemand eine Meinung zu dem Programm und evtl Verbesserungsvorschläge nennen und anhand meines Programms ein funktionierendes Beispiel mit FillArray posten?

    #include <iostream>
    
    #include <algorithm>
    
    using namespace std;
    
    int main() 
    {
    anfang:	
    	float a[6];
    	cout << "Zahlen eingeben? \n""Ja (j) /Nein (n): ";
    	char antwort = ' '; 
    	cin >> antwort;
    
    	if (antwort == 'j'){
    		a[0] = 3.89;
    		a[1] = 8.34;
    		a[2] = 2.78;
    		a[3] = 9.43;
    		a[4] = 1.56;
    		a[5] = 7.45;
    		}
    	else if (antwort == 'n'){
    		cout << "Das Programm wurde beendet.";
    		return 0;
    		}
    
    	else if (antwort != 'n' && antwort != 'j')
    		goto anfang;
    
    teil1:		
    		cout << "unsortierte Zahlen ausgeben? \n""Ja (j) /Nein (n): ";
    		char antwort2 = ' '; 
    		cin >> antwort2;
    
    		if (antwort2 == 'j'){
    			for (int i=0; i<6; i++)
    			cout << a[i] << " ";
    			cout << "\n";
    			}
    		else if (antwort2 == 'n'){
    			cout << "Das Programm wurde beendet.";
    			return 0;
    			}
    		else if (antwort2 != 'n' && antwort2 != 'j')
    			goto teil1;
    
    teil2:				
    			cout << "Zahlen sortieren? \n""Ja (j) /Nein (n): ";
    			char antwort3 = ' '; 
    			cin >> antwort3;
    
    			if (antwort3 == 'j'){	   
    				sort(a, a+6);
    
    				reverse(a, a+6);
    				}
    			else if (antwort3 == 'n'){
    				cout << "Das Programm wurde beendet.";
    				return 0;
    					}
    			else if (antwort3 != 'n' && antwort3 != 'j')
    				goto teil2;
    
    teil3:						
    				cout << "sortierte Zahlen ausgeben? \n""Ja (j) /Nein (n): ";
    				char antwort4 = ' '; 
    				cin >> antwort4;
    
    				if (antwort4 == 'j'){
    
    					for (int i=0; i<6; i++)
    
    					cout << a[i] << " ";
    					}
    				else if (antwort4 == 'n'){
    					cout << "Das Programm wurde beendet.";
    					return 0;
    					}
    				else if (antwort4 != 'n' && antwort4 != 'j')
    					goto teil3;
    
    	getchar();
    
        return 0;
    }
    

    gruß okta



  • Kann mir bitte jemand eine Meinung zu dem Programm und evtl Verbesserungsvorschläge nennen

    Das ist ein gutes Beispiel, wie man goto nicht verwendet. 😉
    Nutze Funktionen und eine (oderer mehrere) Schleife(n).

    Das mit dem fillarray war nur ein Vorschlag, dass du Funktionen benutzen solltest, weil das ganze dann viel übersichtlicher und einfacher zu verstehen ist. Wenn du nämlich eine Funktion hast, die fillarray heisst, dann ist das relativ leicht zu verstehen, was die Funktion macht und man muss nicht den ganzen Code durchgehen, um zu verstehen, was sie macht. (Das ist einer der grossen Vorteile von Funktionen) Wenn du es dann doch tun musst, kannst du die Funktion ja immernoch genauer anschauen.



  • Okta schrieb:

    aber für den Anfang finde ich es gut 😉

    Oktaaaaaa!!! Was tust du???

    Ich habe dir mal ein kleines Beispiel (Ähnlichkeiten mit deiner Aufgabe sind rein zufällig 😉 ) aufgeschrieben. Mir ist zwar nicht ganz klar was dieses "nach Aufforderung" jeweils genau bedeutet, aber so könnte die Lösung einer ähnlichen Aufgabe aussehen:

    #include <iostream>
    
    using namespace std;
    
    void einlesen(char meinArray[]) {
    
    	for (int i=0; i < 2; ++i) {
    		cout << "Bitte " << i+1 << ". Wert eingeben." << endl;
    		cin >> meinArray[i];
    	}
    }
    
    void tauschen(char meinArray[]) {
    
    	char dummy;
    	dummy = meinArray[0];
    	meinArray[0] = meinArray[1];
    	meinArray[1] = dummy;
    }
    
    int main()
    {
    	char meinArray[2];
    	char antwort = 'n';
    
    	einlesen(meinArray);  
    
    	cout << "Array ausgeben? (j/n)";
    	cin >> antwort;
    	if (antwort =='j')
    		cout << "Array nach einlesen() : " << meinArray[0] << " " << meinArray[1] << endl;
    
    	tauschen(meinArray);
    
    	cout << "Array nach tauschen() : " << meinArray[0] << " " << meinArray[1] << endl;
    
    	return 0;
    }
    


  • ist das jetzt besser? 😉

    #include <iostream> 
    #include <algorithm> 
    using namespace std; 
    
    void print(float a[]) { 
        for (int i=0; i<6; i++) 
    		cout << a[i] << " "; 
    	cout << "\n"; 
    } 
    
    void fillarray(float a[]) { 
    	a[0] = 3.89; 
    	a[1] = 8.34; 
    	a[2] = 2.78; 
    	a[3] = 9.43; 
    	a[4] = 1.56; 
    	a[5] = 7.45; 
    } 
    
    void sortarray(float a[]) { 
    
    	sort(a, a+6); 
    	reverse(a, a+6); 
    } 
    
    int main()  
    { 
    	float a[6]; 
    	char antwort = ' '; 
        while(antwort != 'n' && antwort != 'j'){
            cout << "Zahlen eingeben? \n""Ja (j) /Nein (n): "; 
            cin >> antwort; 
            if (antwort == 'j') {
    			fillarray(a); 
    		}
    		else if (antwort == 'n'){
    			cout << "Das Programm wurde beendet.";
    			getchar();
    			getchar(); 		
    			return 0;
    		}
    	}
    
    	antwort = ' '; 
    	while(antwort != 'n' && antwort != 'j') {
    		cout << "unsortierte Zahlen ausgeben? \n""Ja (j) /Nein (n): ";  
    		cin >> antwort; 
    		if(antwort == 'j'){ 
    			print(a); 
    		}
    		else if(antwort == 'n') {
    			cout << "Das Programm wurde beendet.";
    			getchar();
    			getchar(); 		
    			return 0;
    		}
    	}
    
    	antwort = ' '; 
    	while(antwort != 'n' && antwort != 'j') {
    		cout << "Zahlen sortieren? \n""Ja (j) /Nein (n): ";
    		cin >> antwort;
    		if (antwort == 'j'){
    			sortarray(a);
    		}
    		else if (antwort == 'n'){ 
    			cout << "Das Programm wurde beendet.";
    			getchar();
    			getchar();
    			return 0;
    		}
    	}
        antwort = ' ';      
        while(antwort != 'n' && antwort != 'j') { 
            cout << "sortierte Zahlen ausgeben? \n""Ja (j) /Nein (n): ";
            cin >> antwort; 
            if (antwort == 'j'){ 
                print(a); 
    		}
    		else if( antwort == 'n') {
    			cout << "Das Programm wurde beendet.";
    			getchar();
    			getchar(); 		
    			return 0;
    		}
    	}
    	getchar();
    	getchar(); 
        return 0; 
    }
    

    hab eine andere Aufgabe (Nullstellen einer Quadratischen Gleichung) gelöst und würde dazu auch eure Meinung erfahren. Eine Frage habe ich auch noch: Wie kann ich die Augabe am Ende (-10 < x < 10) übersichtlicher gestalten?

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    double a,b,c;
    double p, q, p1, p2, r;
    double x1, x2;
    double y;
    
    void berechnung(){
    
    	p = b/a;
    	q = c/a;
    	p1 = pow(p, 2);
    	p2 = p1/4;
    	r = p2-q;
    	x1 = -p/2 + sqrt(r);
    	x2 = -p/2 - sqrt(r);
    }
    
    int main()
    {
    
    	cout << "Bitte a eingeben: ";
    	cin >> a;
    	if (a != 0){
    		cout << "Bitte b eingeben: ";
    		cin >> b;
    		cout << "Bitte c eingeben: ";
    		cin >> c;
    		berechnung();
    	}
    	else {
    		cout << "Geradengleichung";
    		return 0;
    	}
    
    	if (r < 0){
    		cout << "Komplexe Nullstellen";
    		return 0;
    	}
    	if (r == 0){
    		cout << "Doppelte Nullstelle\n";
    	}
    	cout << "Die Nullstelle x1 lautet: " << x1 <<endl;
    	cout << "Die Nullstelle x2 lautet: " << x2 <<endl;
    	if (b == 0){
    		cout << "Parabel symmetrisch zur Y-Achse";
    	}
    	for (float i=-10; i<=+10; i++){
    		y = pow(i, 2) * a + i*b + c;
    		cout << "\n " << i << "\t \t " << y;
    	}
    	return 0;
    }
    


  • Okta schrieb:

    ist das jetzt besser? 😉

    Naja - es ist besser aber noch immer nicht hübsch... Da ich eigtl gerade Lernen müsste und keine Lust habe, versuch ich mal, dir bissl zu helfen... ^^

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const size_t LENGTH = 6;
    
    void print(float *a, size_t length)
    { 
        for (size_t i=0; i != length; ++i)
        {
            cout << a[i] << " "; 
        }
        cout << endl; 
    } 
    
    void fillarray(float *a, size_t length)
    {
        srand(static_cast <unsigned int> (time(0));
        for (size_t i(0); i != length; ++i)
        {
           a[i]  = static_cast <float> (rand()) / 100.f; //2 nachkommastellen sollten genügen
        }
    } 
    
    void sortarray(float *a, size_t length)
    {
        sort(a, a+length);
        reverse(a, a+length);
    } 
    
    int Quit()
    {
        cout << "Das Programm wurde beendet.";
        getchar();
        return 0;
    }
    
    int main()  
    { 
        float a[LENGTH];
        bool break_loop(false);
        do
        {
            cout << "Zahlen eingeben?\n"
              << "Ja (j) / Nein (n)";
            char antwort; 
            cin >> antwort;
            switch (antwort)
            {
                case 'j':
                    fillarray(a, LENGTH);
                    break_loop = true;
                    break;
                case 'n':
                    return Quit();
                    break;
                default:
                    cout << endl << "Ungueltige Eingabe" << endl;
            }
        } while(! break_loop);
    /*
    Die anderen Schleifen analog dazu ändern
    */
    }
    

    Ich weiß nicht, ob das nun die eleganteste Lösung ist oder nicht - aber hübscher als deine ist sie auf jeden Fall ^^
    Auch ist das switch nicht schneller als das if an der stelle (innerhalb der Schleife) - aber es erhöht die Übersicht doch gewaltig - findest du nicht?!
    außerdem kann man auch leichter auf 'J' / 'j' bzw 'N' / 'n' prüfen etc...

    Die zweite Aufgabe: (du hättest ja wenigsten mal versuchen können, zu compilieren - die letzte schleife hat er niemals so akzeptiert...

    #include <iostream>
    #include <cmath>
    #include <stdexcept> //unsere exception std::invalid_argument
    #include <utility> //std::pair
    using namespace std;
    
    //    1. Typ, 2. Typ
    // falls dich das zu sehr irritiert, kannst du auch ein eigenes struct schreiben oder einfach mal bissl was über "templates" nachlesen...
    
    pair <double, double> berechnung(double a, double b, double c)
    {
        double p = b/a;
        double q = c/a;
        double p1 = p * p; //fürs quadrat brauchen wir noch kein power of...
        p1 /= 4; //bei dir war das hier p2
        p1 -= q; //und das hier p2
    
        if (p1 < 0) //hier werden die nullstellen komplex da neg. wurzel
        {
            throw invalid_argument("..."); //hier musst du noch was eintragen - wenn du möchtest ^^
        }
    
        pair <double, double> ReturnValue;
        ReturnValue.first  = -p/2 + sqrt(p1); //x1
        ReturnValue.second = -p/2 - sqrt(p1); //x2
        return ReturnValue; //sollte klar sein ^^
    }
    
    double p, q, p1, p2, r;
    double x1, x2;
    double y;
    
    int main()
    {
        double a, b, c;
        cout << "Bitte a eingeben: ";
        cin >> a;
        if (a == 0)
        {
            cout << "Geradengleichung";
            return Quit(); //Quit würde so (ähnlich) wie vorhin aussehen
        }
    
        cout << "Bitte b eingeben:";
        double b;
        cin >> b;
        cout << "Bitte c eingeben: ";
        double c;
        cin >> c;
        pair <double, double> ergebnis;
        try
        {
            ergebnis = berechnung (a, b, c);
        }
        catch (const invalid_argument &e)
        {
            cout << e.what();
            return Quit();
        }
    
        cout << "Die Nullstelle x1 lautet: " << ergebnis.first  << endl;
        cout << "Die Nullstelle x2 lautet: " << ergebnis.second << endl;
        if (b == 0)
        {
            cout << "Parabel symmetrisch zur Y-Achse";
        }
    
        for (int i (-10); i != 10; ++i)
        {
            y = i*i * a + i*b + c;
            cout << "\n " << i << "\t \t " << y;
        }
        return Quit();
    }
    

    besser?
    falls du fragen hast, dann frag ruhig - hier war sicherlich einiges dabei, was du (so) noch nicht kanntest...

    bb



  • Danke das sieht schon viel besser aus 🙂
    Allerdings verstehe ich die Funktion von den folgenden Befehlen nicht:

    pair <double, double>
    catch (const invalid_argument &e)
    try

    Ich habe das Programm kompiliert und es hat bei mir auch funktioniert, vielleicht liegt es daran, dass ich xcode benutze...



  • std::pair ist ein Klassentemplate, das zwei Werte beliebigen Typs speichern kann.

    try und catch sind Schlüsselwörter für das sogenannte Exception-Handling, eine Art der Fehlerbehandlung.

    Auf www.cplusplus.com findest du noch mehr Informationen...



  • Okta schrieb:

    Ich habe das Programm kompiliert und es hat bei mir auch funktioniert, vielleicht liegt es daran, dass ich xcode benutze...

    Dein Programm lässt sich problemlos übersetzten.

    Beide Programme sehen OK aus. Daher würde ich an deiner Stelle jetzt nich viel daran ändern oder womöglich noch komische Zugaben einbauen, die überhaupt nicht in der Aufgabenstellung stehen und auch nichts bringen.

    Die Autotyp-Geschichte wird noch schwer genug. 😉

    unskilled schrieb:

    falls du fragen hast, dann frag ruhig - hier war sicherlich einiges dabei, was du (so) noch nicht kanntest...

    Weniger ist manchmal mehr ...
    Es gibt keinen Grund den Exception-, Template-, und Castkäse an der Stelle einzubauen.



  • Es gibt keinen Grund den Exception-, Template-, und Castkäse an der Stelle einzubauen

    also nimmt man weiterhin globale variablen?

    ob er die klasse mit den rückgabewerten selbst schreiben würde, hätte er vrmtl mehr können müssen als std::pair zu nehmen...

    for (float i=-10; i<=+10; i++){
    

    ich kenn keinen Compiler, der nen operator++ bei float kennt...
    in so fern glaub ich auch nicht, dass er es compilieren konnte.

    bb



  • unskilled schrieb:

    ich kenn keinen Compiler, der nen operator++ bei float kennt...

    Du meinst, float ist nicht "plusplus-bar"?



  • meine ich ^^
    genau, wie es keinen %-operator für float gibt...

    bb



  • @unskilled

    Es geht mir dabei darum, dass du einem Anfänger der klar sagt, er beginnt erst mit C++ und unter Zeitdruck steht irgendwelche Templates, Exceptions, usw. an den Kopf knallst. Du selbst sagst ja, es wären Dinge dabei die er vermutlich nicht kennt.

    Hilfreich ist das mit Sicherheit nicht. Und "hübsch" ist es auch nicht.
    Sieht mehr nach einer kleinen "Angeberei" aus. 😉

    Das wollte ich damit sagen. Ob das alles programmiertechnisch sinnvoll ist, ist wieder eine andere Frage.

    Zu der float-Geschichte:
    Hab es jetzt auf mehreren Compilern in der Standard-Konfiguration getestet und es kam bei keinem davon auch nur eine Warnung.

    Ist schwer zu beurteilen, mit welchen Compilern du arbeitest und weshalb du auf die Schlußfolgerung gekommen bist, aber die "gängigen" Compiler unter Windows und Linux schlucken das.



  • unskilled schrieb:

    meine ich ^^
    genau, wie es keinen %-operator für float gibt...

    aber f=f+1 soll gehen? paßt nicht zusammen. entweder geht auch f++ oder geht f=f+1 nicht. was ist die lieber?



  • volkard schrieb:

    unskilled schrieb:

    meine ich ^^
    genau, wie es keinen %-operator für float gibt...

    aber f=f+1 soll gehen? paßt nicht zusammen. entweder geht auch f++ oder geht f=f+1 nicht. was ist die lieber?

    Hum -.- War mir so sicher, dass es nicht geht, dass ichs nich ma probiert hab - sry...

    @Hm:
    Du kannst natürlich auch nen riesiges struct zurückgeben lassen und dann gucken, was dort drin steht (linear, komplexe nullstellen, nullstellen an sich)

    Find ich aber nicht hübscher - dann würd ich es lieber noch ohne die zugehörige funktion direkt in der main-fkt machen...

    bb


Anmelden zum Antworten