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 Formatstringprintf ( %<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
Beiprintf
muss der Formatspecifier zum übergebenen Wert passen.
Es werden soviel Byte ausgewertet, wie zum Specifier passen.
Bei%d
sind dassizeof(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 einenint
. Wenn du zweiint
Variablen addierst bekommst du ebenso einenint
. Und wenn du zweilong
Variablen addierst bekommst du halt einenlong
. 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 Typint
. Ansonsten wird der kleinste Typ genommen mit dem es sich ausgeht (alsolong int
oderlong 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!