Nur eine zufällige Beobachtung, es scheint, dass es auf StackOverflow.com Fragen zu if "++ i == i ++" gibt. Diese Frage wird die ganze Zeit gestellt. Ich glaube, ich habe sie in den letzten zwei Monaten etwa sechs oder sieben Mal gestellt bekommen.
Ich frage mich nur, warum C-Entwickler sich so dafür interessieren. Dasselbe Konzept / dieselbe Frage gibt es auch für C # - und Java-Entwickler, aber ich glaube, ich habe nur eine C # -bezogene Frage gesehen.
Liegt es daran, dass so viele Beispiele ++ i verwenden? Liegt es daran, dass es ein beliebtes Buch oder Tutorial gibt? Liegt es daran, dass C-Entwickler es lieben, so viel wie möglich in eine einzige Zeile für 'Effizienz' / 'Leistung' zu packen und daher häufiger auf 'seltsame' Konstrukte mit dem ++ - Operator zu stoßen?
quelle
++i == i++
oder allgemeiner auf den Bedeutungsunterschied zwischen++i
undi++
?Antworten:
Ich vermute, dass zumindest ein Teil davon ein bisschen einfacher ist: Selbst jetzt sehen wir viele Fragen wie diese, die zu Beginn des Schuljahres anfangen und sich im Laufe des Jahres allmählich verjüngen.
Daher halte ich es für gerechtfertigt, zu vermuten, dass einige von ihnen einfach das Ergebnis von Klassen sind, in denen der Lehrer zumindest ein wenig darüber spricht, aber seine Punkte nicht sehr gut erklärt (so oft wie nicht) weil er sie selbst nicht wirklich versteht). Insbesondere aufgrund der Leute, die diese Fragen zu stellen scheinen, basieren nur wenige auf der tatsächlichen Codierung.
quelle
Weil C-Programmierer die Reihenfolge der Operationen verstehen MÜSSEN. C # -Entwickler verwenden nicht unbedingt die bitweisen Operatoren (&, |, ~) oder Präfixoperatoren, da wir uns normalerweise mehr um andere Dinge kümmern. Was uns C # -Entwicklern jedoch nicht klar ist, ist, dass wir wissen sollten, was die von uns täglich verwendeten Operatoren tun und wie sie richtig eingesetzt werden. Die meisten von uns meiden nur die Stellen, an denen dies ein Problem sein kann.
Was ist die Ausgabe dieses Snippets?
Ich würde sagen, dass viele erfahrene C # -Entwickler keine Ahnung haben, wie die Ausgabe an die Konsole lautet.
quelle
if (myList[i++] == item)
. Klug. Ich fand es auf der Suche nach der Quelle einer IndexOutOfRange-Ausnahme ... In der Tat sehr "clever".++
einen Schwimmer gesehen, und ich muss sagen, dass er sich nicht sehr angemessen anfühlt. Machen die Leute das? (Ich würde es vorziehen+= 1
)Ich denke das ist offensichtlich. In C #, für ein
int i
,i++ == ++i
ist immer falsch , während++i == i++
immer wahr ist, zuverlässig, und jeder, der interessiert ist , dies aus , indem das Erlernen der Regeln von C # (oder tatsächlich durch nur läuft es) leicht nur finden können.In C und C ++ ist es dagegen fast undefiniert, da es vom Compiler, der Ausführungsumgebung, der Plattform usw. abhängt. Daher ist es viel schwieriger, eine Frage zu beantworten, und viele Leute stellen sie.
quelle
Höchstwahrscheinlich, weil es in C wirklich wichtig ist, ob Sie schreiben
i++
oder++i
Zeigerarithmetik ausführen. Dort kann eine Erhöhungi
vor oder nach einer Operation entscheidend sein. Ich würde Ihnen ein Beispiel geben, aber das letzte Mal, dass ich C schrieb, war vor 10 Jahren ...In C # bin ich nie auf eine Situation gestoßen, in der ich nachdenken müsste,
i++
oder++i
weil AFAIK für die for / while-Schleifen keine Rolle spielt.quelle
i++
und++i
, sondern darum , sie in demselben Ausdruck zu kombinieren.Es ist eine beliebte Frage, weil es eine Trickfrage ist. Es ist undefiniert .
Der obige Link führt zu einer FAQ auf der Homepage von Bjarnes Stroustrup, die sich speziell mit dieser Frage befasst und erklärt, warum dieses Konstrukt undefiniert ist. Was es sagt, ist:
quelle
Vor ein paar Jahren habe ich gelesen, dass diese Operatoren als gefährlich eingestuft wurden, also habe ich versucht, mehr Informationen darüber zu sammeln. Wenn zu diesem Zeitpunkt ein Stapelüberlauf aufgetreten wäre, hätte ich ihn dort gefragt.
Jetzt liegt es daran, dass einige verdrehte Leute Loops wie schreiben
Selbst jetzt bin ich mir nicht sicher, was passieren wird / sollte, aber es ist mir ziemlich klar, dass mehrere ++ [var] in derselben Zeile nach Problemen fragen.
quelle
x = ++j;
in C sind gut definiert. Das Obige ist undefiniert, daj
es zweimal ohne dazwischenliegende Sequenzpunkte modifiziert wird.Zwei Gründe.
Die korrekte Implementierung von ++ i besteht darin, i zu erhöhen und dann zurückzugeben. Die korrekte Implementierung von i ++ besteht darin, den aktuellen Wert zu speichern, i zu erhöhen und den gespeicherten Wert zurückzugeben. Es ist wichtig zu wissen, dass diese nicht als Synonyme implementiert sind.
Die Frage wird dann, wann der Compiler sie anwendet, während er einen Ausdruck wie Gleichheit bewertet.
Wenn zuerst der Gleichheitstest durchgeführt wird, dann die Operatoren vor und nach dem Inkrementieren, müssen Sie eine andere Logik schreiben, als wenn zuerst die linke Seite (lhs) und die rechte Seite (rhs) ausgewertet werden die Gleichheit.
Es geht um die Reihenfolge der Operationen, und das wirkt sich wiederum auf den Code aus, den man schreibt. Und nicht allzu überraschend sind sich nicht alle Sprachen einig.
In der Liste der Basistests können Entwickler testen, ob ihre Annahmen korrekt sind und ob die tatsächliche Implementierung mit der Sprachspezifikation übereinstimmt.
Dies kann sich auf alle möglichen Arten auswirken, wenn Sie mit Zeigern, Schleifen oder der Rückgabe von Werten arbeiten.
quelle
++i
besteht darin , den Wert zu verwendeni+1
und zu einem bestimmten Zeitpunkt, vielleicht davor oder danach, aber vor dem nächsten Sequenzpunkt, zu erhöheni
.Ich denke, es ist eine Kulturschocksache.
Wie bereits erwähnt, kann das Verhalten eines Ausdrucks in C oder C ++ undefiniert sein, da die Reihenfolge der Ausführung der Nachinkremente usw. nicht genau definiert ist. Undefiniertes Verhalten ist in C ziemlich verbreitet, und natürlich wurde ein Großteil davon in C ++ importiert.
Für jemanden, der in einer anderen Sprache programmiert hat - für jemanden, der die Idee aufgegriffen hat, dass Programmiersprachen präzise sein sollen und dass Computer das tun sollen, was sie sollen ... nun, das ist ein Schock für ihn entdecken Sie, dass C in einigen Dingen absichtlich vage ist.
quelle
++
und--
Operatoren basierten nicht auf dem PDP-11, der nicht existierte, als diese Operatoren in Cs Vorgängersprache B eingeführt wurden. Siehe cm.bell-labs.com/who/dmr/chist.html und suche nach "auto-increment".Vielleicht ist es nur so, dass C-Entwickler ++ - Inkrementierung im Allgemeinen häufiger verwenden - da C keine "foreach" - oder ähnliche Anweisung zum Durchlaufen von Arrays hat. Oh, und natürlich Zeigerarithmus, wie schon erwähnt!
quelle
Der Unterschied zwischen beiden Teilen: Post und Preincrement funktionieren so, wie diese beiden Codeteile in jeder Sprache funktionieren sollten. DAS IST NICHT SPRACHENABHÄNGIG !!!
Dies ist ein Vorschritt. Dieser Code erhöht zuerst den Wert von,
i
bevor er den Wert an die Zeile sendet, in der er verwendet wird.Dies ist das Postinkrement. Dieser Code gibt den Wert von zurück,
i
bevor er den Werti
in der Zeile erhöht, in der er verwendet wird.In einem anderen kleinen Beispiel:
Dieser Code wird mit den Ergebnissen auf dem Codepad kompiliert.
Dies hat mit der internen Implementierung der Operatorüberladung zu tun.
++i
erhöht direkt den Wert (und ist daher etwas schneller)i++
Zunächst wird eine Kopie erstellt, die an die Stelle zurückgegeben wird, an der sie benötigt wird. Anschließend wird der ursprüngliche Wert deri
Variablen um eins erhöht.Ich hoffe das ist jetzt klar.
quelle
++i
ist nicht schneller und erstellti++
keine Kopie. Außerdem++i
verhält es sich in C etwas anders als in C ++, geschweige denn zwischen anderen Sprachen.