Struct in Header



  • Ich habs bisher so versucht

    #pragma once
    #ifndef Projekt_H
    #define	Projekt_H
    ...
    

    Ist das richtig so? Bringt aber nichts 🙂

    Ich benutze MS Visual Studio 2010 Ultimate. Wo ich das einstelle, was du erwähnt hast, weiß ich leider nicht.



  • @f-th: Linker-Probleme kannst du nicht durch Include-Guards beheben.

    @Perhalo: Du benötigst den Eintrag Analyse Ana1; (das "struct" ist dort redundant) in genau einer CPP-Datei - ohne kommt der genannte Linker-Fehler, bei mehreren kommt normalerweise ein anderer Fehler ("mehrfache Definition").
    Die extern Angabe im Header ist eine reine Deklaration - die besagt nur "irgendwo existiert eine Variable mit dem Namen Ana1". Das ist dem Compiler genug, um den Code zu übersetzen (er setzt dann bei Verwendung nur eine Notiz, daß hier diese Variable benötigt wird). Der Linker benötigt genau eine echte Definition (ohne extern - an der Stelle wird der Compiler tatsächlich Speicherplatz für die Variable reservieren) und ersetzt all diese Notizen dann durch einen Verweis auf genau diese Definition.

    PS: Übrigens gelten globale Variablen als "schlechtes Design" - wenn du eine Möglichkeit hast, bau dein Programm ohne sowas auf.



  • Hallo Perhalo,

    du scheinst in jeder Funktion "struct Analyse Ana1;" (toller Name 😉 eingefügt zu haben.
    Setze diese Definition mal global in eine Sourcedatei (Projekt.cpp) und lösche alle lokalen Variablen gleichen Namens.

    Und wenn das Programm dann läuft, dann versuche auf globale Variablen zu verzichten, indem du Referenzen dieses Objektes an die anderen Funktionen weitergibst.
    Verwendest du denn schon Klassen in deinem Programm, dann könntest du diese Referenz als Klassenmember speichern (und im Konstruktor übergeben).



  • Leider ist das explizit so in der Aufgabenstellung verlangt:

    "Datenstruktur

    Erzeugen Sie in der Headerdatei eine Struct, in der Informationen über die Anzahl der Aufgaben und die Anzahl der richtigen Lösungen gespeichert sind. Die Defaultwerte des Struct sind 5 Aufgaben und 0 richtige Lösungen."

    Wenn ich ich jetzt nur in meinem Menue.cpp

    struct Analyse Ana1;

    einfüge, kann die Datai Rechnung.cpp nicht darauf zugreifen. Lässt sich das Problem irgendwie lösen oder muss ich versuchen das irgendwie mit return Werten hinzubekommen?



  • Erstens: In der Aufgabenstellung steht nichts von globalen Objekten (außer du hast einen Teil unterschlagen).
    Zweitens: Wenn du schon auf die globale Variable zugreifen willst, dann achte darauf, wo du etwas definierst. Wie Th69 schon sagte, hast du vermutlich in jeder Funktion eine lokale Variable angelegte, die (a) die globale und externe Variable überdeckt und (b) bei jedem Funktionsaufruf neu initialisiert wird. Was du benötigst, ist EINE Definition der globalen Variablen:

    //falsch - lokale Variable verdeckt dein globales struct:
    //Rechnung.cpp
    #include "Projekt.h"
    
    int rechne()
    {
      struct Analyse Ana1;//nur innerhalb der Funktion gültig
      ...
      if (Eingabe==Rechnungsergebniss) 
      {
        Ana1.Aufgabenzahl_ges_richtig=Ana1.Aufgabenzahl_ges_richtig+1;
      }
      ...
    }
    
    /******************************************************************************/
    
    //besser - Definition der globalen Variable
    //Projekt.cpp
    #include "Projekt.h"
    
    struct Analyse Ana1;
    
    //Rechnung.cpp
    #include "Projekt.h"
    int rechne()
    {
      //hier keine lokale Definition -> Ana1 bezieht sich auf dein globales struct
      ...
      if (Eingabe==Rechnungsergebniss) 
      {
        Ana1.Aufgabenzahl_ges_richtig=Ana1.Aufgabenzahl_ges_richtig+1;
      }
      ...
    }
    
    /******************************************************************************/
    //noch besser - Verzicht auf globale Variablen
    //Projekt.h
    #ifndef PROJEKT_H
    #define PROJEKT_H
    struct Analyse
    {
        int Aufgabenzahl_ges;
        int Aufgabenzahl_ges_richtig;
        Analyse()
        {
            Aufgabenzahl_ges=5;
            Aufgabenzahl_ges_richtig=0;
        }
    };
    #endif
    
    //Rechnung.cpp
    #include "Projekt.h"
    int rechne(struct Analyse& Ana1)//das richtige Objekt wird als Parameter übergeben
    {
      ...
      if (Eingabe==Rechnungsergebniss) 
      {
        Ana1.Aufgabenzahl_ges_richtig=Ana1.Aufgabenzahl_ges_richtig+1;
      }
      ...
    }
    
    //main.cpp
    #include "Projekt.h"
    #include "Rechnung.h"
    ...
    int main()
    {
      ...
      struct Analyse myAna;
      int erg = rechne(myAna);
      ...
    }
    

    (Ja, ich weiß selber, daß die ganzen "struct" vor den Variablen-Definitionen redundant sind)



  • Danke schonmal für Deine Hilfe. Leider habe ich das Problem immer noch nicht ganz behoben bekommen, weil das Programm doch insgesamt noch etwas komplexer ist. Auch wenn es etwas mehr ist, poste ich den wichtigen Teil jetzt einfach mal. Ich hoffe damit kann jemand etwas anfangen.
    Das Problem ist, dass ich mein Menü immer wieder aufrufen muss bis der Benutzer es beendet. Deshalb hab ich das jetzt so versucht:

    main.cpp
    
    int main()
    {
    	struct Analyse myAna;
    	bool M=1;
    
    	while (M)
    	{
    		M=Menue(myAna);
    	}
    
    	system("PAUSE");
    	return 0;
    }
    
    Menue.cpp
    bool Menue(struct Analyse& Ana1)
    {
    	char Operator;
    	int Aufgabenzahl;
    	bool Start;
    	bool Ergebnisse;
    
    	cout << "Willkommen zum Rechentrainer!" << endl;
    	cout << "Geben Sie 0 zum Beenden des Programms ein, ansonsten 1" << endl;cin >> Start; cout << endl;
    
    	if (Start==0) 
    	{
    		cout << "Danke, dass Sie den Rechentrainer benutzt haben!" << endl;
    		AuswertungProzent(Ana1.Aufgabenzahl_ges_richtig, Ana1.Aufgabenzahl_ges);
    		return 0;
    	}
    	else 
    	{
    		cout << "Geben Sie 0 ein, wenn Sie ihre gesamten bisherigen Ergebnisse wissen moechten. Ansonsten 1" << endl; cin>> Ergebnisse; cout << endl;
    		if (Ergebnisse==0)
    		{
    			cout << "Sie haben bisher  " << Ana1.Aufgabenzahl_ges << "  Aufgaben gerechnet." << endl;
    			cout << "Davon waren  " << Ana1.Aufgabenzahl_ges_richtig << "  Aufgaben richtig." << endl;
    		}
    		cout << "Waehlen Sie eine Rechenoperation(+ oder -): "; cin >> Operator; cout << endl;
    		cout << "Waehlen Sie ihre Aufgabenzahl: "; cin >> Aufgabenzahl; cout << endl;
    
    		Ana1.Aufgabenzahl_ges=Ana1.Aufgabenzahl_ges + Aufgabenzahl;
    		Ana1.Aufgabenzahl_ges_richtig= Ana1.Aufgabenzahl_ges_richtig+Rechnung(Aufgabenzahl, Operator);
    		cout << "Sie haben insgesamt " << Ana1.Aufgabenzahl_ges_richtig << " mal richtig gerechnet" << endl;
    		return 1;
    	}
    
    }
    

    Ich bekomme jetzt wieder den Fehler mit dem unaufgelösten Symbol. Kann es sein, dass ich meine struct-Werte wieder zurückgeben lassen muss?

    Hoffe der Code erschlägt niemanden, danke sehr! 🙂



  • Du bekommst anscheinend einen Linker Fehler. Das bedeutet, dass menue.cpp nicht korrekt zum Projekt hinzugefügt wurde.



  • Ich glaube nicht. Wenn ich mein struct global im Menue verkünde, läuft das Programm. Der komplette Fehler zu dem Code oben heißt

    1>main.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""bool __cdecl Menue(struct Analyse)" (?Menue@@YA_NUAnalyse@@@Z)".
    1>C:\uni\c++\Projekt 1. Semester(Rechentester)\Projekt\Debug\Projekt.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.



  • Hast du die Referenz bei der Deklaration der Funktion angegeben?

    // Code
    bool Menue(struct Analyse& Ana1)
    
    // Fehlermeldung
    bool Menue(struct Analyse)
    

    Ausserdem kannst du das struct vor Variablendeklarationen weglassen, das macht niemand in C++.



  • Ah danke, hab tatsächlich vergessen die Fkt. richtig zu deklarieren 😉

    Danke an alle für die Hilfe!


Anmelden zum Antworten