2017-11-20 5 views
0

Ich verwende meinen C-Code auf gcc, um den Pre-/Post-Inkrement-Operator zu verstehen. Allerdings sind die Ergebnisse, die ich sehe, nicht das, was ich erwartet habe. Wie für die Linie 6, da ich 5 ist, haben esIst dies ein undefiniertes Verhalten in C?

8 7 6 5 5 

sein sollen Aber es ist 8 7 6 5 8

dann auf die letzte Zeile kommt, zeigt es 14 14 14 14. Kann mir bitte jemand dieses Verhalten erklären. Ich hatte erwartet 14 14 13 12

Ist dieser Compiler abhängig? Ist das Verhalten der printf-Funktion auf Sequenzpunkten undefiniert?

#include <stdio.h> 

int main() 
{ 
     i = 5; 
     printf("%d %d %d %d %d \n", i, i++, i++, i++, i); 
     printf("%d \n", ++i); 
     printf("%d \n", ++i); 
     printf("%d \n", ++i); 
     printf("%d %d %d %d \n", i, ++i, ++i, ++i); 

} 
+3

Es ist undefiniertes Verhalten. Ihre Erwartungen werden vom C-Standard – CIsForCookies

+3

nicht unterstützt. Es kann nicht erklärt werden, es ist undefiniertes Verhalten. Sie können nicht mehrere Inkremente derselben Variablen in eine einzelne Anweisung einfügen. –

+2

Moral der Geschichte: Vermeiden Pre/Post Inkrement in 99% der Situationen. Leser Ihres Codes werden es zu schätzen wissen. – Alexander

Antwort

6

Der Standard besagt, dass

Zwischen dem vorherigen und nächsten Sequenzpunkt ein Objekt wird seine gespeicherten Wert geändert höchstens einmal durch die Auswertung eines Ausdrucks haben. Darüber hinaus darf nur auf den früheren Wert zugegriffen werden, um den zu speichernden Wert zu ermitteln.

Und das sind die Orte, wo man Sequenzpunkte finden:

  • am Ende der Auswertung eines vollständigen Ausdrucks (einen vollen Ausdruck ist ein Ausdruck Anweisung oder jeder anderer Ausdruck, ist kein Teilausdruck innerhalb eines größeren Ausdrucks);

  • bei den ||, &&, ?: und Komma-Operatoren; und

  • bei einem Funktionsaufruf (nach der Auswertung aller Argumente und kurz vor dem eigentlichen Aufruf).

Eine Ausarbeitung des letzten Punktes: der Komma-Betreiber in einem Funktionsaufruf sind nicht Sequenzpunkte und die Ausdrücke zwischen dem , s kann in jeder beliebigen Reihenfolge ausgewertet werden.

Überprüfen Sie this und this zum besseren Verständnis.

In printf("%d %d %d %d %d \n", i, i++, i++, i++, i); schreiben Sie mehr als einmal zwischen zwei Sequenzpunkten auf dieselbe Speicherstelle und rufen so undefined behaviour auf.

+0

Vielleicht erwähnenswert, dass Ein Komma, das Funktionsaufrufargumente trennt, ist nicht der Kommaoperator. – aschepler

+0

@aschepler Danke, dass Sie das herausgebracht haben. Bearbeitet. – babon

Verwandte Themen