define und const



  • dot schrieb:

    int pi;
    

    Ääääh...



  • Wenn du's so abwegig findest, dann mach ein int* draus...



  • nochmal meine Frage...

    Wir können auch statt Pi die Antwort auf Alles (42) nehmen.
    Die ist sicherlich nicht in irgendeiner Bibliothek drin 😉
    Da sich die Antwort auf alles nicht ändert, ist es besser, diese als globale Variabel const int antwort_auf_alles=42; zu nehmen oder #define ANTWORT_AUF_ALLES 42 ?

    Ich denke, da hat vielleicht jede seine eigenen Bevorzugungen, aber was mich eher interessiert, ist, warum?



  • const int. Begründung siehe oben.



  • Bei Integern würde ich

    enum {
      ANTWORT_AUF_ALLES = 42
    };
    

    schreiben. Das Problem mit Makros ist, dass sie keine Scopes respektieren, also völlig legalen Code zerstören können. Ich hatte grad letztens erst einen Fall, in dem ein Makro genau so hieß wie eine Funktion und der Compiler sich darüber beschwerte, dass er

    static double 100000000() { ... }
    

    übersetzen sollte. So was ist lustig zu debuggen, wenn man nicht alle alten Header auswendig kennt.

    Umgekehrt lassen sich int-Konstanten zumindest in C89 nicht überall verwenden. Beispielsweise ist

    int const ANTWORT_AUF_ALLES = 42;
    int array[ANTWORT_AUF_ALLES]; /* Kawumm. */
    

    dort nicht erlaubt. Da nicht alle gängigen Compiler (hust, MSVC, hust) C99 unterstützen, ist das bis auf weiteres ein Problem.

    enum vereinigt da aus meiner Sicht das beste der beiden Welten.

    Bei Fließkommakonstanten besteht das zweite Problem nicht, also ist da prinzipiell double const besser. Allerdings bin ich mir aus dem Stand nicht sicher, wie es sich da bei den gängigen Compilern mit constant folding während der Optimierung verhält. Wahrscheinlich würde ich

    static double const pi = 3.141592653589; /* Press das mal in einen int, dot. */
    

    schreiben.



  • Mir ist nicht ganz klar was du mit deinem Kommentar bezüglich "in einen int pressen" meinst!?
    Ich hab auch nie was anderes gesagt als const verwenden 😕
    Mein Beispiel mit dem int diente genau dazu, das von dir mittlerweile ebenfalls erwähnte Problem von Makros vs. Scope zu illustieren...



  • Naja, Pi als int (also als Ganzzahl) darstellen zu wollen, hat schon etwas merkwürdiges.

    Übrigens, was die Scope-Geschichte angeht - auch

    struct Foo {
      double pi;
    };
    

    funktioniert nicht wirklich gut als Namensraum, und static geht in C ja an dieser Stelle nicht. Man könnte womöglich

    static struct {
      double one;
      double zero;
      double pi;
      double e;  
    } const math_constants = {
      1.0,
      0.0,
      3.1415926535897932384626434,
      2.7182818284590452353602875
    };
    
    double circle_area(double radius) {
      return 2 * math_constants.pi * radius;
    }
    

    schreiben, aber die Funktionalität ist gegenüber echten Namensräumen, wie man sie von C++ kennt, natürlich stark eingeschränkt, und ob man jetzt MATH_CONSTANTS_PI oder math_constants.pi da stehen hat, ist letztendlich ohne Bedeutung.



  • Einzig der Vorteil bei Strukturen ist, dass man die einzelnen Konstanten und Namen nicht auswendig kennen muss. Kennt man den Structurnamen, werden einem (je nach Entwicklungsumgebung) die darin enthaltenen Elemente angezeigt. Aber dies ist rein gesehen eine sache des Komforts 😉

    Mir wurde damals im ersten Jahr Programmieren reingedrückt, ich solle Makros (Problemstellung wurde oben genannt) mit Vorsicht genießen. Daher verwende ich für PI ne globale Variable vom Typ const double. Auf Define greife ich in VC nur für die Länge der statischen Arrays zu, da es nicht
    immer nötig ist solche Dynamisch auf dem Heap anzulegen 😉



  • seldon schrieb:

    Naja, Pi als int (also als Ganzzahl) darstellen zu wollen, hat schon etwas merkwürdiges.

    Wir reden aneinander vorbei, darum gings nie. Das Beispiel mit dem struct sollte zeigen was passiert wenn du ein #define pi hast und dann irgendo sonst im Programm der Bezeichner pi vorkommt. Mach einen int* draus und du hast gern mal irgendwo ein pi, nicht wegen dem griechischen Buchstaben, sondern z.B. wegen ungarischer Notation (um weiteren Missverständnissen vorzubeugen: Nein die empfehle ich nicht)...



  • DrakoXP schrieb:

    Also weder noch beantwortet seine Frage wirklich :S

    @Swordfish: auch wenn viele Standarbibliotheken M_PI beinhalten mögen, so ist es dennoch nicht Teil des ANSI Standards.

    Echt ned?

    In dem Fall nimmst ein const double mit sinnigem Namen und und irgendeinen Wert, der in richtung pi geht 🤡


Anmelden zum Antworten