Wert im Struct ändern



  • Hallo Hendrik,

    vielen Dank.

    Ich habe es so gemacht wie du es gesagt hast, also mit dem Objekt und Zugriff auf die Referenz.

    Der Compiler meldet allerdings irgendwas mit einem Verweis auf nicht aufgelöstes externes Symbol mit change_anzahl(void)?

    #include<iostream>
    #include"head.h"
    using namespace std;
    
    int menu();
    int rechnen();
    void change_anzahl();
    
    int main()
    {
    	aufgaben aufgenObjekt;
    
            ...
    }
    

    Die Headerdatei hab ich eingebunden. Was hab ich denn noch vergessen?

    Viele Grüße
    Christian


  • Mod

    Das meldet dir nicht der Compiler, sondern der Linker. Um ein konkretes Programm erstellen zu können braucht dieser den compilerten Code der Funktion. Lösung: Du musst noch gegen die Objektdatei die du aus den anderen .cpp-Dateien erstellt hast linken. Wie das genau geht kommt auf deine Entwicklungsumgebung an.



  • Ok, danke!

    Ich benutze Visual Studio 2007. Wie muss ich das dort machen?



  • Dein Problem ist ein anderes: In der main definierst Du ein change_anzahl mit Rückgabetyp void, die definierte Version in rechnen.cpp hat aber Rückgabetyp int.

    Allerdings solltest Du in main diese Definitionen nicht schreiben. Es bietet sich an, zu jeder Quellcodedatei eine Header-Datei zu erstellen, welche diese Deklarationen enthält. Diese kannst Du dann überall inkludieren (also auch in main.cpp), wo Du die Funktionen nutzen möchtest.



  • 1.) Bitte kein Denglisch. Einige dich auf Englisch, oder auf Deutsch, also auf Englisch.
    2.) printf ist C. Benutze std::cout



  • Vielen Dank für die Hinweise!

    Hab jetzt pritf durch cout ersetzt und auch englische Namen vergeben. Außerdem hab ich die Deklarartionen der Funktionen in die Headerdatei gepackt.

    @Eisflamme: Das mit Rückgabetyp von change_anzahl hatte ich geändert, also beides als void, aber es kommt immer noch die Fehlermeldung:

    " errorLink2019: Verweis auf nicht aufgelöstes externes Symbol ""void_cdecl change_count(void)"(?change_count@@YAXXZ)"in Funktion"_main". "

    Hier nochmal der Code:

    /* -------- head.h -------- */
    #include<iostream>
    
    int menu();
    int calculate();
    void change_count();
    
    struct tasks
    {
    int count;
    	// Defaultwert
    	tasks()
    	{
    		count = 5;		
    	}
    };
    
    /* -------- main.cpp -------- */
    #include<iostream>
    #include"head.h"
    using namespace std;
    
    int main()
    {
    	tasks tasksObject;
    
    	bool exit = false;
    	for(;;)
    	{
    		int choice = menu();
    
    		switch(choice)
    			{
    			case 1:
    				calculate();
    				break;
    			case 2:
    				change_count();
    				break;
    			case 3:
    				exit = true;
    				break;
    			default:
    				cout << " ---Falsche Eingabe--- \n";
    				cout << "  Versuch es nochmal!  \n";
    				break;
    			}
    		if (exit)
    			break;
    	}
    return 0;
    }
    
    /* -------- menu.cpp -------- */
    #include<iostream>
    #include"head.h"
    using namespace std;
    
    int menu()
    {
    
    system("cls");
    
    int choice;
    
    cout << "  <1>  Aufgaben rechnen\n";
    cout << "  <2>  Anzahl ändern\n";
    cout << "  <3>  Beenden\n";
    cout << "Eingabe: ";
    
    cin >> choice;
    
    return choice;
    }
    
    /* -------- change_count.cpp -------- */
    #include<iostream>
    #include"head.h"
    using namespace std;
    
    void change_count(tasks& ref)
    {
    	cout << "Zur Zeit sind " << ref.count << " Aufgaben eingestellt.";
    	cout << "Anzahl eingeben: ";
    	//cin >> ref.count << endl;
    }
    
    /* -------- calculate.cpp -------- */
    #include<iostream>
    using namespace std;
    
    int calculate(const tasks& ref)
    {
    	cout << "Jetzt werden " << /* ??? */ << "Aufgaben gerechnet.\n";
    	//...
    
    return 0;
    }
    

    Ich denke es ist irgendwas in der change_count.cpp falsch!?

    Wie kann ich eingentlich auf die Anzahl der Aufgaben in der calculate.cpp zugreifen?


  • Mod

    Einmal nimmt dein change_count nichts und einmal ein task§ als Parameter.



  • Wie meinst du das er nimmt nichts?



  • Die Funktion hat keine Parameter. Deklaration und Definition der Funktion müssen übereinstimmen, bei dir sind sie unterschiedlich.



  • Ok, so hab ich es jetzt gemacht:

    Deklarartion in der Headerdatei:

    ...
    void change_count(int tasks); // Deklarartion
    ...
    

    Definition in change_count.cpp:

    #include<iostream>
    #include"head.h"
    using namespace std;
    
    // Definition
    void change_count(int tasks& ref)
    {
    	cout << "Zur Zeit sind " << ref.count << " Aufgaben eingestellt.";
    	cout << "Anzahl eingeben: ";
    	//cin >> ref.count << endl;
    }
    

    Und dann in main.cpp der Funktionsaufruf:

    ...
    case 2:
    		change_count(int tasks);
    		break;
    ...
    

    ...aber es funktioniert nicht.



  • Das ist imer noch kein legaler Code (schon davon abgesehen, daß "int tasks& ref" nicht erlaubt ist, sind die Deklaration und Definition immer noch verschieden - und main() deklariert eine eigene lokale Funktion). Prinzipiell sollte es so funktionieren:

    //task.h
    struct task{...};
    
    void change_count(task& ref);
    
    //task.cpp
    #include "task.h"
    
    void change_count(task& ref)
    {
      ...
    }
    
    //main.cpp
    #include "task.h"
    
    int main()
    {
      ...
      task t;
      change_count(t);
      ...
    }
    

    (btw, vom Design her würde ich die change_count nicht als freie Funktion definieren, sondern als Methode deiner Struct)



  • Wieso packst du nicht gleich alles in eine Klasse? Bringt doch praktisch nur Vorteile: übersichtlicher, einfacher, da man nicht so eine komplizierte Funktion hat, usw.

    /* ---------- Aufgaben.j ---------- */
    
    class CAufgaben
    {
    	private:
    		int m_Anzahl;
    
    	public:
    		CAufgaben(int nAnzahl);
    		void AnzahlAendern(int nAnzahl)							{ m_Anzahl = nAnzahl; }
    		void Rechnen();
    };
    
    /* ---------- Aufgaben.cpp ---------- */
    
    CAufgaben::CAufgaben(int nAnzahl)
    {
    	m_Anzahl = nAnzahl;
    }
    
    CAufgaben::Rechnen()
    {
    	cout << "Jetzt werden " << this->m_Anzahl << " Aufgaben gerechnet" << endl;
    }
    

    ...... jetzt musst du nur noch in der main() die Klasse initialisieren:

    int main(int argc, char **argv)
    {
    	bool bExit = false;
    	int iChoice;
    	CAufgaben m_Aufgaben(5);
    
    	while(!bExit)
    	{
    		system("cls");
    
    		cout << "RECHENTOOL" << endl;
    		cout << "**********" << endl;
    		cout << "<1> Aufgaben Rechnen" << endl;
    		cout << "<2> Anzahl ändern" << endl;
    		cout << "<3> Beenden" << endl;
    
    		cin >> iChoice;
    
    		switch(iChoice)
    		{
    			case 1:
    				m_Aufgaben.Rechnen();
    				break;
    
    			case 2:
    				int iNeueAnzahl;
    				cout << endl << "Anzahl eingeben: ";
    				cin >> iNeueAnzahl;
    				m_Aufgaben.AnzahlAendern(iNeueAnzahl);
    				break;
    
    			case 3:
    				bExit = true;
    				break;
    
    			default:
    				cout << endl << "Falsche Eingabe!" << endl << "Auswahl bitte erneut durchführen!" << endl;
    				break;
    		}
    	}
    
    	return 0;
    }
    


  • PS: In der Kommentarzeile sollte es natürlich "--------- Aufgaben.h ----------" heißen



  • Hi,

    vielen Dank für die Tipps hat mir geholfen, es funktioniert jetzt.

    @wersdf: Danke für den Hinweis. Wenn ich es mit den Funktionen umgesetzt hab, werde ich es auch noch mit Klassen realisieren.

    Ich will jetzt noch die Anzahl der richtigen Anworten erfassen. Dafür hab ich im struct 'correct' angelegt mit dem Default-Wert 0.

    In calculate möchte ich auf 'correct' zugreifen und es verändern und 'count' nur auslesen.

    Hab mir das wie folgt gedacht (schematisch):

    //task.h 
    struct task
    {
    int count;
    int correct;
     tast()
    	{
    	count = 5;
    	correct = 0;
    	}
    
    }; 
    
    void change_count(task& ref);
    int calculate(const task& ref, task& ref2); 
    
    //task.cpp 
    #include "task.h" 
    
    void change_count(task& ref) 
    { 
      ... 
    } 
    
    //calculate.cpp
    #include "task.h"
    
    int calculate(const task& ref, task& ref2)
    {
    cout << "Es werden " << ref.count << " Aufgaben gerechnet!";
    //... 
     ref2.correct = 9; // correct verändern
    cout <<"Du hast" << ref.correct << "Aufgaben falsch berechnet";
    //...
    }
    
    //main.cpp 
    #include "task.h" 
    
    int main() 
    { 
      ... 
      task t; 
      change_count(t); 
      calculate(t);
      ... 
    }
    

    ... es funktioniert so aber nicht. Kann ich die Argumentenliste so aufstellen?

    Gruss



  • Das ist alles etwas wirr, was du da versuchst, insbesondere die Funktion calculate , die zwei tasks erwartet. Auch die Funktion change_count , die die Anzahl der Aufgaben in einem Task setzt sollte besser eine Elementfunktion der Klasse task sein. Am besten du formulierst mal klar deine Aufgabe und den Lösungsansatz, den du dir dazu überlegt hast. Ich glaube nämlich, dass du nicht so wirklich weißt, was du machst und einfach nur so lange Code hin- und herschiebst, bis ungefähr das passiert, was du willst.
    Und Fehlerbeschreibungen wie "...aber es funktioniert nicht..." sind wenig hilfreich, kein Mensch weiß, was nicht funktioniert und wo der Fehler in etwa zu suchen ist. Eigentlich dürftest du dich nicht wundern, wenn du dann Ratschläge wie "Dann musst du es richtig machen." bekommst, der spielt in der gleichen Liga. Also, beim nächsten Mal bitte den Fehler beschreiben, am besten die Fehlermeldung des Compilers posten oder zumindest eine Beschreibung mit Zeilenangabe abgeben.

    class task
    {
    public:
       task() : Count_( 0 ), Correct_( 0 )
       {
       }
    
       unsigned int count() const
       {
          return Count_;
       }
    
       void count( unsigned int Count )
       {
          Count_ = Count;
       }
    
       unsigned int correct() const
       {
          return Correct_;
       }
    
       void correct( unsigned int Correct )
       {
          Correct_ = Correct;
       }
    
    private:
       unsigned int Count_;
       unsigned int Correct_;
    };
    
    int main()
    {
       task theTask;
    
       theTask.count( 5 );
       theTask.correct( 0 );
    }
    


  • Die Aufgabe ist es ein Rechenprogramm zu schreiben, das eine Menü besitzt. Im Menü kann man entweder unter dem Punkt "Anzahl ändern" die Anzahl der Aufgaben einstellen oder es werden automatisch 5 Aufgaben gestellt. Unter dem Punkt "Aufgaben rechnen" startet man das Programm. Unter dem Punkt "Auswertung" soll man sehen wieviel Aufgaben man richtig berechnet hat und unter "Beenden" das Programm beenden.

    Vorgegeben ist, dass wir ein struct in einer Headerdatei erstellen sollen, welche die Default-Werte für die Anzahl der richtigen Antworten(=0) und Anzahl der Aufgaben (=5) enthält.

    In der zweiten Aufgabe sollen wir es mit Klassen realisieren.

    Meine Frage:

    Wie kann ich auch correct aus dem struct in der Headerdatei zugreifen? Also ich will correct in der Funktion calculate verändern und in der Funktion results ausgeben.

    Das ist mein Lösungsansatz:

    // def.h
    struct tasks
    {
    int count; // Anzahl der Aufgaben
    int correct; // Anzahl der richtigen Antworten
    
    	tasks()
    	{
    		count = 5;
    		correct = 0;
    	}
    };
    void change_count(tasks& ref);
    int calculate(const tasks& ref);
    int menu();
    int results(const tasks& ref);
    
    // calculate.cpp
    #include<iostream>
    #include<conio.h>
    #include"def.h"
    using namespace std;
    
    int calculate(const tasks& ref)
    {
    	system("cls");
    
    	cout << "Jetzt werden " << ref.count << " Aufgaben gerechnet.\n";
    	/*
    	- hier werden dann je nach Eingabe n Aufgaben berechnet
    	- außerdem noch überprüft ob richtig gerechnet wurde
    	*/
    
    	cout << "\nWeiter mit beliebiger Taste...";
    	getch();
    
    return 0;
    }
    
    // change_count.cpp
    #include<iostream>
    #include<conio.h>
    #include"def.h"
    using namespace std;
    
    void change_count(tasks& ref)
    {
    	cout << "Zur Zeit sind " << ref.count << " Aufgaben eingestellt.\n";
    	cout << "Anzahl eingeben: ";
    	cin >> ref.count;
    
    	cout << "\nWeiter mit beliebeiger Taste...";	
    	getch();	
    }
    
    // main.cpp
    #include<iostream>
    #include"def.h"
    using namespace std;
    
    int main()
    {
    	tasks tObject;
    
    	bool exit = false;
    	for(;;)
    	{
    		int choice = menu();
    
    		switch(choice)
    			{
    			case 1:
    				calculate(tObject);
    				break;
    			case 2:
    				change_count(tObject);
    				break;
    			case 3:
    				results(tObject);
    				break;
    			case 4:
    				exit = true;
    				break;
    			default:
    				cout << " ---Falsche Eingabe--- \n";
    				break;
    			}
    		if (exit)
    			break;
    	}
    return 0;
    }
    
    // menu.cpp
    #include<iostream>
    #include"def.h"
    using namespace std;
    
    int menu()
    {
    
    system("cls");
    
    int choice;
    
    cout << "  <1>  Aufgaben rechnen\n";
    cout << "  <2>  Anzahl aendern\n";
    cout << "  <3>  Auswertung\n";
    cout << "  <4>  Beenden\n";
    cout << "Eingabe: ";
    
    cin >> choice;
    
    return choice;
    }
    
    // results.cpp
    #include<iostream>
    #include<conio.h>
    #include"def.h"
    using namespace std;
    
    int results(const tasks& ref)
    {
    	system("cls");
    
    	cout << "Du hast " << ref.correct << " Aufgaben richtig berechnet.\n";
    
    	cout << "\nWeiter mit beliebiger Taste...";
    	getch();
    
    return 0;
    }
    


  • Wenn du die Inhalte der struct ändern willst, darfst du sie natürlich nicht als "const tasks&" übergeben, sondern als normale Referenz (so wie bei der change_count()-Funktion).

    PS: Du solltest eventuell nochmal zurückkehren zu den Grundlagen, z.B. wie eine Funktion definiert und aufgerufen wird.



  • Ok, ich glaub ich habs jetzt, wenn ich calculate so deklariere:

    void calculate(tasks& ref);
    

    bedeutete das, dass ich eine Funktion deklariere, die nichts zurückgibt, wegen void. Der Name ist calculate und der Parameter, der übergeben wird, ist eine Referenz von tasks!?

    Dann erstelle ich ein Objekt in main:

    tasks = tObject;
    

    ...und füge es bei den Funktionen ein, die es benutzen sollen:

    calculate(tObject);
    

    Dann definiere ich die Funktion:

    void (tasks& ref)
    {
    ref.correct = 12;
    ref.count = 1;
    ...
    }
    

    ...und kann da die Elemente von der Referenz des structs beliebig verändern.

    Und mit const kann ich den Wert natürlich nicht veränder sonder nur auslesen?



  • Beinahe... du erstellst das Objekt in main natürlich so, nicht per Zuweisung:

    int main()
    {
       tasks theTasks;
       ...
    }
    

Anmelden zum Antworten