[Für die Aufzeichnung habe ich diese Antwort ziemlich erheblich bearbeitet, da sie akzeptiert und abgestimmt wurde. Es sagt aber immer noch im Grunde die gleichen Dinge.]
Dieser Code ist zutiefst, vielleicht absichtlich, verwirrend. Es enthält eine eng abgewendete Instanz des undefinierten Dread- Verhaltens . Es ist grundsätzlich unmöglich festzustellen, ob die Person, die diese Frage konstruiert hat, sehr, sehr klug oder sehr, sehr dumm war. Und die "Lektion", über die dieser Code Sie unterrichten oder befragen könnte - nämlich, dass der unäre Plus-Operator nicht viel tut - ist sicherlich nicht wichtig genug, um diese Art von subversiver Fehlleitung zu verdienen.
Es gibt zwei verwirrende Aspekte des Codes, die seltsame Bedingung:
while(+(+k--)!=0)
und die wahnsinnige Aussage, die es kontrolliert:
k=k++;
Ich werde zuerst den zweiten Teil behandeln.
Wenn Sie eine solche Variable haben k, die Sie um 1 erhöhen möchten, bietet C Ihnen nicht eine, nicht zwei, nicht drei, sondern vier verschiedene Möglichkeiten:
k = k + 1
k += 1
++k
k++
Trotz dieser Prämie (oder vielleicht gerade deswegen) sind einige Programmierer verwirrt und husten Verrenkungen wie
k = k++;
Wenn Sie nicht herausfinden können, was dies tun soll, machen Sie sich keine Sorgen: Niemand kann. Dieser Ausdruck enthält zwei verschiedene Versuche, kden Wert zu ändern (das k =Teil und das k++Teil). Da es in C keine Regel gibt, die besagt, welche der versuchten Modifikationen "gewinnt", ist ein Ausdruck wie dieser formal undefiniert , was nicht nur das bedeutet es hat keine definierte Bedeutung, aber das gesamte Programm, das es enthält, ist verdächtig.
Nun, wenn man sich sehr sorgfältig, werden Sie , dass in diesem speziellen Programm sehen, die Linie k = k++nicht tatsächlich ausgeführt werden, weil (wie wir über zu sehen sind) die Kontrolle Zustand anfänglich falsch ist, so dass die Schleife 0 mal läuft . Also dieses besondere Programm möglicherweise nicht tatsächlich undefiniert sein - aber es ist immer noch pathologisch verwirrend.
Siehe auch diese kanonischen SO-Antworten auf alle Fragen zu undefiniertem Verhalten dieser Art.
Aber du hast nicht nach dem k=k++Teil gefragt . Sie haben nach dem ersten verwirrenden Teil gefragt, dem +(+k--)!=0Zustand. Das sieht seltsam, denn es ist seltsam. Niemand würde jemals einen solchen Code in ein echtes Programm schreiben. Es gibt also keinen Grund zu lernen, wie man es versteht. (Ja, es ist wahr, das Erforschen der Grenzen eines Systems kann Ihnen helfen, seine Feinheiten kennenzulernen, aber in meinem Buch gibt es eine ziemlich klare Grenze zwischen einfallsreichen, zum Nachdenken anregenden Erkundungen und düsteren, missbräuchlichen Erkundungen, und dieser Ausdruck ist sehr deutlich die falsche Seite dieser Linie.)
Wie auch immer, lassen Sie uns untersuchen +(+k--)!=0. (Und nachdem wir das getan haben, vergessen wir alles.) Jeder Ausdruck wie dieser muss von innen nach außen verstanden werden. Ich nehme an, du weißt was
k--
tut. Es nimmt kden aktuellen Wert und "gibt" ihn an den Rest des Ausdrucks zurück und dekrementiert mehr oder weniger gleichzeitig, dh kes speichert die Menge k-1zurück in k.
Aber was macht das +dann? Dies ist ein unäres Plus, kein binäres Plus. Es ist wie ein unäres Minus. Sie wissen, dass das binäre Minus subtrahiert: der Ausdruck
a - b
subtrahiert b von a. Und Sie wissen, dass unäres Minus die Dinge negiert: den Ausdruck
-a
gibt Ihnen das Negativ von a. Was Unary +tut, ist ... im Grunde nichts. +agibt Ihnen aden Wert, nachdem Sie positive Werte in positive und negative Werte in negative geändert haben. Also der Ausdruck
+k--
gibt dir, was k--dir gegeben hat, das ist kder alte Wert.
Aber wir sind noch nicht fertig, weil wir haben
+(+k--)
Dies nimmt nur das, was +k--Sie gegeben haben, und gilt wieder ungleichmäßig +. Also gibt es dir, was +k--dir gegeben hat, was k--dir gegeben hat, was kder alte Wert war.
Also am Ende die Bedingung
while(+(+k--)!=0)
macht genau das Gleiche wie der viel gewöhnlichere Zustand
while(k-- != 0)
hätte es getan. (Es macht auch das Gleiche wie die noch komplizierter aussehende Bedingung while(+(+(+(+k--)))!=0). Und diese Klammern sind nicht wirklich notwendig; es macht auch das Gleiche wie while(+ + + +k--!=0)es getan hätte.)
Sogar herauszufinden, was der "normale" Zustand ist
while(k-- != 0)
tut ist irgendwie schwierig. In dieser Schleife gibt es zwei Dinge: Da die Schleife möglicherweise mehrmals ausgeführt wird, werden wir:
- mach weiter
k--, um immer kkleiner zu machen , aber auch
- Mach weiter mit dem Körper der Schleife, was auch immer das tut.
Aber wir erledigen den k--Teil sofort, bevor wir (oder gerade) entscheiden, ob wir eine weitere Reise durch die Schleife unternehmen wollen. Und denken Sie daran, dass k--der alte Wert von "zurückgegeben" wird k, bevor er dekrementiert wird. In diesem Programm ist der Anfangswert von k0. k--Der alte Wert 0 wird also "zurückgegeben" und dann kauf -1 aktualisiert . Aber dann ist der Rest der Bedingung != 0- aber wie wir gerade gesehen haben, haben wir beim ersten Testen der Bedingung eine 0 erhalten. Wir werden also keine Fahrten durch die Schleife machen, also werden wir nicht versuchen, die auszuführen überhaupt problematische Aussage k=k++.
Mit anderen Worten, in dieser speziellen Schleife stellt sich heraus, dass Sache 1 einmal passiert, Sache 2 jedoch null Mal, obwohl ich gesagt habe, dass "zwei Dinge vor sich gehen".
Auf jeden Fall hoffe ich, dass jetzt hinreichend klar ist, warum diese schlechte Entschuldigung für ein Programm am Ende -1 als Endwert von druckt k. Normalerweise beantworte ich Quizfragen wie diese nicht gerne - es fühlt sich an wie Betrug -, aber in diesem Fall macht es mir nichts aus, da ich mit dem ganzen Punkt der Übung so lautstark nicht einverstanden bin.