Kleine Klausurfragen

ThommyTom

Aktives Mitglied
Hallo liebes Forum und ein frohes neues Jahr! 😉

Ich habe einige kleinere Fragen, die sich mir im Rahmen der Klausurvorbereitung stellen:

1)
int x = 1;
int y = 1;
x += y += x += y;

Wieso hat x hier den Wert 4 und y 3 nach der Ausführung? Nach dem ersten += ist doch x=2, y=1, nach dem zweiten += x=2 y=3 und nach dem dritten x=5 y=3.
Was sehe ich hier falsch?

2)
int x = 0;

System.out.println( ++x+x++ );

Wie genau wird der Ausdruck in der Klammer ausgewertet? Also was zuerst, was als letztes?
Kann man das so Klammern: ((++x)+x)++ ?

3)
int i = 0;
int j = 1;
boolean b = (j > 1) && (++i > 0);

Wieso ist i nach Ausführung weiterhin 0?

4)
System.out.println( 2 << 5 * 2 + 5);
Was genau bedeutet das << ? Ich hab natürlich schon google bemüht, aber so richtig schlauer bin ich nicht geworden.

5)
int x = 0;

boolean einBoolean = ~5 < 5 & 4 > 3 && false != true && false == true || (x = 8 & 4) < 8;

Hier hat man auch ähnlich wie bei 4 mir unbakannte Symbole. Aber das klärt sich vielleicht mit 4.

Danke für eure Hilfe! 🙂
Liebe Grüße,
Tom
 
Zu 1) Das ist von rechts nach links nicht links nach rechts.

Zu 2) Das sind Postfixe und Präfixe, da gibt es keine "Klammern", aber (++x) + x(++) wäre korrekt. Zuerst ++x, dann plus x und danach noch x++.

zu 3) Weil j nicht grösser 1 ist. Das nennt man Short Circuit Evaluation (SCE). Das pendant dazu ist das einfache & (oder | bei oder-Verknüpfung), das die komplette Bedingung abarbeiten lässt. der SCE bricht ab, da j nicht grässer 1 ist -> die ganze Bedingung kann schon gar nie wahr werden.

zu 4) Binäres schieben nach links mit vorzeichenbeachtung. Vorzeichenbeachtung bedeutet, dass das MSB (most siginificant bit) beachtet wird (da ein signed int). Du kannst also nicht plötzlich negative Zahlen erhalten, wenn die Vorzeichenbachtung aktiv ist.

zu 5) Das & ist das logische UND ohne SCE. Das ~ ist binäres invertieren. Das < ist binäres linksschieben ohne Vorzeichenbeachtung und > das gleiche für rechts.

Hoffe, konnte helfen. Mit den genannten Begriffen sollte sich jedenfalls genug weiterführender Stoff finden :rtfm:
 
Zuletzt bearbeitet:
Hi,
Danke!
1) kann ich noch nicht nachvollziehen. Auch wenn ich von links beginne, erhalte ich x=5.

2,3,4 sind klar.

Kannst du evtl. 5 mal vormachen?
~5 ist 10, oder? aber 10 < 5 ist doch garnicht erfüllt.
 
ist es so verständlicher:
1)
int x = 1;
int y = 1;
x += y += x += y;
Setze mal Klammern:
x += y += (x += y); x = y + 1 --> x = 2; y = 1;
x += (y += x) += y; x = 2; y = x + 1 --> y = 3;
(x += y) += x += y; x = y + 1 --> x = 4; y = 3;
 
Achso,
ich dachte x += y wäre äquivalent zu x = x+y 😀 Sorry!
Ja, so wurde es gut verständlich.

Hast auch noch was in Pette zu der 5.)? 😉
 
Ne Moment, x += y ist doch aber das gleiche wie x = x+y.

In meinem Kopf geht das so:
x += y += (x += y); x = x + y --> x = 2; y = 1;
x += (y += x) += y; x = 2; y = x + x --> y = 3;
(x += y) += x += y; x = y + x --> x = 5; y = 3;
 
Du hast schon recht mit der Aussage x+=y ist glech wie x = x+y;
Aber bei dieser ganzen Operation wird ein Postkrement operation durchgeführt.
Bei post increment wird die zuerst die Zuweisung vom Aktuellen Wert von i an i wieder zugewiesen, dann wird i inkrementiert. erst bei der nächsten iteration, hat i den neuen Wert. Im gegensatz zur pre inkrement operation d.h. ++i. Hier wird zuerst i um 1 inkrementiert, dann wird der neue Wert an i zugewiesen.

