Globale Variablen werden nicht erkannt



  • ich hab übrigens das buch genommen, war aber irgendwann ziemlich frustrierend wenn die lösungen der übungen ganz anders waren als ich es gemacht hab...



  • Microsoft Visual C++ 2010

    Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.



  • Ki schrieb:

    Microsoft Visual C++ 2010

    Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.

    ... führe damit zwei Hallo-Welt-Programme aus, einfach um mal zu sehen was man da alles machen muss und kehre dann wieder zurück zu einer der produktivsten IDEs, nämlich Visual Studio.



  • Ki schrieb:

    Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.

    Klar, wenn man mit dem Programmieren nicht klar kommt, sollte man sich noch zusätzliche Hürden in den Weg legen. Lass ihn doch erst mal seinen eigenen Prozessor zusammenlöten 🙄

    OP: Deine Frage wurde zwar schon beantwortet, aber IMHO nicht auf einem anfängerfreundlichen Niveau. Damit dem Compiler eine (globale) Variable bekannt ist, muss sie vorher, d.h. weiter oben im Quelltext, deklariert worden sein.

    Welche Dateien übersetzt dein Compiler? Jede cpp-Datei bildet eine sogenannte Übersetzungseinheit, die sich der Compiler dann anschaut. Die h-Dateien werden nur jeweils genau dann kompiliert, wenn sie in einer Übersetzungseinheit inkludiert werden. Inkludieren heißt nichts anderes als reine Textersetzung. Wo also #include "foo.h" steht, könntest du genauso gut den Inhalt von foo.h hinschreiben.

    Wo stehen die include-Anweisungen? In aller Regel am Anfang einer Datei. Davon solltest du auch nicht abweichen. Wenn du also in der main.cpp oben foo.h inkludierst und weiter unten eine globale Variable deklarierst, die foo.h braucht, kann das nicht funktionieren: Der Compiler ersetzt die include-Anweisung durch den Quellcode aus foo.h, der die globale Variable braucht, d.h. dieser Code steht vor der Deklaration der globalen Variable. Das führt dann natürlich zu einem Fehler.

    Komm jetzt nicht auf die Idee und deklariere die globale Variable vor der include-Anweisung. Damit kommst du nur in Teufels Küche. Überlege dir stattdessen, dass du die globale Variable gar nicht benötigst. Du könntest beispielsweise den Funktionen aus foo.h, die die Variable benötigen, einen entsprechenden Parameter verpassen.



  • und was ist wenn ich mehrere cpp dateien habe? da werden die elemente der einen in der anderen auch nicht erkannt. ich hab eine klasse und ein array mit zeigern auf objekte dieser klasse. wenn ich das objekt sich selbst aus dem array entfernen lassen will muss ich ja auf das array zugreifen, soll ich das dann jedes mal im konstruktor übergeben oder geht das auch anders?


  • Mod

    1. Globale Variablen sind abenteuerlich, besser sein lassen.
    2. Arrays sind abenteuerlich, besser sein lassen, Containerklassen benutzen
    3. Zeiger sind auch abenteuerlich. Sicher, dass du sie brauchst? (Tipp: Höchstwahrscheinlich nicht)
    4. Arrays von Zeigern sind somit doppelt abenteuerlich.
    5. Globale Arrays aus Zeigern sind somit das fehleranfälligste, was irgendwie möglich ist.
    6.

    wenn ich das objekt sich selbst aus dem array entfernen lassen will

    Auch ein abentuererliches Vorhaben. Beschreib lieber mal, was du erreichen möchtest, nicht wie du dir die technische Lösung vorstellst. Die technische Lösung ist bei dir nämlich von deinem mangelndem Verständnis geprägt und von den abenteuerlichen Techniken, die du in dem Buch beigebracht bekommen hast.

    Mit diesen Hinweisen nun die Antwort auf deine Frage, die du dann hoffentlich nicht benutzt, weil dir die Hinweise zu Herzen nimmst:

    class_header.h

    // Bei den Headern Includeguards nicht vergessen, schreibe ich aber nicht explizit hin
    
    class foo
    {
     // Bla
    };
    

    global_array_header.h

    #include "class_header.h" // Eine forward-Definition würde hier auch reichen, da du nur Zeiger auf foo benutzt
    
    extern foo *array[1234];
    

    main.cc

    #include "global_array_header.h"
    #include "class_header.h"
    
    // Code der foos und das array benutzt
    

    class_implementation.cc:

    #include "global_array_header.h"
    #include "class_header.h"
    
    // Code der foos und das array benutzt
    

    global_array_implementation.cc

    #include "class_header.h"
    
    foo *array[1234];
    


  • Nikolai schrieb:

    ...

    Du hast selbst gesagt, das du bereits ein Buch gelesen hast, ich behaupte das darin auch auf die Trennung von Headern und Sourcedateien intensiv eingegangen wurden ist. Und dieses Thema solltest du dir nochmals intensiv zur Brust nehmen.

    Prinzipiell: cpp-Dateien sollten niemals voneinander abhängig sein, Header dienen der Deklaration (und in der jeweiligen Source steht die Implementierung). Und dann inkludiert man diese Header wo sie benötigt werden ein.

    Ganz davon abgesehen sind globale Variablen ohnehin nur in Ausnahmen sinnvoll.



  • was ich vorhabe ist, den server anfragen von clients annehmen zu lassen. dafür hab ich eine client klasse erstellt wo die infos wie der socket und die sockaddr infos drinne sind. hab jetzt versucht ein struct an den konstruktor übergeben zu lassen, nichtmal das funktioniert.

    struct CltInfo{
    	int pos;
    	SOCKET s;
    	sockaddr addr;
    	Client *** clients;
    	int* cltcnt;
    };
    

    in der zeile mit Client *** clients; kommt der fehler
    error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'clients'
    vieleicht weil die klasse erst danach definiert wurde... und wenn ich die struktur erst danach definiere dann kommt fehler mit undefiniertem struct.


  • Mod

    Nikolai schrieb:

    error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'clients'
    vieleicht weil die klasse erst danach definiert wurde...

    Sogar ganz sicher aus diesem Grund.

    und wenn ich die struktur erst danach definiere dann kommt fehler mit undefiniertem struct.

    Welcher genau?

    Wie auch immer:
    1. Hier reicht eine Forward-Declaration:

    class Client;
    
    struct CltInfo{
        int pos;
        SOCKET s;
        sockaddr addr;
        Client *** clients;
        int* cltcnt;
    };
    

    Aber setz das nicht voreilig ein, denn:
    2. Dein Code ist grauenhaft und wird bestimmt nur mit vielen Schmerzen zum Laufen gebracht werden. Du bist nämlich im wahrsten Sinne des Wortes ein Drei-Sterne-Programmierer:
    Google: three star programmer
    Abstraktion und klares Design helfen ungemein bei der Fehlervermeidung!
    3. So wie es aussieht, hast du irgendeinen C/C++-Mischmasch gelernt. Damit wirst du Schwierigkeiten bekommen, besonders da dein Projekt durchaus anspruchsvoll zu sein scheint. Da ist saubere Programmierung in einer Sprache Pflicht, wenn du jemals zu einem brauchbaren Ergebnis kommen möchtest. Dazu müsstest du natürlich zuerst eine der Sprachen richtig lernen.



  • Michael E. schrieb:

    Klar, wenn man mit dem Programmieren nicht klar kommt, sollte man sich noch zusätzliche Hürden in den Weg legen. Lass ihn doch erst mal seinen eigenen Prozessor zusammenlöten 🙄

    Es geht nicht um Hürden, sondern um Verständnis 😉



  • http://c2.com/cgi/wiki?YouMightBeaThreeStarProgrammer

    @SeppJ: Genial. Leider traf nur eine einzige Sache zu:
    Ich benutze wo möglich den Ternären Operator um If-Statements zu vermeiden.

    @Ki: Als Anfänger braucht man dein "Verständnis" nicht. Deswegen ist man ja auch "Anfänger", weil man es nicht versteht 😉 Vor allem sollte man nicht versuchen, Anfänger mit komplexen Zeug zu verunsichern oder wegzuschrecken.


Anmelden zum Antworten