Was bedeutet ‘u’ nach einer Zahl?

Lesezeit: 5 Minuten

Benutzeravatar von Lodhart
Lodhart

Können Sie mir sagen, was genau das bewirkt u nach einer Zahl, zum Beispiel:

#define NAME_DEFINE 1u 

Benutzeravatar von Lundin
Lundin

Ganzzahlige Literale wie 1 in C-Code sind immer vom Typ int. int ist dasselbe wie signed int. Man fügt hinzu u oder U (äquivalent) zum Literal, um sicherzustellen, dass es unsigned int ist, um verschiedene unerwartete Fehler und seltsames Verhalten zu verhindern.

Ein Beispiel für einen solchen Fehler:

Auf einem 16-Bit-Rechner, auf dem int 16 Bit ist, führt dieser Ausdruck zu einem negativen Wert:

long x = 30000 + 30000;

Beide 30000-Literale sind int, und da beide Operanden int sind, ist das Ergebnis int. Ein 16-Bit-Int mit Vorzeichen kann nur Werte bis zu 32767 enthalten, sodass es überläuft. x wird dadurch einen seltsamen, negativen Wert erhalten, anstatt wie erwartet 60000.

Der Code

long x = 30000u + 30000u;

wird sich jedoch wie erwartet verhalten.

  • this expression will result in a negative value. Nun, oder Dämonen fliegen aus Ihrer Nase, da Integer-Überläufe undefiniertes Verhalten sind.

    – au

    27. Januar 2012 um 9:01 Uhr

  • @ouah Theoretisch ja. In der realen Welt behandeln alle Compiler, die ich je gesehen habe, ganzzahlige Überläufe auf die gleiche Weise. Wie auch immer, es ist ein Fehler, unabhängig vom Ergebnis.

    – Ludin

    27. Januar 2012 um 10:10 Uhr

  • Die Tatsache, dass ein ganzzahliger Überlauf undefiniert ist, ist nicht nur theoretisch. Selbst in der realen Welt nutzen Compiler den Überlauf von Ganzzahlen als undefiniertes Verhalten, um Optimierungen durchzuführen. gcc hat zum Beispiel mindestens 20 Fälle, in denen es keinen Integer-Überlauf zum Umbrechen in Betracht zieht, damit es eine Optimierung durchführen kann. Ein einfaches Beispiel ist ein Ausdruck wie a - 8 < 42wenn a ist ein signierter Typ gcc könnte den Ausdruck reduzieren auf a < 50.

    – au

    27. Januar 2012 um 10:28 Uhr

  • Antwort auf den Kommentar von @ouah: unsigned overflow ist definiert, vorzeichenbehafteter Überlauf nicht. Siehe: diese SO-Frage

    – svek

    5. April 2017 um 19:59 Uhr

  • @svec in der C-Terminologie Ganzzahlüberlauf ist undefiniertes Verhalten, da nur vorzeichenbehaftete Ganzzahlen überlaufen können. Siehe C11, 3.4.3p3 „Ein Beispiel für undefiniertes Verhalten ist das Verhalten bei Ganzzahlüberlauf“ und 6.2.5p7 „Eine Berechnung mit vorzeichenlosen Operanden kann niemals überlaufen, […]”

    – au

    5. April 2017 um 21:19 Uhr

Es ist eine Art zu definieren ohne Vorzeichen wörtliche ganzzahlige Konstanten.

