Nach der Recherche habe ich gelesen, dass der Inkrement-Operator für den Operanden ein modifizierbares Datenobjekt benötigt: https://en.wikipedia.org/wiki/Increment_and_decrement_operators .
Daraus ergibt sich, dass es einen Kompilierungsfehler gibt, da (a+b)
es sich um eine temporäre Ganzzahl handelt und daher nicht geändert werden kann.
Ist dieses Verständnis richtig? Ich habe zum ersten Mal versucht, ein Problem zu untersuchen. Wenn ich also nach etwas hätte suchen sollen, geben Sie mir bitte Bescheid.
c = a + b + 1
Ihre Absicht klarer wird und die Eingabe auch kürzer ist. Die Inkrement- / Dekrement-Operatoren führen zwei Dinge aus: 1. Sie und ihr Argument bilden einen Ausdruck (der z. B. in einer for-Schleife verwendet werden kann). 2. Sie ändern das Argument. In Ihrem Beispiel verwenden Sie Eigenschaft 1., aber nicht Eigenschaft 2., da Sie das geänderte Argument wegwerfen. Wenn Sie Eigenschaft 2 nicht benötigen und nur den Ausdruck möchten, können Sie einfach einen Ausdruck schreiben, z. B. x + 1 anstelle von x ++.Antworten:
Es ist nur eine Regel, das ist alles und möglicherweise dazu da, (1) das Schreiben von C-Compilern zu vereinfachen, und (2) niemand hat das C-Standardkomitee davon überzeugt, es zu lockern.
Informell gesehen können Sie nur schreiben,
++foo
wennfoo
auf der linken Seite eines Zuweisungsausdrucks wie angezeigt werden kannfoo = bar
. Da Sie nicht schreiben könnena + b = bar
, können Sie auch nicht schreiben++(a + b)
.Es gibt keinen wirklichen Grund, warum
a + b
es keine temporäre Funktion geben könnte, mit der gearbeitet werden++
kann, und das Ergebnis davon ist der Wert des Ausdrucks++(a + b)
.quelle
++
manchmal ein Nebeneffekt darin besteht, etwas zu modifizieren, und manchmal einfach nicht.Der C11-Standard besagt in Abschnitt 6.5.3.1
Und "modifizierbarer Wert" ist in Abschnitt 6.3.2.1 Unterabschnitt 1 beschrieben
Es
(a+b)
handelt sich also nicht um einen veränderbaren l-Wert und ist daher nicht für den Präfix-Inkrement-Operator geeignet.quelle
Du hast Recht. Der
++
versucht, den neuen Wert der ursprünglichen Variablen zuzuweisen. So++a
nimmt den Werta
, fügt1
ihn und dann zuweisen zurücka
. Da (a + b), wie Sie sagten, ein temporärer Wert und keine Variable mit zugewiesener Speicheradresse ist, kann die Zuweisung nicht durchgeführt werden.quelle
Ich denke, Sie haben meistens Ihre eigene Frage beantwortet. Ich könnte eine kleine Änderung an Ihrer Formulierung vornehmen und "temporäre Variable" durch "rvalue" ersetzen, wie von C. Gibbons erwähnt.
Die Begriffe Variable, Argument, temporäre Variable usw. werden klarer, wenn Sie das Speichermodell von C kennenlernen (dies scheint eine schöne Übersicht zu sein: https://www.geeksforgeeks.org/memory-layout-of-c-program/ ).
Der Begriff "rvalue" mag undurchsichtig erscheinen, wenn Sie gerade erst anfangen. Ich hoffe, dass das Folgende bei der Entwicklung einer Intuition darüber hilft.
Lvalue / rvalue sprechen über die verschiedenen Seiten eines Gleichheitszeichens (Zuweisungsoperator): lvalue = linke Seite (Kleinbuchstabe L, keine "Eins") rvalue = rechte Seite
Wenn Sie ein wenig darüber lernen, wie C Speicher (und Register) verwendet, können Sie erkennen, warum die Unterscheidung wichtig ist. In breiten Pinselstrichen erzeugt der Compiler eine Liste der Anweisungen in Maschinensprache, die das Ergebnis eines Ausdrucks (der R - Wert) berechnet und dann legt dieses Ergebnis irgendwo (der L - Wert). Stellen Sie sich einen Compiler vor, der sich mit dem folgenden Codefragment befasst:
Im Assembly-Pseudocode sieht es möglicherweise so aus wie in diesem Spielzeugbeispiel:
Der ++ - Operator (und sein Gegenstück) benötigen ein "irgendwo" zum Ändern, im Wesentlichen alles, was als Wert funktionieren kann.
Das Verständnis des C-Speichermodells ist hilfreich, da Sie eine bessere Vorstellung davon haben, wie Argumente an Funktionen übergeben werden und (eventuell) wie mit der dynamischen Speicherzuweisung wie der Funktion malloc () gearbeitet wird. Aus ähnlichen Gründen können Sie irgendwann eine einfache Assembly-Programmierung studieren, um eine bessere Vorstellung davon zu bekommen, was der Compiler tut. Auch wenn Sie gcc verwenden , die -S- Option "Nach der eigentlichen Kompilierungsphase anhalten; nicht zusammenbauen". kann interessant sein (obwohl ich empfehlen würde, es an einem kleinen Codefragment zu versuchen ).
Nebenbei bemerkt: Die ++ - Anweisung gibt es seit 1969 (obwohl sie in Cs Vorgänger B begann):
Wenn Sie dieser Wikipedia-Referenz folgen, gelangen Sie zu einem interessanten Artikel von Dennis Ritchie (das "R" in "K & R C") über die Geschichte der C-Sprache, der hier der Einfachheit halber verlinkt ist: http://www.bell-labs.com/ usr / dmr / www / chist.html wo Sie nach "++" suchen können.
quelle
Der Grund ist, dass der Standard erfordert, dass der Operand ein l-Wert ist. Der Ausdruck
(a+b)
ist kein Wert, daher ist das Anwenden des Inkrementoperators nicht zulässig.Nun könnte man sagen "OK, das ist in der Tat der Grund, aber es gibt tatsächlich keinen anderen * wirklichen * Grund als diesen" , aber unglücklicherweise erfordert der spezielle Wortlaut, wie der Bediener tatsächlich arbeitet , dass dies der Fall ist.
Natürlich können Sie nicht schreiben,
E += 1
wenn diesE
kein Wert ist. Was schade ist, denn man hätte genauso gut sagen können: "Inkrementiere E um eins" und fertig sein. In diesem Fall wäre es (im Prinzip) durchaus möglich, den Operator auf einen Nicht-Wert anzuwenden, was den Compiler etwas komplexer macht.Jetzt könnte die Definition trivial umformuliert werden (ich denke, es ist nicht einmal ursprünglich C, sondern ein Erbstück von B), aber dies würde die Sprache grundlegend in etwas ändern, das nicht mehr mit den früheren Versionen kompatibel ist. Da der mögliche Nutzen eher gering ist, die möglichen Auswirkungen jedoch enorm sind, ist dies nie geschehen und wird wahrscheinlich auch nie eintreten.
Wenn Sie zusätzlich zu C C ++ in Betracht ziehen (Frage ist mit C gekennzeichnet, es gab jedoch Diskussionen über Operatorüberladungen), wird die Geschichte noch komplizierter. In C ist es schwer vorstellbar, dass dies der Fall sein könnte, aber in C ++ könnte das Ergebnis von
(a+b)
etwas sein, das Sie überhaupt nicht inkrementieren können, oder das Inkrementieren könnte sehr erhebliche Nebenwirkungen haben (nicht nur das Hinzufügen von 1). Der Compiler muss in der Lage sein, damit umzugehen und problematische Fälle zu diagnostizieren, sobald sie auftreten. Bei einem Wert ist das immer noch trivial zu überprüfen. Nicht so für irgendeinen zufälligen Ausdruck in einer Klammer, den Sie auf das arme Ding werfen.Dies ist kein wirklicher Grund, warum es nicht konnte getan werden, aber es ist sicher eine Erklärung dafür, warum die Leute, die dies implementiert haben, nicht gerade begeistert sind, eine solche Funktion hinzuzufügen, die nur sehr wenigen Leuten sehr wenig Nutzen verspricht.
quelle
(a + b) ergibt einen r-Wert, der nicht erhöht werden kann.
quelle
++ versucht, der ursprünglichen Variablen den Wert zuzuweisen, und da (a + b) ein temporärer Wert ist, kann die Operation nicht ausgeführt werden. Und sie sind im Grunde genommen Regeln der C-Programmierkonventionen, um die Programmierung zu vereinfachen. Das ist es.
quelle
Wenn ++ (a + b) Ausdruck ausgeführt wird, dann zum Beispiel:
quelle