#ifndef #define



  • Hallo miteinander

    ich verstehe die Anweisung einfach nicht #ifndef #define, so wird mehrfach inkluding verhindert oder?

    Kann mir jemand geaueres über das erzählen, für was man #ifndef #define benutzt!

    Danke AnfängerC++



  • anfängerc++ schrieb:

    ich verstehe die Anweisung einfach nicht #ifndef #define, so wird mehrfach inkluding verhindert oder?

    Die Sachen, die mit '#' beginnen, sind Präprozessordirektiven. Der Präprozessor geht das Programm noch vor dem Compiler durch und löst all die Direktiven auf. Wenn du z.B.
    #define BLABLA 4
    schreibst, ersetzt der Präprozessor jedes BLABLA im Code durch 4.
    Abschnitte, die von
    #ifdef BLABLA
    und
    #endif
    umgeben sind, werden nur an den Compiler weitergegeben, wenn BLABLA vorher durch #define definiert wurde (ifdef == if defined). ifndef (== if !defined) ist die Umkehrung, tritt also ein, wenn BLABLA nicht definiert wurde.
    Wenn nun eine Headerdatei eingebunden wurde, wird überprüft, ob ein Makro definiert wurde (ifndef); wenn nicht, dann wird es definiert (define) und die Headerdatei eingebunden. Wurde das Makro schon definiert, also die Headerdatei bereits eingebunden, dann wird sie nicht weitergegeben.

    Steht aber eigentlich in jedem guten C-Tutorial...



  • anfängerc++ schrieb:

    ich verstehe die Anweisung einfach nicht #ifndef #define, so wird mehrfach inkluding verhindert oder?

    Kommt darauf an.

    #ifndef, etc. sind sog. Präprozessor-Direktiven. Diese werden ausgewertet, wenn der Präprozessor den Code durchläuft.
    Eine Übersicht über die Direktiven findest du hier: http://www.cppreference.com/preprocessor/index.html.

    #ifdef, #ifndef sind im Prinzip einfache If-Abfragen, die (zum Zeitpunkt des Präprozessors) prüfen ob ein Makro definiert bzw. nicht definiert ist.

    Beispiel:

    #include <iostream>
    using namespace std;
    
    //#define HALLO_WELT
    
    int main()
    {
        #ifdef HALLO_WELT
        echo "HALLO_WELT ist definiert!\n";
        #else
        echo "HALLO_WELT ist nicht (!) definiert!\n";
        #endif
    }
    

    Kompiliere das Programm einmal ohne die Definition von HALLO_WELT und einmal mit.

    Mit Hilfe der Präprozessor-Direktiven kannst du dir jetzt z.B. auch sog. Include-Guards basteln.

    Beispiel:

    // global_header.hpp
    #ifndef GLOBAL_HEADER
    #define GLOBAL_HEADER
    
    #include <iostream>
    // ...
    
    #endif
    
    // header_a.hpp
    // benötigt global_header.hpp
    #include "global_header.hpp"
    
    ...
    
    // header_b.hpp
    // benötigt ebenfalls global_header.hpp
    #include "global_header.hpp"
    
    ...
    
    // main.cpp
    #include "header_a.hpp"
    #include "header_b.hpp"
    
    int main() { ... }
    

    Damit nicht zweimal (einmal über header_a und einmal über header_b) der Code in global_header an den Compiler weitergegeben wird, hast du die sog. Include-Guards zur Hilfe geholt.
    header_a inkludiert global_header. Dort wird als erstes geprüft, ob das Makro GLOBAL_HEADER bereits definiert ist. Wenn ja, wird nichts mehr getan (und folglich nichts aus gobal_header an den Compiler übergeben). Wenn das Makro GLOBAL_HEADER dagegen noch nicht definiert ist (was in obigem Beispiel der Fall ist), wird es definiert und der folgende Header-Inhalt später durch den Compiler compiliert.
    Im Beispiel wird nach header_a header_b inkludiert. Dieser inkludiert ebenfalls global_header. Allerdings ist jetzt das Makro GLOBAL_HEADER gesetzt (merke: header_a hat global_header bereits inkludiert), wesshalb der Inhalt von global_header von header_b nicht nocheinmal miteingebunden wird.

    Btw: Die Standard-Header machen von den Include-Guards übrigens auch Gebrauch, wesshalb das Beispiel Non-Sense ist... Ich hoffe aber trotzdem, dass dir das Prinzip klar geworden ist.

    /edit: Zu spät...

    Gruß Caipi



  • //Wenn nicht definiert..
    #ifndef _MAIN_H_
    //Definiere..
    #define _MAIN_H_
    
    //Code...
    
    //Ende..
    #endif _MAIN_H_
    

    Somit wird alles dazwischen nur 1x definiert.


Anmelden zum Antworten