Es ist eine Möglichkeit, dem Compiler mitzuteilen, dass die Konstante 1 als Ganzzahl ohne Vorzeichen verwendet werden soll. Einige Compiler gehen davon aus, dass jede Zahl ohne Suffix wie ‘u’ vom Typ int ist. Um diese Verwirrung zu vermeiden, wird empfohlen, ein Suffix wie „u“ zu verwenden, wenn eine Konstante als Ganzzahl ohne Vorzeichen verwendet wird. Es gibt auch andere ähnliche Suffixe. Beispielsweise wird für Float ‘f’ verwendet.

  • Nicht “einige Compiler”. Alle Compiler.

    – Ludin

    27. Januar 2012 um 7:50 Uhr

  • Ich wollte nicht verallgemeinern, da ich persönlich nur ein paar Compiler verwendet habe.

    – Mokka

    27. Januar 2012 um 8:06 Uhr

  • Mein Punkt ist, dass der C-Standard den Compiler dazu zwingt, ein Integer-Literal ohne ‘u’ als signed int zu behandeln.

    – Ludin

    27. Januar 2012 um 8:45 Uhr

  • @Lundin Nicht ganz richtig, es kann auch lang oder lang lang sein. Ohne Suffix ist der Typ eines Integer-Literals der erste von int, long und long long die den Wert halten kann (falls vorhanden).

    – Daniel Fischer

    27. Januar 2012 um 13:00 Uhr

  • @DanielFischer: Das stimmt. Aber es wird immer ein signierter Typ sein, es sei denn, Sie schreiben das ‘u’.

    – Ludin

    27. Januar 2012 um 15:16 Uhr

es bedeutet “unsigned int”, im Grunde funktioniert es wie ein Cast, um sicherzustellen, dass numerische Konstanten zur Kompilierzeit in den entsprechenden Typ konvertiert werden.

Benutzeravatar von Dirk Herrmann
Dirk Herrmann

Ein dezimales Literal im Code (die Regeln für oktale und hexadezimale Literale sind unterschiedlich, siehe https://en.cppreference.com/w/c/language/integer_constant) hat einen der Typen int, long oder long long. Aus diesen muss der Compiler den kleinsten Typ auswählen, der groß genug ist, um den Wert aufzunehmen. Beachten Sie, dass die Typen char, signed char und short werden nicht berücksichtigt. Zum Beispiel:

0 // this is a zero of type int
32767 // type int
32768 // could be int or long: On systems with 16 bit integers
      // the type will be long, because the value does not fit in an int there.

Wenn Sie ein hinzufügen u Suffix für eine solche Zahl (ein Großbuchstabe U geht auch), muss der Compiler stattdessen den kleinsten Typ auswählen unsigned int, unsigned long und unsigned long long. Zum Beispiel:

0u // a zero of type unsigned int
32768u // type unsigned int: always fits into an unsigned int
100000u // unsigned int or unsigned long

Anhand des letzten Beispiels kann der Unterschied zu einem Guss aufgezeigt werden:

100000u // always 100000, but may be unsigned int or unsigned long
(unsigned int)100000 // always unsigned int, but not always 100000
                     // (e.g. if int has only 16 bit)

Nebenbei bemerkt: Es gibt Situationen, in denen das Hinzufügen von a u Suffix ist das Richtige, um die Korrektheit der Berechnungen sicherzustellen, wie Lundins Antwort zeigt. Es gibt jedoch auch Codierungsrichtlinien, die das Mischen von signierten und unsignierten Typen strengstens verbieten, selbst soweit die folgende Aussage

unsigned int x = 0;

wird als nicht konform eingestuft und muss so geschrieben werden

unsigned int x = 0u;

Dies kann dazu führen, dass Entwickler, die sich viel mit vorzeichenlosen Werten beschäftigen, die Angewohnheit entwickeln, zu addieren u Suffixe zu Literalen überall. Beachten Sie jedoch, dass eine Änderung der Signierung in verschiedenen Kontexten zu unterschiedlichem Verhalten führen kann, z. B.:

(x > 0)

kann (je nach Art von x) etwas anderes bedeuten als

(x > 0u)

Glücklicherweise warnt Sie der Compiler / Code-Checker normalerweise vor verdächtigen Fällen. Trotzdem fügt man a hinzu u Suffix sollte mit Bedacht erfolgen.

1403820cookie-checkWas bedeutet ‘u’ nach einer Zahl?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy