Unterschied #define zu const



  • Hallo, kann mir jemand bitte sagen was der Unterschied zwischen "#define" und "const" ist. Welche Vor. bzw. Nachteile ergeben sich.



  • Die beiden Sachen haben eigentlich nicht wirklich viel miteinander zu tun.
    Durch define kannst du Textersetzungen vornehmen die der Präprozessor auswertet. Schreibst du also

    #define bla 3
    

    und verwendest es zum Beispiel als Rückgabewert

    return bla;
    

    dann kommt beim Compiler nur noch

    return 3;
    

    an.

    Mit const erzeugst du sozusagen schreibgeschützte Werte. Damit versicherst du dem Compiler das sich der Wert zur Laufzeit nicht mehr ändert.



  • const ist typsicher.


  • Administrator

    Und für konstante Variablen sollte const gegenüber #define vorgezogen werden. Der Grund ist, dass der Präprozessor ein sehr dummes Tool ist. Es kümmert sich kein bisschen um die Syntax, sondern ersetzt einfach nur den Text und dies überall. Einfaches Beispiel:

    #define MeineKonstante 20
    
    enum MeinEnum
    {
      MeineKonstante,
      DeineKonstante,
      UnsereKonstante
    };
    
    // ...
    

    Dieser Code wird nicht kompilieren, weil der Präprozessor im enum MeinKonstante durch 20 ersetzt. Der Kompiler bekommt somit diesen Code vorgelegt:

    enum MeinEnum
    {
      20,
      DeineKonstante,
      UnsereKonstante
    };
    

    Grüssli



  • Aus diesem Grund nennt man diese Makro-Konstante nicht MeineKonstante sondern MEINE_KONSTANTE und diese Schreibweise ist m.E. schon Grund genug const zu verwenden.

    Ein Vorteil von define der mir einfällt ist, dass die Konstanten sich ohne Laufzeitaufwand zu zusammensetzen lassen:

    #define MEINE_KONSTANTE 20
    const char s[] = "Meine Konstante " #MEINE_KONSTANTE " in einem konstanten String";
    

    Mit C++ und ints ist dies eventuell mit TMP möglich, aber sobald Nachkommastellen auftreten musst du mit Konstanten geringste Geschwindigkeitseinbussen in Kauf nehmen.

    #define ERSTE_KONSTANTE 618
    #define ZWEITE_KONSTANTE 033988 // Die 0 wird unten übernommen
    #define GOLDENER_SCHNITT 1.##ERSTE_KONSTANTE##ZWEITE_KONSTANTE
    

    So etwas braucht jedoch kein Mensch und die Nachteile von defines sind überwältigend: nicht typsicher, keine namespaces, nicht als const-reference benutzbar, schlechtere Optimierung vom Compiler, nichtsaussagende Fehlermeldungen, tausende Fehlerquellen mit Addition ohne Klammern, kein C++-artiger Code, ...
    defines vermeiden, dass man ihre Adresse nimmt, das kann man als Vorteil oder Nachteil sehen.

    Ein wirklicher Grund für defines sind ihre Verwendung als Angabe zur Grösse eines Array bzw. Templateparameters. Mit dem neuen Standard gehört das aber der Vergangenheit an.



  • altarch schrieb:

    #define ZWEITE_KONSTANTE 033988 // Die 0 wird unten übernommen
    

    Übrigens: Oktalzahlen dürfen keine 8 oder 9 enthalten.



  • altarch schrieb:

    Ein Vorteil von define der mir einfällt ist, dass die Konstanten sich ohne Laufzeitaufwand zu zusammensetzen lassen:

    #define MEINE_KONSTANTE 20
    const char s[] = "Meine Konstante " #MEINE_KONSTANTE " in einem konstanten String";
    

    Kleiner Haken: Das klappt so nicht. Diese "Stringifikation" ist nur bei Parametern von Funktions-Makros erlaubt. Man müsste es so schreiben:

    const char s[] = "Meine Konstante " STRINGIFY(MEINE_KONSTANTE) " in einem konstanten String";
    

    wobei STRINGIFY entsprechend definiert werden muss:

    #define STRINGIFYX(x) #x
    #define STRINGIFY(x) STRINGIFYX(x)
    

    kk



  • Vielen Dank für die Antworten!!


Log in to reply