C - Wertzuweisung



  • Hallo,

    ich habe mal eine allgemeine Frage und hoffe mein Verständnis verbessert sich dadurch.

    Ist immer so bei Zahlenwerten in C

    dass,

    wenn man

    Zahlendatentyp bezeichner = <hier eine Zahl die größer als der Wertebereich des Zahlendatentyps ist>

    macht, das ein Überlauf stattfindet, dass heißt wie am anderen Ende des Wertebreichs des Typ weiter zählt?

    Ist dies auch bei float, double und char so?

    Zeite Frage passiert das selbe also auch ein Überlauf wenn ich
    in einem Formatstring

    printf ( %<Zahlenplatzhalter> , <hier eine Zahl die größer als die Speichergröße des Zahlenplatzhalters - entspricht
    diese Speichergröße dann genau seinem Wertebereich?>

    Kann man wenn man das weiß also auch sowas machen

    unsigned long long zahl = 200000000000000000000000000000000000000000000000000ull

    also werte die der Computer eig gar nicht speicher kann zuweisen und der macht dann den Überlauf?

    Danke,
    James



  • @JamesNguyen
    Bei printfmuss der Formatspecifier zum übergebenen Wert passen.
    Es werden soviel Byte ausgewertet, wie zum Specifier passen.
    Bei %d sind das sizeof(int) . Wenn der übergebene Wert mehr hat, hast du UB (Undefined Behavior) - da darf Alles passieren.

    Du musst da ganz stark aufpassen - und die Warnungen vom Compiler ernst nehmen (am Besten auf stärkster Stufe)



  • @JamesNguyen sagte in C - Wertzuweisung:

    Ist immer so bei Zahlenwerten in C
    dass,
    wenn man
    Zahlendatentyp bezeichner = <hier eine Zahl die größer als der Wertebereich des Zahlendatentyps ist>
    macht, das ein Überlauf stattfindet, dass heißt wie am anderen Ende des Wertebreichs des Typ weiter zählt?
    Ist dies auch bei float, double und char so?

    Das steht in § 6.3.1.3 Signed and unsigned integers in n2454.pdf.



  • @JamesNguyen
    Du solltest dringend ein paar Grundlagen lernen. Und dazu ist das Forum nicht da. Das solltest du dir selbst aneignen.

    Ein paar Dinge die du wissen solltest:

    • C ist statisch typisiert. Google danach und lies dir durch was das bedeutet.
    • Wenn du in C eine Variable mit einem bestimmten Type definierst, dann bekommst du natürlich immer genau diesen Typ. Es ist mir rätselhaft wie man annehmen kann es könnte anders sein.
    • Der Typ von Ausdrücken in C hat nichts mit den Werten von irgendwelchen Variablen zu tun, sondern immer nur mit den Typen der Operanden. Wenn du z.B. zwei char Variablen addierst, dann bekommst du immer einen int. Wenn du zwei int Variablen addierst bekommst du ebenso einen int. Und wenn du zwei long Variablen addierst bekommst du halt einen long. Bei unterschiedlicher Grösse gewinnt der grössere. Das selbe bei anderen Rechenarten. Die genauen Regeln dazu kannst du in einem Buch deiner Wahl oder auch auf diversen Seiten im Internet nachlesen.

    Beispiel:

    // Annahme: INT_MAX = 2147483647, LLONG_MAX = 9223372036854775807 (übliche Werte)
    
    void fun() {
        int a = 10;
        int b = 20;
        printf("%d", a * b); // Ergebnis von a * b ist wieder ein int, mit Wert 200,
        // und der wird ausgegeben. Alles OK.
    }
    
    void fun2() {
        int a = 1234567;
        int b = 1000000;
        printf("%d", a * b); // Ergebnis von a * b wäre auch hier ein int.
        // Allerdings undefiniertes Verhalten, da es zu einem Überlauf kommt,
        // und mit int darfst du keinen Überlauf machen (mit unsigned int dürftest du).
    }
    
    void fun3() {
        long long a = 10;
        long long b = 20;
        printf("%d", a * b); // Ergebnis von a * b ist long long.
        // Undefiniertes Verhalten da %d nicht zu long long passt.
    }
    
    void fun4() {
        long long a = 10;
        long long b = 20;
        printf("%lld", a * b); // Ergebnis von a * b ist long long. OK in C99, gibt 200 aus.
    }
    
    void fun5() {
        long long a = 1234567;
        long long b = 1000000;
        printf("%lld", a * b); // Ergebnis von a * b ist long long. OK in C99, gibt 1234567000000 aus.
    }
    
    • Der Typ von Literalen (also Zahlen die du einfach so als Zahlen hinschreibst) ist in C99 allerdings von der Zahl abhängig. Für alles was in einen int passt ist der Typ int. Ansonsten wird der kleinste Typ genommen mit dem es sich ausgeht (also long int oder long long int).

    Und noch eine Anmerkung zu "Undefiniertes Verhalten": das bedeutet nicht dass die Zahl die ausgegeben wird undefiniert ist. Es bedeutet dass dein Programm falsch ist. Undefiniertes Verhalten bezieht sich auf das ganze Programm, d.h. das ganze Programm ist "undefineirt". D.h. es kann z.B. auch einfach abstürzen. Es kann aber blöderweise auch wie gewünscht funktionieren - undefiniertes Verhalten ist keine Garantie für einen Fehler. Daher ist auch "funktioniert aber" keine sinnvolle Antwort darauf wenn dir jemand sagt etwas sei falsch.



  • @Swordfish sagte in C - Wertzuweisung:

    @JamesNguyen sagte in C - Wertzuweisung:

    Ist immer so bei Zahlenwerten in C
    dass,
    wenn man
    Zahlendatentyp bezeichner = <hier eine Zahl die größer als der Wertebereich des Zahlendatentyps ist>
    macht, das ein Überlauf stattfindet, dass heißt wie am anderen Ende des Wertebreichs des Typ weiter zählt?
    Ist dies auch bei float, double und char so?

    Das steht in § 6.3.1.3 Signed and unsigned integers in n2454.pdf.

    Achje, jetzt hab ich erste verstanden was er meint.

    @JamesNguyen
    Kurze Antwort: nein, das ist nicht garantiert.
    Praktisch wäre es auf den meisten Systemen so. Allerdings ist es praktisch auch so dass du eine Warning vom Compiler bekommst wenn du das schreibst.



  • Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten