ProgrammierungC-Entwickler

Beschreiben Sie die Unterschiede zwischen den Inkrement-Operationen (i++) und (++i) in der Programmiersprache C. Was ist ihre Semantik, wann sollte man die eine oder die andere Variante verwenden und welche Gefahren bestehen in komplexen Ausdrücken?

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

Antwort

In der Programmiersprache C erhöhen die postfix (i++) und prefix (++i) Inkrement-Operationen den Wert der Variablen um 1, aber der Rückgabewert unterscheidet sich:

  • i++ (Postfix): gibt zuerst den aktuellen Wert zurück und erhöht ihn dann.
  • ++i (Prefix): erhöht zuerst den Wert und gibt dann den neuen Wert zurück.

Beispiel:

int i = 5; int a = i++; // a == 5, i == 6 int j = 5; int b = ++j; // b == 6, j == 6

In einfachen Ausdrücken ist der Unterschied unerheblich, aber in komplexen (zum Beispiel mit mehreren Inkrementen gleichzeitig) kann unbestimmtes Verhalten auftreten.

Fangfrage

Welcher Wert hat die Variable a nach der Ausführung des Ausdrucks int a = i++ + ++i;, wenn i = 1 ist?

Antwort:

Die Berechnung hängt von der Reihenfolge der Auswertung der Operanden ab, die der Standard nicht garantiert, und führt auch zu unbestimmtem Verhalten (undefined behavior), da die Variable i mehr als einmal zwischen aufeinanderfolgender Verwendung des Wertes modifiziert wird. So sollte man nicht schreiben!

Beispiel für solchen Code:

int i = 1; int a = i++ + ++i; // unbestimmtes Verhalten! So nicht verwenden!

Beispiele tatsächlicher Fehler aufgrund fehlenden Wissens über die Feinheiten des Themas


Geschichte

In einem großen Projekt wurde der Index im Array als arr[i++] = getValue(++i); berechnet – der Entwickler wollte den alten Wert speichern und gleichzeitig den neuen erhalten. Das Verhalten unterschied sich je nach Compiler: manchmal überschrieben sich die Werte, manchmal stürzte das Programm ab. Der Grund war die unzulässige mehrfache Modifikation von i in einem Ausdruck.


Geschichte

In einem Embedded-Projekt wurde der Wert des Zählers als Teil eines komplexen Ausdrucks erhöht: if (buffer[i++] == TERMINATOR && ++i < SIZE) ... – auf „Hardware“ ergab sich manchmal ein falscher Index aufgrund unterschiedlicher Auswertungsreihenfolge, was zu einem Lesen von nicht initialisierten Daten führte.


Geschichte

Beim Portieren des Codes auf einen anderen Compiler führte der Unterschied in der Implementierung der Reihenfolge der Auswertung der Operanden dazu, dass eine Schleife wie while (arr[i++] && i < MAX && arr[++i]) sich unvorhersehbar verhielt. Der Fehler wurde erst aufgrund der Testergebnisse in der Phase der Tests beim Kunden entdeckt.