Suffix(e)



  • Guten Morgen alles zusammen,

    ich habe ein Verständniss Problem, vlt. könnt Ihr mir weiterhelfen.

    Also ich habe vor ein Paar Tagen angefangen C++ zu lernen. Da ich in die Windows Programmierung einsteigen möchte habe ich mich für Visual C++ 2010 entschieden und mir das Buch Visual C++ 2010 - Das umfassende Handbuch von Galileo Computing gekauft.

    Als erstes werden da die Grundlagen von ANSI C++ behandelt.
    Bis zu den Variablen und deren Datentypen ist auch alles verständlich, nur verstehe ich leider nicht was es mit den Suffix(en) auf sich hat.

    In meinem Buch steht folgendes:
    Um Literale anderer Datentypen zu erzeugen, werden Suffixe verwendet. Diese werden hinter das Literal gesetzt. Dabei spielt die Grpß- und Kleinschreibung sowie die Reihenfolge keine Roller.

    In dem Buch C++ von A-Z steht allerdings was anders:
    Man kann an die Dezimal-, Oktal- und Hexadezimalzahlen noch ein Suffix anhängen,
    mit dem der Wertebereich einer Zahl genauer spezifiziert werden kann. Das
    Suffix u bzw. U deutet zum Beispiel an, dass es sich um eine vorzeichenlose
    (unsigned) Zahl handelt. l bzw. L gibt an, dass es sich um eine long-Zahl handelt.

    Das ist für mich als Anfänger sehr verwirrend!
    Was sind den nun Suffixe?
    Kann man damit Literale anderer Datentypen erzeugen
    Wenn ja was bedeutet das?
    Oder kann man damit den Wertebereich einer Zahl genauer spezifizieren
    😕

    Ich wäre echt sehr dankbar wenn Ihr mir das Prinzip mit den Suffixen erklären könntet und mir ein Beispiel zur Veranschalichung geben könntet.

    Vielen Dank im Voraus und viele Grüße
    Schany



  • Du hast hier 2 Fehler begangen:
    1.)Du hast Bücher von Galileo Computing gekauft.
    2.)Du hast ein Buch von Jürgen Wolf gekauft.

    Suffixe geben bei einem Literal den Typ an:

    std::cout << 1.0d; // double
    std::cout << 1.0; // ebenfalls double
    std::cout << 1.0f; // float
    std::cout << 1.0u; // unsigned
    std::cout << 1.0ul; // unsigned long
    


  • 314159265358979 schrieb:

    Du hast hier 2 Fehler begangen:
    1.)Du hast Bücher von Galileo Computing gekauft.
    2.)Du hast ein Buch von Jürgen Wolf gekauft.

    Exakt. Eine Auswahl guter Bücher findest du hier. Der "C++ Primer" ist wohl das beliebteste Buch.



  • 314159265358979 schrieb:

    Du hast hier 2 Fehler begangen:

    Suffixe geben bei einem Literal den Typ an:

    std::cout << 1.0d; // double
    std::cout << 1.0; // ebenfalls double
    std::cout << 1.0f; // float
    std::cout << 1.0u; // unsigned
    std::cout << 1.0ul; // unsigned long
    

    Also mit dem Suffix gebe ich den Typ von einem Literal an.

    Ich verstehe aber nicht wieso ich das tuen soll.

    Ein Beispiel aus meinem Buch:

    const float MWST=1.19f;
    

    hier bei wird doch der Variable MWST der Datentyp Float zugewiesen, wieso gebe ich dann dem Literal 1.19 mittels des Suffix f den Typ Float wenn der Variable schon der Typ zugeweisen ist.

    Vielen Dank
    Gruß Schany



  • Weil es ohne nochmal konvertiert werden muss. Das Suffix gehört hier einfach zur Zahl dazu, damit handelt es sich ganz initial um eine Zahl vom Typ float. Ohne f ist das standardmäßig double. Deswegen habe ich z.B. auch noch nie d als Suffix benutzt.



  • Wenn du z.B. eine Funktion mit 2 Überladungen hast:

    void do_something(double);
    void do_something(float);
    
    do_something(1.0f); // float-Version
    do_somethind(1.0d); // double-Version
    

  • Mod

    Eisflamme schrieb:

    Weil es ohne nochmal konvertiert werden muss.

    Na und?

    Wichtiger ist das eher zur Überladungsauflösung.

    edit: zu langsam...



  • Also ich fasse noch einmal zusammen.

    Wenn ich eine Variable einen Datentyp zuweise und dieser dann eine Zahl z.b.

    float zahl=5.5;
    

    Dann ist die Variable vom Typ Float.
    Die Zahl jedoch trotzdem vom Typ double.
    Ich müsste es also wie folgt machen, damit es korrekt ist:

    float zahl=5.5f;
    

    Hab ich das richtig verstanden?



  • Du kannst beides verwenden, in dem Fall ist es egal. Wichtiger ist es bei Überladungen.



  • 314159265358979 schrieb:

    Du kannst beides verwenden, in dem Fall ist es egal. Wichtiger ist es bei Überladungen.

    Mmmmhhh... also ist es ersteinmal für mich "unwichtig"? Da ich noch nicht beim Thema Überladungen angekommen bin.?

    Vielen Dank schon mal für euere Hilfe



  • Guten Morgen,
    wo siehst du bei deinen deinen beiden Zitaten nun Gegensätze?

    Suffix = etwas, das du an das Ende von etwas anhängst.
    Prefix = etwas, das du an den Anfang von etwas anhängst.

    Literal = konstanter Ausdruck:

    /*
            Ganzzahlen: 123
            Fließkommazahlen: 1.23
            Zeichen: 'a'
            Zeichenkette: "abc"
            Wahrheitswerte: true, false
            const
            Konstanten eines enum
            ...
        */
    
    /*
            Gibst du einfach so eine Ganzzahl an, ist sie vom Datentyp int.
        */
        cout << 123;
    
        /*
            Willst du z.B. nun aber eine Ganzzahl vom Datentyp long int.
        */
        cout << 123l << "oder" << 123L; // l/L = Suffix
    

    Der Datentyp bestimmt den Wertebereich. short int hat z.B. 2Byte, kann demnach nur 2^16 verschiedene Werte fassen. int hat z.B. 4Byte, kann demnach nur 2^32 verschiedene Werte fassen.

    lg



  • Guten Morgen Gugelmoser,

    Ich versteh es leider noch nicht so ganz.
    ich habe jetzt folgendes ausprobiert:

    cout << "Fließkommazahl: " << 12.12345678910 << endl;
    cout << "Fließkommazahl: " << 12.12345678910f << endl;
    

    Beide Ausgaben enden bei der 4-Nachkommastelle mit 5 (also gerundet).

    Wieso? Float hat doch 7-Stellen oder nicht?

    lg Schany


  • Mod

    Gugelmoser schrieb:

    Guten Morgen,
    wo siehst du bei deinen deinen beiden Zitaten nun Gegensätze?

    Das Galileo-Buch behauptet, Groß-/Kleinschribung spiele keine Rolle. Das ist bedingt richtig, solange man Zeichenkettenliterale weglässt (da wären es auch strenggenommen Präfixe, aber mit dem gleichen Effekt).

    JW behauptet, es würde den Wertebereich ändern. Das ist einfach nur ungenau. Es ändert sich der Typ und das ist das richtige und das wichtige.


  • Mod

    Schany schrieb:

    Wieso? Float hat doch 7-Stellen oder nicht?

    Ja, aber cout zeigt davon standardmäßig erst einmal nur 4 an, sofern du nicht erst die Darstellungsform von Fließkommazahlen änderst.



  • Was meinst Du damit?
    Sry. aber wie gesagt ich bin noch blutiger Anfänger, ich möchte jedoch verstehen was ich da mache und aus meinen Buch werde ich leider nicht schlau.

    Wann und wozu verwende ich den Suffixe?

    Bei dem Beispiel aus meinem Buch verstehe ich z.B. wie schon gesagt nicht wieso ich die Variable als Float deklariere und anschließen die Zahl den Suffix f gebe.
    Bsp. aus dem Buch:

    const Float MWST=1.19f;
    

    ist das dann nicht doppelt gemoppelt?

    Gruß
    Schany



  • Schany schrieb:

    const Float MWST=1.19f;
    

    ist das dann nicht doppelt gemoppelt?

    1.19 ist ein Literal.
    MWST ist eine Variable.

    Ein Literal hat einen Typ.
    Eine Variable hat einen Typ.
    Sind diese beiden Typen nicht kompatibel, gibt es einen Fehler.

    Lässt du das f weg, so gibt es noch einen automatischen Cast, da 1.19 vom Typ double, die Variable aber vom Typ float ist.

    lg



  • Suffix 'd' für double? Gibt's doch gar nicht.



  • void funktion(float f)
    {
        cout << "float";
    }
    
    void funktion(double d)
    {
        cout << "double";
    }
    
    int main()
    {
        funktion(1.23); // Du willst nun die Funktion für float aufrufen...
                        // Das Literal 1.23 ist aber vom Typ double...
                        // Für die Funktion mit float brauchst du aber ein Literal vom Typ float...
        funktion(1.23f);
    
        cin.get();
        return 0;
    }
    


  • Schany schrieb:

    Bsp. aus dem Buch:

    const Float MWST=1.19f;
    

    ist das dann nicht doppelt gemoppelt?

    Nein ist es nicht. Du hast hier mehrere Dinge: Zum Einen eine Deklaration/Definition einer Variablen mit Namen MWST und Typ Float (der übrigens kein C++-Typ ist, meintest du float?)
    Zum Anderen initialisierst du diese Variable mit einem Wert. Diesen definierst du durch das Literal 1.19f, auch vom Typ float (durch das Suffix)
    Folgendes wäre auch möglich:

    const float MWST=1.19; //1
    const double MWST=1.19f; //2
    const double MWST=1.19d; //3
    

    bei 1 initialisierst du die float-Variable mit einem double-Wert. Das geht nur, weil es eine implizite Konvertierung von double nach float gibt. Evtl wird hier der Compiler aber eine Warnung geben, weil double genauer als float ist und im Allgemeinen bei der Konvertierung Stellen verloren gehen können.
    bei 2 initialisierst du einen double mit einem float-Literal. Das geht, weil der Compiler eine implizite Konvertierung von float nach double erlaubt.
    bei 3 initialisierst du einen double mit einem double-Literal, hier gibts keine Konvertierung.

    Was gerade bei float und double noch angemerkt werden muss ist, dass 1.19f und 1.19 in Wirklichkeit unterschiedliche Werte haben können. Der Grund ist, dass die Variablen intern im 2er System gespeichert werden und nur eine begrenzte Anzahl von Stellen zur Verfügung steht. Vergleichbar ist das mit der Darstellung von 1/3: Während im 3er-System die Zahl mit nur einer Nachkommastelle darstellbar ist (0,1)3, ist sie im Dezimalsystem eine periodische Zahl und mit begrenzter Genauigkleit nicht exakt darstellbar.

    Beispiel:

    #include <iostream>
    #include <iomanip>
    using std::cout;
    
    int main()
    {
      float f= 1.19f;
      double d = 1.19;
      cout << setprecision(20) << f << '\n' << setprecision(20) << d << '\n';
    }
    

    Output:

    1.1900000572204589844
    1.1899999999999999467
    


  • krümelkacker schrieb:

    Suffix 'd' für double? Gibt's doch gar nicht.

    http://ideone.com/LOnUH 😉


Anmelden zum Antworten