PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Schleifen "ohne" Abbruchbedingung


Grivel
2013-01-26, 17:49:39
Hi,

(Vorab:Google habe ich nichts gefunden!)

Wieso gibt ein Programm bei

int i=0;
while(i++)
printf("%d",i);

gar nix aus?


Aber bei:
int i=-1;
while(i++)
printf("%d",i);

Gibt es 0 aus.

Bei:

int i=1;
while(i++)
printf("%d",i);

läufts bis unendlich, dass was ich auch bei den anderen beiden Sachen erwartet hätte.

Danke für die Nachhilfe.

fdk
2013-01-26, 17:51:47
weil deine sprache in dem Fall wohl i=0 als false interpretiert.

Gnafoo
2013-01-26, 17:58:33
Weil i++ eins auf i addiert, aber den *alten* Wert zurückliefert.

Im ersten Beispiel kommt direkt beim ersten Aufruf 0 heraus, deshalb wird die Schleife überhaupt nicht betreten. Im zweiten Beispiel gibt es genau eine Iteration, weil erst -1 und dann 0 herauskommt. Im letzten Beispiel fängt es bei 1 an und zählt dann bis der Integer überläuft. Da der Überlauf bei vorzeichenbehafteten Integern undefiniert ist, kann danach alles mögliche passieren.

Was du erwartest, ist vermutlich das Verhalten von ++i.

Gast
2013-01-26, 22:19:11
kommt auf die sprache drauf an. es kommt auch vor, dass -1 als true definiert.

normalerweise ist 0 false und alles andere (oder auch nur der wert 1) true.

z.b. werden kontstrukte wie while(1) verwendet, um eine fortlaufende ausführung in einem thread zu erzeugen, wo dann die abbruchbedigung für die schleife von außen gesteuert werden kann.

Grivel
2013-01-27, 08:59:23
Hi,

danke für die Antworten. So habe ich das ganze nicht betrachtet. (Aber doch realitiv logisch, dass i=0 also false in der While bedingung interpretiert wird)

Sprache natürlich C mit minGW Compiler.

Trap
2013-01-27, 11:26:19
läufts bis unendlich, dass was ich auch bei den anderen beiden Sachen erwartet hätte.
Mit einem int als Zählvariable läuft es sicher nicht bis unendlich. Mit Konsolen-Ausgabe dauert es aber zu lang um das zu sehen.

mittelding
2013-01-27, 12:17:30
Unendlich läuft er wohl schon, nur kommen keine vernünftigen Zahlen mehr dabei raus, oder?

Gohan
2013-01-27, 12:30:28
Unendlich läuft er wohl schon, nur kommen keine vernünftigen Zahlen mehr dabei raus, oder?

Was sind für dich "vernünftige" Zahlen?

Wenn der Datentyp erschöpft ist, kommt es zum Überschlag. Beispiel bei einem 16Bit Integer:

-32768 bis 32767, wenn Signed.
0 bis 65535, wenn Unsigned.

Das heißt wenn das maximal zählbare erreicht ist, geht es bei 0 bzw. -32768 wieder los.

Zwangsläufig wird dann irgendwann wieder die 0 getroffen, was je nach Sprache als false interpretiert wird und die Schleife bricht ab.

PatkIllA
2013-01-27, 14:32:48
danke für die Antworten. So habe ich das ganze nicht betrachtet. (Aber doch realitiv logisch, dass i=0 also false in der While bedingung interpretiert wird)

Sprache natürlich C mit minGW Compiler.
Bei C# kompiliert das erst gar nicht. Wenn man bool will muss man da auch einen boolschen Ausdruck hinschreiben. IMO sauberer auch wenn meist mehr schreiben muss. Dafür werden versehentliche Zuweisungen statt Vergleiche direkt erkannt.

Gnafoo
2013-01-28, 01:09:06
Was sind für dich "vernünftige" Zahlen?

Wenn der Datentyp erschöpft ist, kommt es zum Überschlag. Beispiel bei einem 16Bit Integer:

-32768 bis 32767, wenn Signed.
0 bis 65535, wenn Unsigned.

Das heißt wenn das maximal zählbare erreicht ist, geht es bei 0 bzw. -32768 wieder los.

Zwangsläufig wird dann irgendwann wieder die 0 getroffen, was je nach Sprache als false interpretiert wird und die Schleife bricht ab.

Zumindest bei C und C++ ist das nicht ganz korrekt. Da trifft das nämlich nur auf den unsigned Integer zu.

Beim signed Integer erzeugt der Überlauf dagegen undefiniertes Verhalten. Das heißt der Compiler kann an der Stelle so ziemlich alles machen. Das wird teilweise von Compilern für Optimierungen genutzt, weil diese davon ausgehen dürfen, das ein dieser „Wrap-around“ nicht auftritt. Zum Beispiel darf ein standardkonformer Compiler „a + 1 > a“ durch „true“ ersetzen, wenn a ein „int“ ist. Ebenso darf der Compiler die dritte Schleife im Eingangspost durch eine Endlosschleife ersetzen. Er dürfte genau so gut das Programm beenden, sobald der Integer überläuft.

Beim GCC gibt es deswegen z. B. auch eine extra Compiler-Option „-fwrapv“, um diese Optimierungen zu deaktivieren. Wenn man portablen Code schreiben möchte, dann sollte man Overflows bei einem signed Integer aber einfach vermeiden.

Edit: Beispiel http://ideone.com/Y9YZyV