ProgrammierungC Entwickler

Welche Regeln zur Typumwandlung (type conversion, type promotion) gelten in Ausdrücken in der Programmiersprache C? Nennen Sie Beispiele für unerwartete Fehler und Lösungen.

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In der Programmiersprache C finden in Ausdrücken häufig Typumwandlungen (type promotion, type conversion) statt, die durch den Standard geregelt sind:

  • Integer Promotion: Typen geringerer Ordnung (z. B. char, short) werden automatisch zu int oder unsigned int vor arithmetischen Operationen umgewandelt.
  • Usual Arithmetic Conversions: Wenn die Operanden unterschiedlicher Typen sind, werden sie gemäß festgelegten Regeln in einen "breiteren" Typ umgewandelt.
  • Bei gemischten Operationen mit vorzeichenbehafteten und vorzeichenlosen Typen kann das Ergebnis unerwartet variieren, bedingt durch die Umwandlung.

Beispiel:

unsigned short a = 65535; signed short b = -1; printf("%d ", a + b); // hängt von der Umwandlung ab!

Empfehlung: Achten Sie genau auf die Typen der Operanden, insbesondere bei der Arbeit mit Bitoperationen, Array-Längen, Indizes, und vermeiden Sie implizites Mischen von vorzeichenbehafteten und vorzeichenlosen Typen.

Fallen Frage

Was gibt der folgende Code aus?

unsigned int u = 1; int i = -2; printf("%d ", u + i);

Antwort: Die Variable i wird zu unsigned int umgewandelt, der Endwert wird sehr groß, da das Ergebnis unter der Haube: 1U + (unsigned int)-2U lautet, was eine Zahl nahe UINT_MAX (4294967295) ergibt. Es wird nur dann eine negative Zahl ausgegeben, wenn printf als int formatiert, ansonsten Müll.

Beispiele für reale Fehler durch Unkenntnis der Feinheiten des Themas


Geschichte

Bei der Berechnung der durchschnittlichen Intensität eines Bildes wurden int und unsigned int verwechselt. Negative Werte wurden fälschlicherweise als unsigned übertragen und ergaben riesige Zahlen, was zu einem Pufferüberlauf des Bildes führte.


Geschichte

In der eingebetteten Firmware wurde die Länge einer Zeichenkette über size_t berechnet, während das Array über int indiziert wurde. Bei der Überprüfung der Bedingung für den Array-Grenzüberlauf wurde int i >= size_t len verglichen, was die Logik für lange Zeichenketten brach und Bugs beim Vergleich unterschiedlicher Typen (size_t — unsigned) verursachte.


Geschichte

Ein Entwickler in einem Finanzprojekt berechnete den Rest einer Division für negative Zahlen mit %, vergass jedoch, dass das Vorzeichen des Ergebnisses für negative Operanden von der Implementierung abhängt. In einer Umgebung war das Ergebnis positiv, in einer anderen negativ, weshalb die Berechnungen gelegentlich "aus dem Ruder liefen".