Zur Aufgabe 5:
boolean einBoolean = ~5 < 5 & 4 > 3 && false != true && false == true || (x = 8 & 4) < 8
~ bitweises Komplement ~5d = ~0101b = 1010b = -6d (wird mit 2- komplement berechnet:

5d = 0101b --> alle 1 mit 0 und alle 0 mit 1 wechseln: 1010 dann 1 dazuzählen --> 1011 Daraus wird -6d

-6d < 5 --> true
4 > 3 --> true

true& true --> true;

false != true --> true;

false == true --> false;

(x = 8 & 4) < 8 --> 8d = 1000b 4d = 0100b --> x = 1000 & 0100 --> x = 0000 x < 8 --> true

true && true && false || true

boolean einBoolean = true

Da im Ausdruck eine OR- Verknüpfung steht, muss nur diese ausgewertet werden: (x = 8 & 4) < 8
Wenn diese True ist, ist der gesammte ausdruck true. Wenn nicht, muss der Ausdruck vor der OR- Verknüpfung ausgewertet werden.
 
Zuletzt bearbeitet:
Also das geht so:

x += y += x += y
x = x + y; x = 2; y = 1;
y = y + x; x = 2; y = 3;
x = x + y; x = 4; y = 2;

Zu 5... Hui, eigentlich habe ich gerade keine Lust, das aufzulösen...

Also, 5 in binär ist ungefähr 0101; 4 in binär ist ungefähr 0100; 3 in binär ist ungefähr 011
00101 = 5
00100 = 4
00011 = 3
11011 = ~5

Also das erste & erfüllt.

false != true erfüllt

Also das zweite & erfüllt.

false == true nicht efüllt, also das 3. und fehlgeschlagen -> wir gehen zum oder.

Beim x = 8 & 4 ergibt 0, da 8 != 4 (die sind ja nicht gleich), was wiederum kleiner als 8 ist. Das gibt true.

Also müsste der Ausdruck true ergeben.

edit: Ich stand da oben auf dem Schlauch... < und > sind logischerweise nicht bitweises schieben, ich meinte da <<< und >>>. Langer Tag heute :shock:
 
Zuletzt bearbeitet:
In deiner Vorgehensweise, die du gepostet hast (mit den Klammern), ist in Zeile 2 auch ein Fehler. Du hast y = x + x es muss jedoch y = y + x heissen.

+= heisst immer, das links plus das rechts wird dem links zugewiesen.

a += b => a = a + b
w += v => w = w + v

Edit: eine Anwendung dieses += ist so etwas:

a += 5;
c += 1;

Wobei letzteres gleichbedeutend mit c++ ist.
 
Zuletzt bearbeitet:
Was das konkret heißt, ist klar. Aber ich kann nicht einsehen, wieso das falsch ist:
x += y += (x += y); x = x + y --> x = 2; y = 1;
x += (y += x) += y; x = 2; y = x + y --> y = 3;
(x += y) += x += y; x = y + x --> x = 5; y = 3;
 
Vielleicht hilft das hier weiter:

int x=1;
int y=1;

x += y += x += y;

zuerst wird x += y berechnet: x += 1 + 1 --> x = 2, y = 1;
nun wird y += x berechnet y += 1 + 2 --> x = 2, y = 3;
dann kommt: x += y: x += 1 + 3; --> x = 4; y = 3 ------>
Die Frage ist hier nun: wieso ist x nun 1 statt 2? (siehe Link unten)

Dieses Beispiel zeigt dir vielleicht wieso x=4 als resultat erscheint und nicht x=5
Java:
public static void main(String[] args) {
	int a = 9;
	a += (a = 3); 
	System.out.println(a);	// hier wird 12 ausgegeben, und nicht 6
	int b = 9;
	b = b + (b = 3);
	System.out.println(b);	// hier wird 12 ausgegeben, und nicht 6
}

In der Java Language Specification Expressions findest du in Abschnitt 15.7.1 Evaluate Left-Hand Operand First eine Erklärung für dieses "Verhalten"
 
Zuletzt bearbeitet:
Okay, ich glaube so langsam dämmerts mir.
Bei deinem Beispiel b = b + (b=3) merkt er sich b = 9, rechnet also 9 + 3 = 12.

Aber wenn ich jetzt mein Beispiel durchgehe, erhalte ich erneut das falsche Ergebnis.
Das kann doch nicht sein...

Ich bin auch mittlerweile auf ein neues Problem gestoßen:
int x = 0;
int y = 1;
++x+y++ ergibt 2 und nicht drei... Aber vielleicht verstehe ich das ja, wenn ich ersteinmal das andere Beispiel verstanden habe.
 
Das ist, weil beim ++ das ++ ausgeführt wird und dann der Wert genommen wird und beim x++ wird der Wert genommen und dann das ++ ausgeführt wird.
 
Hi,
Aber wenn ich jetzt mein Beispiel durchgehe, erhalte ich erneut das falsche Ergebnis.
Das kann doch nicht sein...

Ich bin auch mittlerweile auf ein neues Problem gestoßen:
int x = 0;
int y = 1;
++x+y++ ergibt 2 und nicht drei... Aber vielleicht verstehe ich das ja, wenn ich ersteinmal das andere Beispiel verstanden habe.

zu: ++x+y++ (ist zwar nicht wie in deinem Posting beschrieben):
y wird inkrementiert --> y = 2;
dann x ist immer noch 0!
dann x+y = 0+2 = 2
Am Schluss wird x inkrementiert (x ist nun 1!). Aber erst wenn x ausgelesen wird, wird der neue Wert, sichtbar...

Java:
public static void main(String[] args) {
	int x = 0;
	int y = 1;
	
	System.out.println(x);
	System.out.println(y);
	System.out.println(++x+y++);
	System.out.println(x);
	System.out.println(y);
}
Was ist in Aufgabe 1 noch nicht klar?
int x = 1;
int y = 1;
x += y += x += y;

zuerst wird x += y berechnet: x += 1 + 1 --> x = 2, y = 1;
nun wird y += x berechnet y += 1 + 2 --> x = 2, y = 3;
dann kommt: x = x + y: x = 1 + 3; --> x = 4; y = 3
x ist immer noch 1! genau wie im Beispielcode von oben gepostet..
 
Zuletzt bearbeitet:
Okay,
also kann man es auch so sehen:
zuerst ++x (x um 1 erhöhen), dass das neue x + y und das ist dann schon das Ergebnis, was herauskommt. Fragt man y ab, erhält man y+1.

Verstanden.
Woher weiß man eigentlich, ob zuerst ++ oder + ausgeführt wird? Ich habe hier so eine Präzendenztabelle, und dort steht, dass ++ stärker bindet als +. Das würde doch aber eigentlich für (++x)+(y++) sprechen, oder?

zu dem leidigen anderen Thema (danke schoneinmal für eure Geduld...):
Wieso wird dann im zweiten Schritt das neue x (x=2) gewählt, und nicht das alte?
 
zu dem leidigen anderen Thema (danke schoneinmal für eure Geduld...):
Wieso wird dann im zweiten Schritt das neue x (x=2) gewählt, und nicht das alte?
y += x --> y = y + x --> y = 1 + 2 (x = 2 weil die Operation vorher x inkrementiert hat)
Dies ist aber bei der 3. Operation nicht der Fall. Hier ist das x auf der linken Seite immer noch 1!
Diese 1 wird dann bei der Addition auf der rechten Seite genommen. Nicht der Wert der bei der ersten Operation ermittelt wurde..

Woher weiß man eigentlich, ob zuerst ++ oder + ausgeführt wird? Ich habe hier so eine Präzendenztabelle, und dort steht, dass ++ stärker bindet als +. Das würde doch aber eigentlich für (++x)+(y++) sprechen, oder?
Das ist schon so. Die Pre und Post inkrements haben eine höhere Prio als +. Aber da dies alles in einem einzigen Ausdruck steht, wird alles zuerst berechnet, dann folgen die Zuweiseungen. Deshalb wird x erst bei der nächsten Abfrage den Wert anzeigen, der als letzte Aktion durchgeführt wurde, also ++x.
 
1. Teil: okay! Wer hätte das noch geglaubt...

2. Teil: Also geht man, wenn mehrere Operationen anzufinden sind, stur von links nach rechts vor?
 

Neue Themen


Zurück
Oben