Hilfestellung, Tipp, Idee < Java < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 12:21 Sa 21.07.2012 | Autor: | Marcel08 |
Hallo zusammen!
Ich hätte eine Frage zu den Gemeinsamkeiten bzw. den Unterschieden der beiden kopfgesteuerten Schleifen "for" und "while". In meinen Unterlagen steht, dass sich jede for-Schleife in eine while- Schleife (und umgekehrt) umschreiben lässt. Daraus schließe ich unmittelbar auf deren Äquivalenz. Weiterhin steht dort, dass man for-Schleifen vorzugsweise dann anwendet, wenn die Anzahl der Durchläufe a priori bekannt ist, während die while- Schleife in allen anderen Fällen zur Anwendung kommt.
Jetzt betrachte ich ein und dasselbe Beispiel unter Anwendung ...
(a) ... einer while- Schleife:
public class Schleifen {
public static void main(String[] args) {
int x = 0;
int y = 0;
x = 1;
while (x < 10) {
x = x + 1;
y = y + 2 * x;
}
System.out.println("x = " + x );
System.out.println("y = " + y );
}
}
(b) ... einer for-Schleife:
public class Schleifen2 {
public static void main(String[] args) {
int x = 0;
int y = 0;
for (x=1; x < 10; x++) {
y = y + 2 * x;
}
System.out.println("x = " + x );
System.out.println("y = " + y );
}
}
Ich würde nun gerne wissen, warum die beiden Schleifen zu unterschiedlichen Ergebnissen führen, obwohl die Unterschiede laut Skript nur in der Syntax des jeweiligen Programmcodes liegen. Was habe ich möglicherweise übersehen? Über hilfreiche Antworten würde ich mich freuen; vielen Dank!
Viele Grüße, Marcel
|
|
|
|
Hallo Marcel,
ich bin mir mit meiner Antwort nicht sicher, da iuch ehrlich gesagt von Java nicht viel Ahnung habe. Aus anderen Sprachen (TurboPASCAL, C, C++ etc.) ist mir jedoch in Erinnerung, dass die Schleifenvariable x (oder wie nennt man das? ) im Falle einer for-Struktur immer erst am Ende der Schleife iteriert wird, während du das in deiner while-Schleife ja zu Beginn tust.
Vielleicht klärt das ja aber deine Frage doch schon? Ich stelle zur Sicherheit aber auf 'teilweise beantwortet'.
Gruß, Diophant
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:45 Sa 21.07.2012 | Autor: | Marcel08 |
Hallo!
> Hallo Marcel,
>
> ich bin mir mit meiner Antwort nicht sicher, da iuch
> ehrlich gesagt von Java nicht viel Ahnung habe. Aus anderen
> Sprachen (TurboPASCAL, C, C++ etc.) ist mir jedoch in
> Erinnerung, dass die Schleifenvariable x (oder wie nennt
> man das? ) im Falle einer for-Struktur immer erst am
> Ende der Schleife iteriert wird, während du das in deiner
> while-Schleife ja zu Beginn tust.
Mit anderen Worten: Bei einer for-Schleife wird erst die eigentliche Anweisung ausgeführt und dann die Schleifenvariable angepasst:
1. Schritt: [mm] y_{neu}=y_{alt}+2*x_{alt}=f(x_{alt})
[/mm]
2. Schritt: [mm] x_{neu}=x_{alt}+1
[/mm]
Bei einer while-Schleife wird erst die Schleifenvariable angepasst und dann die eigentliche Anweisung ausgeführt:
1. Schritt: [mm] x_{neu}=x_{alt}+1
[/mm]
2. Schritt: [mm] y_{neu}=y_{alt}+2*x_{neu}=f(x_{neu})
[/mm]
Die beiden Schleifen führen also im Allgemeinen nicht auf dasselbe Ergebnis. Bleibt noch zu klären, wann welche Schleife zur Anwendung kommt. Kann man sich darauf beschränken, dass for-Schleifen verwendet werden, wenn eine Laufvariable hoch oder heruntergezählt werden soll und while-Schleifen in allen übrigen Fällen?
> Vielleicht klärt das ja aber deine Frage doch schon? Ich
> stelle zur Sicherheit aber auf 'teilweise beantwortet'.
>
>
> Gruß, Diophant
Viele Grüße, Marcel
|
|
|
|
|
Hallo,
> Mit anderen Worten: Bei einer for-Schleife wird erst die
> eigentliche Anweisung ausgeführt und dann die
> Schleifenvariable angepasst:
>
> 1. Schritt: [mm]y_{neu}=y_{alt}+2*x_{alt}=f(x_{alt})[/mm]
>
> 2. Schritt: [mm]x_{neu}=x_{alt}+1[/mm]
das habe ich eben auch so in Erinnerung.
>
> Bei einer while-Schleife wird erst die Schleifenvariable
> angepasst und dann die eigentliche Anweisung ausgeführt:
Hier hast du es doch selbst in der Hand. While- oder auch Do-Schleifen laufen einfach so lange, so lange eine Aussage wahr ist, die im einen Fall zu Beginn, im anderen Fall am Ende der Schleife abgeprüft wird.
Wenn du jetzt diese Aussage von einer Integer-Variablen abhängig machst, die iteriert wird, dann hast du es natürlich selbst in der Hand, wo im Code das geschieht.
> Die beiden Schleifen führen also im Allgemeinen nicht auf
> dasselbe Ergebnis. Bleibt noch zu klären, wann welche
> Schleife zur Anwendung kommt. Kann man sich darauf
> beschränken, dass for-Schleifen verwendet werden, wenn
> eine Laufvariable hoch oder heruntergezählt werden soll
> und while-Schleifen in allen übrigen Fällen?
Das ist jetzt einfach ein Erfahrungswert (ich habe früher auch mal relativ viel programmiert, das war aber noch unter MS-DOS, ist also schon ein paar Tage her), aber die for-Schleife müsste theoretisch die von der Laufzeit her schnellere Struktur sein. Ich würde sie daher immer dann einsetzen, wenn ich von vorhnberein die Anzahl der Durchläufe kenne und wenn auch wirklich jeder Wert der Laufvariablen berücksichtigt werden soll. Anderenfalls würde ich es mit While, bzw. Do-While, oder wie auch immer diese Schleifen heißen, versuchen.
Gruß, Diophant
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 14:12 Sa 21.07.2012 | Autor: | Marcel08 |
Alles klar, vielen Dank!
|
|
|
|
|
Hallo!
im Allgemeinen benutzt man FOR-Schleifen, um eine Variable hoch- bzw. runter zählen zu lassen.
Schneller werden die dadurch, daß der Compiler die FOR-Schleife ausschreiben kann, d.h. den Inhalt einfach mehrmals hintereinander im Programmcode auftaucht. Dadurch können die Sprünge an den Anfang der Schleife sowie der Vergleich mit der Abbruchbedingung entfallen.
Das funktioniert aber auch nur, wenn die Abbruchbedingung konstant und zur Compilierzeit bekannt ist (also eine feste Zahl). Und bei Schleifen mit sehr vielen Durchläufen wird der Programmcode irgendwann sehr lang, speziell bei geschachtelten Schleifen.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 09:03 Mi 25.07.2012 | Autor: | Diophant |
Hallo Marcel,
eine weitere Eigenheit zumindest bei C++ habe ich nicht bedacht. Ich weiß aber nicht, ob Java das auch kann.
Sei i die Laufvariable, die inkrementiert wird. Wenn man schreibt
for(i=1;i<=10;i++)
Dann wird der Wert von i tatsächlich am Ende der Schleife iteriert. C++ (und damit Java wohl auch) erlauben aber auch die Syntax
for(i=1;i<=10;++i)
Jetzt steht der Inkrementierungs-Operator vor der Variablen, das bedeutet, sie wird direkt beim Aufruf inkrementiert und damit vor dem Schleifendurchlauf.
Das noch als Ergänzung.
EDIT:
Event_Horizon hat mich dankenswerterweise darauf hingewiesen, dass obiges falsch ist. Beachte seine folgende Mitteilung dazu!
Gruß, Diophant
|
|
|
|
|
Hallo!
nein, das ist falsch:
Code:
1: |
| 2: | for(int i=1; i<10; i++){
| 3: | printf("%2d\n",i);
| 4: | }
| 5: |
| 6: | printf("\n");
| 7: |
| 8: | for(int i=1; i<10; ++i){
| 9: | printf("%2d\n",i);
| 10: | }
|
Ausgabe:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
Es ist also beides gleich.
Der dritte Ausdruck wird erst ausgeführt, nachdem der Schleifenkörper komplett ausgeführt wurde.
i++ und ++i sind in dem Fall identisch. Der Unterschied wird erst hier sichtbar:
i=5;
a=i++;
printf("%d %d", a, i)
i=5;
a=++i;
printf("%d %d", a, i)
Im ersten Fall wird a der Wert von i zugewiesen, und dann i inkrementiert. Die Ausgabe ist dann "5 6".
Im zweiten Fall wird erst i inkrementiert, und dieser Wert dann a zugewiesen. Die Ausgabe ist dann also "6 6".
Der feine Unterschied:
i++ belegt im Speicher Platz für zwei Variablen. Die Variable selbst wird um 1 erhöht, daneben wird aber eine Kopie der Variablen mit dem alten Wert angelegt, welche zurückgegeben (und in dem Beispiel in a geschrieben) wird.
Mit ++i wird die Variable um 1 erhöht, und genau dieser Wert wird zurück gegeben. Es wird keine Kopie angelegt.
Bei einfachen Zahlen spielt das kaum eine Rolle, aber wenn i keine Zahl, sondern ein Iterator für z.B. eine Liste mit sehr langen Strings ist, benötigt der Rechner für das Anlegen einer Kopie bei i++ doch schon mehr Rechenzeit und Speicher. Da ist ++i besser.
Das ist der einzige Unterschied im Zusammenhang mit FOR-Schleifen. Allerdings frage ich mich, ob heutige Compiler das nicht merken, und automatisch intern das i++ in ein ++i umwandeln.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 18:38 Do 26.07.2012 | Autor: | Marcel08 |
Vielen Dank nochmal für die ausführlichen Beteiligungen.
|
|
|
|