For Schleife Aufgabe warum 2,3,4?

Aufrufe: 787     Aktiv: 13.03.2023 um 09:07

0

Hallo zusammen,

Ich verstehe grade diese For-Schleife nicht:

    System.out.println("Exemple 1:");
    int n = 5;
    int a = 2;
    for(a = 3; a < n + 1; a = a++) {
    System.out.println(a-1);
    a = a + 1;
    }

Also ich habe es so verstanden:

for(a = 3; 3 < 5 + 1; a = 3+1) //somit ist a =4 System.out.println(4-1) // somit ist der Output: 3 a = 3 +1; //4

for(a=4; 4 < 5+1; a= 4+1) //somit ist a =5 System.out.println(5-1) // somit ist der Output: 4 a = 4 + 1 //5

for(a=6; 6 < 5+1; a= 4+1) //abbruch

Somit ist die Ausgabe 3,4

Aber warum ist es eigentlich 2,3,4?

Diese Frage melden
gefragt

Student, Punkte: 66

 
Kommentar schreiben
2 Antworten
0

Hallo sayuri, der Code ist - ich sag mal - seltsam. 1. die Zuweisung von a vor der for-Schleife ist überflüssig. a wird ja beim Start der for-Schleife auf 3 gesetzt. Da ist also die vorherige Zuweisung total egal. 2. die Schleifenvariable, hier a, wird immer am Ende der for-Schleife "bearbeitet". In diesem Fall a+1 wegen a++. Die Zuweisung a=a++ braucht es an dieser Stelle auch nicht. a++ hätte gereicht. 3. Denkfehler. Das Ergebnis der Ausgabe ist nur 2 und 4, 3 kommt nicht vor. Warum nicht? Weil in der for-Schleife die Schleifenvariable mit a=a+1 zusätzlich manipuliert wird. Also wird a zweimal erhöht. Somit kommt 3 nicht vor, weil a mit 3 startet, dann 5 wird und beim dritten Durchlauf 7 erreicht was das Ende der for Schleife bedeutet. Grundsätzlich gilt für for Schleifen folgendes: Als erstes wird die Schleifenvariable zugewiesen, dann wird die Abbruchbedingung geprüft und am Ende der Schleife die Schleifenvariable „bearbeitet“. Jede der 3 Anweisungen ist separat zu betrachten und kann auch weggelassen werden. So stellt z.B. die Schleife for(;;) {…} ganz einfach eine Endlosschleife dar. So, ich hoffe ich habe dich jetzt genug verwirrt ;-) Gruss jobe.

Diese Antwort melden
geantwortet

Sonstiger Berufsstatus, Punkte: 505

 

Vielen Dank für deine Antwort. Aber wenn ich es laufen lasse, erhalte ich 2,3,4....

  ─   sayuri 13.12.2022 um 07:16

Hallo sayuri, ich habe dein Programm als C Programm interpretiert und laufen lassen. Falls es eine andere Programmiersprache ist kann die for-Schleife auch anders interpretiert werden. Wenn du eine andere Ausgabe als ich hast, wirst du wohl auch eine andere Programmiersprache benutzt haben. Ich bittet dich daher zukünftig die Programmiersprache dazuzuschreiben. Gruß jobe.

  ─   jobe 13.12.2022 um 07:56

Achso, es handelt sich um Java.

  ─   sayuri 13.12.2022 um 13:02

Kommentar schreiben

0

Die Post-Inkrementierung von a im Schleifenkopf vor der Zuweisung führt dazu das der Wert verworfen wird. Deshalb die Ausgabe 2, 3, 4. Was Jobe unter seinem dritten Punkt schreibt ist dementsprechend nicht ganz richtig. Und unter C wäre es BTW dasselbe wie in Java. ;-)

Was mich aber wirklich wundert: es werden hier die Laufvariablen im Kopf und nochmal zusätzlich innerhalb der Schleife manipuliert, unnötig Referenzierungen erzeugt und vor allem eine an sich wirklich todsimple Sache völlig unnötig verkompliziert. Ich hoffe einfach mal inständig, das Beispiel stammt nicht von einem Lehrer oder Dozenten. Wenn ja, nimm es als Beispiel dafür wie man es nicht macht. Code sollte lesbar und bestenfalls selbsterklärend sein.

