#define #ifdef #ifndef



  • #define ist stupide Textersetzung. Wenn die definierte Zeichenfolge irgendwo gefunden wird (natürlich nach dem #define), dann wird sie durch das definierte ersetzt.

    Bsp:

    #define foo {bar(); baz();}
    
    // ...
    foo;
    

    wird zu:

    {bar(); baz();};
    

    #include ist genauso dumm: Es schreibt die zu inkludierende Datei (d.h. den Inhalt) dorthin wod er include Befehl steht:

    // A.h
    void foo()
    {
        cout << "lol" << endl;
    }
    
    // B.cpp
    #include "A.h"
    
    void bar()
    {
        foo();
    }
    

    wird zu:

    // B.cpp
    void foo()
    {
        cout << "lol" << endl;
    }
    
    void bar()
    {
        foo();
    }
    

    Da nun aber gerade Klassen nicht mehrfach definiert werden dürfen, es sogar schon bei kleinen Projekten dazu kommt, dass mehrere Dateien eine gleiche Datei inkluden, muss Abhilfe geschaffen werden.

    Das macht man, indem man prüft ob ein bestimmtes Symbol schon definiert worden ist und wenn nein, dann definiert man es und schreibt gleichzeitig seinen Dateiinhalt dorthin. Beim nächsten include ist das Symbol nun definiert und es wird nix von der Datei dahingeschrieben.

    // A.h
    #ifndef A_h_
    #define A_h_
    class Foo{};
    #endif
    
    // B.h
    #ifndef B_h_
    #define B_h_
    #include "A.h"
    
    class Bar{};
    
    #endif
    
    // C.h
    #ifndef C_h_
    #define C_h_
    
    #include "A.h" // wird inkludiert, damit wird das A_h_ Symbol definiert
    #include "B.h" // wird inkludiert, aber darin wird A.h nicht inkludiert, da ja das A_h_ Symbol definiert ist schon
    
    class Foobar
    {
        Foo f;
        Bar b;
    };
    #endif
    


  • Ein Beispiel war auch gerade: http://www.c-plusplus.net/forum/p2374853#2374853



  • So ich habe mir das nochmal durchgelesen.
    Und ich erkläre euch mal ob ich das richtig verstanden habe 😃

    Also man inkludiert in der "main()" Datei eine .h (header) Datei die man vorher erstellt. In dieser .h Datei kommt dann soetwas wie :

    #ifndef FILENAME_H_INCLUDED
    #define FILENAME_H_INCLUDED
    #endif // FILENAME_H_INCLUDED
    

    und Funktionsprototypen (aber auch andere "Bausteine").
    Und in dieser .h Datei ist nocheinmal eine .cpp Datei includiert die die z.b. komplette FUnktion beinhaltet.

    Ist das so richtig verstanden?



  • Nicht ganz, .cpp oder .c Dateien werden normalerweise nie #included, sondern alle separat kompiliert (zu Objektdateien), und diese Objektdateien werden dann zu einer ausführbaren Datei zusammen gelinkt. Den Compiler interessieren (außer bei inline etc.) nur die Funktionsdeklarationen im Header, und erst der Linker sucht sich die passenden Definitionen.



  • Skeptar schrieb:

    Und in dieser .h Datei ist nocheinmal eine .cpp Datei includiert die die z.b. komplette FUnktion beinhaltet.

    Nein!
    Die .cpp ist eine eigenständige Datei.
    In der .h stehen die Informationen, damit man die zugehörige .cpp nutzen kann.

    Mit dem #if #ifdef #ifndef kannst du während des compilierens einfluss auf da Programmm nehmen.
    Du kannst so auf verschiedene Compiler, Betriebsysteme, Programmfunktionen, ... reagieren



  • Hey..
    ich komme immer noch nicht damit klar 😃
    Wie verbinde ich die 3 Teile nun mit einander???

    main.cpp

    #include <iostream>
    #include "funktionen.h"
    
    using namespace std;
    
    int main(){
         return 0;
    }
    

    funktionen.h

    #include "funktionen.cpp"
    

    funktionen.cpp

    #include <iostream>
    
    using namespace std;
    
    int main(){
         return 0;
    }
    

    Ist die Verbindung nun so richtig?? 😕 😕 😕



  • Nein, ist komplett falsch.

    // Funktionen.h
    #ifndef Funktionen_h_
    #define Funktionen_h_
    
    void func();
    
    #endif // Funktionen_h_
    
    // Funktionen.cpp
    #include "Funktionen.h"
    #include <iostream>
    
    void func()
    {
        std::cout << "Hallo Welt" << std::endl;
    }
    
    // Main.cpp
    #include "Funktionen.h"
    #include <iostream>
    
    int main()
    {
        std::cout << "Meine Funktion sagt: ";
        func();
    
        return 0;
    }
    


  • Danke dir! 😃 😃 😃
    Aber habe noch eine letzte Frage in diesem Thread:
    Warum schreibt man das so?

    // Funktionen.h
    #ifndef Funktionen_h_
    #define Funktionen_h_
    
    void func();
    
    #endif // Funktionen_h_
    

    Hinter #ifndef & #define das "Funktionen_h_" (die unterstriche _) warum sind die dort.



  • Skeptar schrieb:

    Hinter #ifndef & #define das "Funktionen_h_" (die unterstriche _) warum sind die dort.

    Die simulieren den Punkt im Dateinamen. Wenn deine Datei Hans.h heißt, dann eben #ifndef HANS_H



  • Aber wenn ich eine Header Datei erstelle schreibt der mit hin "FUNKTION_H_INCLUDED" muss das "_INCLUDED" stehen?



  • Skym0sh0 schrieb:

    Nein, ist komplett falsch.

    // Funktionen.h
    #ifndef Funktionen_h_
    #define Funktionen_h_
    
    void func();
    
    #endif // Funktionen_h_
    
    // Funktionen.cpp
    #include "Funktionen.h"
    #include <iostream>
    
    void func()
    {
        std::cout << "Hallo Welt" << std::endl;
    }
    
    // Main.cpp
    #include "Funktionen.h"
    #include <iostream>
    
    int main()
    {
        std::cout << "Meine Funktion sagt: ";
        func();
    
        return 0;
    }
    

    Genau so habe ich das nun gemacht.. Aber der Compiler sagt mir "undefined reference to 'func()'"
    Es kann natürlich sein ob ich bei der Datei erstellung etwas falsch gemacht habe.
    Ich benutze den Compiler COde::Blocks und und bin oben auf File -> New -> File und dann habe ich 2x .cpp genommen und 1x .h habe die halt benannt, und in einen Ordner gepackt.



  • Du musst die Datei Funktionen.cpp noch zu deinem Projekt hinzufügen.
    Es sollte also links in der Liste unter Sources zu sehen sein.
    (Management ->Projects)
    Falls du das Fenster nicht hast, drück Shift-F2.



  • Okey alles super danke!! 🙂



  • Okey alles super danke!! 🙂
    Aber immer noch die Frage:

    Aber wenn ich eine Header Datei erstelle schreibt der mit hin "FUNKTION_H_INCLUDED" muss das "_INCLUDED" stehen?



  • Skeptar schrieb:

    Aber wenn ich eine Header Datei erstelle schreibt der mit hin "FUNKTION_H_INCLUDED" muss das "_INCLUDED" stehen?

    Nein. Du kannst das #define auch HANS_WURST nennen.
    Man sollte aber aussagekräftige Symbole nehmen, wie immer in der Programmierung.
    Das ist dem Präprozessor egal.
    Es ist ein Schutz, damit die gleiche .h Datei nicht öfters inkludiert wird als notwending, da das zu Fehlern führt. Nennt man auch einen Include Guard.
    Jedesmal, wenn der Präprozessor auf eine #include Anweisung stößt, versucht er die Datei vor die Datei zu setzen in der es auftrat. Diese Präprozessor Anweisung sorgt dafür, dass ein Symbol (HANS_WURST) definiert wird, wenn das das erste mal geschieht. Dann wird die Datei eingesetzt. Ansonsten eben nicht.

    #ifndef HANS_WURST  // <- Ist HANS_WURST definiert? Wenn ja, abbruch
    #define HANS_WURST  // <- Nein, also wird HANS_WURST definiert
    class foo
    {};
    #endif             // <- Ende der Anweisung an den Präprozessor
    

Anmelden zum Antworten