Forum: Compiler & IDEs Inkrementieren vor Zuweisung?


von Sebastian (Gast)


Lesenswert?

Ich habe gerade ein Problem bei C:

Drei gleiche Werte inkrementieren.

Warum geht allgemein:
1
A = B = C;
aber nicht:
1
A = B = C++;
sondern:
1
A++;
2
B++;
3
C++;

Der Zuweisungsoperator übernimmt Zuweisungen von rechts nach links wenn 
ich mich nciht täusche. Dass das Inkrement von niederer Priorität ist 
als das = weiß ich. Nur verstehe ich halt nicht, warum nicht erst 
inkrementiert und dann zugewiesen wird.

Gruß,

Seb

von Floh (Gast)


Lesenswert?

Du kannst aber mit Preinkrement arbeiten:

A = B = ++C;

hier wird bereits vor der Verwendung (Zuweisung) die Variable C 
inkrementiert, in deinem Beispiel wird C erst verwendet und dann 
inkrementiert.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> als das = weiß ich. Nur verstehe ich halt nicht, warum nicht erst
> inkrementiert und dann zugewiesen wird.

Weil das genau das ist, was du geschrieben hast

Post-Inkrement:

   i++

ist ein Ausdruck, der den Wert von i liefert und als Nebeneffekt i um 1 
erhöht.

Wichtig in diesem Zusammenhang: Der Wert des Ausdrucks ist der Wert von 
i vor dem Inkrementieren.

Und diesen Wert weist du an eine Variable zu

   j = i++;

j bekommt daher den Wert von i, noch bevor das Inkrement stattgefunden 
hat.
Nun ist eine Zuweisung selber wieder ein Ausdruck, der einen Wert hat. 
Nämlich den Wert der zugewiesen wurde. Auch mit diesem Wert kann man 
wieder weiterarbeiten

   k = j = i++;

das Ergebnis der Zuweisung von i nach j (das ist der zugewiesene Wert 
selber) wird an k zugewiesen.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> Der Zuweisungsoperator übernimmt Zuweisungen von rechts nach links wenn
> ich mich nciht täusche.

Das ist unglücklich ausgedrückt.

Der Zuweisungsoperator ist rechts-assoziativ

Damit muss der Compiler den Ausdruck

   A = B = C

als

  A = ( B = C )

lesen und damit ergibt sich dann die Auswerte-Reihenfolge 'von rechts 
nach links'

von Sebastian (Gast)


Lesenswert?

OK.

Und um das alles zu berücksichtigen nimmt man ein Präinkrement?!

Wo wird das noch alles eingesetzt? Hab dessen verwendung nie 
verstanden...

von (prx) A. K. (prx)


Lesenswert?

Präinkrement ++x ist lediglich eine andere Schreibweise der sowieso 
vorhandenen Operation (x += 1) und die logische Ergänzung von 
Postinkrement.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> OK.
>
> Und um das alles zu berücksichtigen nimmt man ein Präinkrement?!

Ein Präinkrement nimmst du, wenn du beim Ausdruck

   ++i

am Wert von i nach dem Inkrement interessiert bist.

                    Post-Inkrement             Prä-Inkrement

Schreibweise             i++                      ++i
Wert des Audrucks     i vor dem Inkrement       i nach dem Inkrement


> Wo wird das noch alles eingesetzt?

Immer dann wenn man eines der beiden braucht.
Beiden gemeinsam ist, dass i auf jeden Fall inkrementiert wird. Jetzt 
hängt es nur noch davon ab, welcher Wert im kompletten Ausdruck 
interessiert: der vor oder der nach dem Inkementieren. Je nachdem nimmt 
man einen der beiden. Wenn es egal ist, weil der Wert des Ausdrucks an 
sich nicht weiter interessiert, kann man im Prinzip beides nehmen. C++ 
Jünger bevorzugen dann allerdings den Prä-Inkrement. In C ist es egal.

von Jürgen (Gast)


Lesenswert?

> Wo wird das noch alles eingesetzt?

Am besten garnicht.

Solche verketteten Zuweisungen sind schwer verständlich und deswegen 
schlechter Code. Besser ist es, jede Zuweisung (auch Inkrement) als 
getrennte Anweisung zu schreiben.

von Gastino G. (gastino)


Lesenswert?

Jürgen schrieb:
> Am besten garnicht.
>
> Solche verketteten Zuweisungen sind schwer verständlich und deswegen
> schlechter Code. Besser ist es, jede Zuweisung (auch Inkrement) als
> getrennte Anweisung zu schreiben.

Richtig. Eine Programmierweise, bei der Rätselraten angesagt ist, in 
welcher Reihenfolge was ausgeführt wird und zu welchen Ergebnissen das 
dann führt, ist Müll.
Man muss nicht jeden Blödsinn mitmachen, den die C-Syntax prinzipiell 
ermöglichen würde.

von Sebastian (Gast)


Lesenswert?

Ja

Gastino G. schrieb:
> Richtig. Eine Programmierweise, bei der Rätselraten angesagt ist, in
>
> welcher Reihenfolge was ausgeführt wird und zu welchen Ergebnissen das
>
> dann führt, ist Müll.

Da geb ich euch Recht.

Es gibt hier im Forum so einige Spezis die meinen sie müssten immer und 
überall shiften, obwohl eingetlich die Multiplikation/Division gemeint 
ist. Oder Spezis die mit irgendwelchen wirren #defines Flags durch 
Bitmanipulatoren á la "|=" bzw. "&=~" setzten, anstatt =1 oder =0. Der 
Code wird dadurch unglaublich erschwert, weil ja wohl kaum jemand binär 
im Kopf rechnet. Aber naja man will ja besonders anspruchsvolle Vokabeln 
in seinem Aufsatz haben.

Für mich ist es halt wichtig Code ÜBERSICHTLICH UND VERSTÄNDLICH zu 
halten. Und das ist sicherlich ein schmaler Grat.

Deshalb müssen wir halt mal drüber sprechen, was so der aktuelle Schick 
ist.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> Deshalb müssen wir halt mal drüber sprechen, was so der aktuelle Schick
> ist.


Na, ja

Wenn

    a = b = c = 0;

ein Verständnisproblem heraufbeschwört, dann sollte man doch seine 
C-Kentnisse überprüfen. Auch wenn ich euch in der Sache an sich 
(verständlich und lesbar programmieren) natürlich recht gebe.

Was für den einen schon getrickst ist, ist für den anderen sonnenklar.

Wobei:
Ich muss mich da auch ein wenig an der Nase nehmen.
1
  int a;
2
  double b, c;
3
4
  b = a = c = 5.4;

welchen Wert hat b?
(Und ich gestehe: Ich weiß es auch nicht auf Anhieb, würde aber auf 5.0 
tippen :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.