Sollte die Erhöhung um je eins so beabsichtigt sein, wär das die "Standard"lösung (a durch i qua Konvention ersetzt):

int n = 5;
for(int i = 3; i < n + 1; i++) {
     System.out.println(i - 1);
}

Erklärung:

  1. n wird mit dem Wert 5 initialisiert
  2. i wird mit dem Wert 3 initialisiert
  3. Die Schleife läuft nun so lange wie i kleiner als n + 1 (also 6) ist.
  4. i hingegen wird mit jedem Durchlauf um eins erhöht (i++, Inkrementierung)
  5. Deshalb erhöht sich der Wert in der Ausgabe jede Runde um 1
  6. n ändert sich nicht, deshalb wird der Abbruch durch die Erhöhung von i ausgelöst

Sollte beabsichtigt sein, dass i um je zwei erhöht wird, kannst du statt

i++

einfach

i+=2

schreiben. i bliebe dann ungerade und es würden nur die geraden Zahlen geprinted werden.

Die Initialisierung von i kann man auch außerhalb der Schleife vornehmen, wenn man davon ausgeht, dass der Wert schnell erkannt und von anderen Entwicklern angepasst werden kann. Ist aber eher unüblich, weil i meistens auf 0 gesetzt wird oder einen dynamischen Wert, der dann dekrementiert wird (i--), mit Abbruchbedingung i > n. Dann wäre die elegantere Lösung aber fast eine while Schleife :-)

int n = 5;
int a = 3;
while(a <= n) {
    System.out.println(a++ - 1);
}
Diese Antwort melden
geantwortet

 

Hallo hansenausberlin, vielleicht gibt es doch Unterschiede zwischen Java und C? Den Code unter VS durch den C Compiler gejagt und hier das Ergebnis:
Exemple 1:
Erg: 2
Erg: 4

Code:
int main()
{
printf("Exemple 1:\n\r");
int n = 5;
int a = 2;
for (a = 3; a < n + 1; a = a++) {
printf("Erg: %d\n\r", a - 1);
a = a + 1;
}
}

  ─   jobe 12.03.2023 um 18:08

Interessant, bei mir sinds (C 11) 2, 3, 4. Den Post Inkrement kann man entfernen (sagt einem auch CLion, das der neue Wert nie zugewiesen wird) mit demselben Ergebnis (s. meine Erklärung). Anders verhält es sich wenn du a = a + 1 verwendest, da dann der neue Wert noch zugwiesen wird. Selbiges mit nem Präinkrement, also ++a.
Aber vielleicht verhalten sich die Compiler da auch anders, will hier natürlich nicht in Frage stellen das bei dir ein anderes Verhalten entsteht. Aber komisch ist es schon, da die Anweisung halt zuerst ausgewertet wird (Wertzuweisung, also a = a) und dann inkrementiert wird, ergo der Wert gleich bleibt. Kannste ja hier auch nochmal nachlesen: "The post-increment operator is used when it is required to increment the value of the variable after evaluating the expression. Therefore, in post-increment value is first used in the expression, and then it is incremented." (https://www.scaler.com/topics/pre-increment-and-post-increment-in-c/)
Wie auch immer: Der Fragesteller hat ja eindeutig ohnehin an der Syntax erkennbar Javacode gepostet und da isses auch 2,3,4. Letztlich gehts ja um die Erklärung und nicht darum, das sich dein C Compiler anders verhält als erwartet (das Verhalten von post increments ist btw auch in C#, C++ und was auch immer überall gleich).

  ─   hansenausberlin 13.03.2023 um 00:31

Hallo hansenausberlin, interessant. Habe das mal mit meinen GCC (embedded Compiler) getestet. Der macht's richtig und gibt auch eine Warnung aus: operation on 'a' may be undefined [-Wsequence-point]. Wohl ein Fehler im Microsoft Compiler. Aber die Diskussion ist Makulatur. Es geht ja um JAVA. Gruß jobe.

  ─   jobe 13.03.2023 um 09:07

Kommentar schreiben