rechtwinklige Dreiecke mit while schleifen
-
Hallo,
gleich vorneweg ich weiss, dass man dieses Prolem wohl besser mit einer for schleifen Konstruktion realisiert, mir ging es eher darum eine for schleife mit einer while schleife zu realisieren einfach weil ich gerade die Kontrollstrukturen ganz genau verstehen will
Ich habe also nun folgenden Code:
#include <iostream> using namespace std; int main() { int a=0; int b=0; int c=0; int total=0; while ( a <= 500 ) { while ( b <= 500 ) { while ( c <=500 ) { if ((a*a)+(b*b)==(c*c)) { total++; } c++; } b++; } a++; } cout << "A ist: " << a << " B ist: " << b << " C ist: " << c << " Total ist: "<< total << endl; system("PAUSE"); return 0; }Da dabei
A ist: 501 B ist: 501 C ist: 501 Total ist: 1
rauskommt und das soweit ich weiss nicht stimmt wollte ich mal wissen, wo mein Denkfehler ist

-
Warum sollte das nicht stimmen? Die while-Schleife bricht ab, wenn deine Wert > 500 ist. Das ist bei 501 der Fall oder meinst du das Ergebnis in total?
-
Hauptsächlich das Ergebnis kommt mir falsch vor.
-
Das Ergebnis ist aber richtig, da die if-Bedingung nur einmal zutrift -> a=0,b=0,c=0
-
Laut dem folgenden Programm:
int main() { int total = 0; cout<< "Praktikum 3 Dreieck" <<endl; for ( int n1 = 1; n1<=500; n1++) { for ( int n2 = 1; n2<=500; n2++) { for ( int n3 = 1; n3<=500; n3++) { if ((n1*n1)+(n2*n2)==(n3*n3)) { total++; } } } } cout<<total<<endl; system("PAUSE"); return 0; }Liegt das korrekte Ergebnis aber bei 772?
-
Dann setze c in der b-Schleife wieder auf 0 und b in der a-Schleife auf 0. Die Schleifen werden von innen nach aussen aufgelöst, d.h. wenn c == 501 wird b incrementiert. Da c aber nicht zurüchgesetzt wurde ist die Bedingung nicht erfüllt und b wird wieder incrementiert usw. usw. und zum Schluss das gleiche Spiel mit a.
-
Wieso sollte ich b wieder auf null setzen ich will doch das es aufsteigt?
Wenn ich es richtig sehe ist eine vor schleife doch "nur" eine etwas anders geschriebene while schleife (ok da gibts noch break und continue) deswegen verstehe ich nicht wirklich wo nun der Unterschied zwischen den For Bedingungen und meinen while bedingungen ist ?
-
Nur dass bei der for-Schleife der index jedesmal neu auf den Anfangswert gesetzt wird.
-
In der for-Schleife wird nach Incrementierung der nächst höheren wieder von vorne begonnen, d.h.
n1 = 1
n2 = 1
n3 = 1...500dann
n1 = 1
n2 = 2
n3 = 1...500usw.
Bei deinen While-Schleifen geschieht dies aber nicht, es sei denn du setzt nach jedem kommpletten Umlauf den Wert wieder auf den Anfangszustand, damit die Bedingungen wieder neu ausgewertet werden können.
Teste es doch mal mit kleineren Werten(z. B. 5) und dem Debugger. Setze dazu einen Breakpoint bei einer der while-Schleifen und steppe im einzelschritt dann durch.
[Edit] Oh mann, diese Rechtschreibung[/Edit]
-
Hm... durch welchen Teil der for schleife passiert das denn genau? Bis jetzt hatte ich es nämlich so verstanden, dass auch bei der for schleife alles "gleichzeitig" hoch gezählt wird
-
Schau mal in diesen Thread hier unter dir.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-203533.html
asc erklärt das schön.
-
ThaRealMatix schrieb:
Hm... durch welchen Teil der for schleife passiert das denn genau?
Was meinst du damit?
ThaRealMatix schrieb:
Bis jetzt hatte ich es nämlich so verstanden, dass auch bei der for schleife alles "gleichzeitig" hoch gezählt wird
Nein, immer von innen nach aussen
for(int n1 = 0; n1 < 2; ++n1) { for(int n2 = 0; n2 < 2; ++n2) { for(int n3 = 0; n3 < 2; ++n3) { // mach was } } }Erste Runde n1=0,n2=0 und n3 wird von 0 bis 1 abgearbeitet.
Dann wird n2 um 1 erhöht und n3 wieder abgearbeitet.
Danach wird erst n1 erhöht, n2 beginnt wieder bei 0 und n3 ebenfalls und das eben beschriebene wiederholt sich.
-
Eine for schleife in c++
for(int i=0; i == 3 ; i++) { ... }und die equivalente while schleife
{ int i = 0; while( i == 3 ) { ... i++; } } // hier ist i ungültigbeachtet die lokale variable i
-
michme schrieb:
Nein, immer von innen nach aussen
for(int n1 = 0; n1 < 2; ++n1) { for(int n2 = 0; n2 < 2; ++n2) { for(int n3 = 0; n3 < 2; ++n3) { // mach was } } }Erste Runde n1=0,n2=0 und n3 wird von 0 bis 1 abgearbeitet.
Dann wird n2 um 1 erhöht und n3 wieder abgearbeitet.
Danach wird erst n1 erhöht, n2 beginnt wieder bei 0 und n3 ebenfalls und das eben beschriebene wiederholt sich.Deine Beschreibung sehe ich nicht als aussagekräftig genug für einen Anfänger an.
Ich greife mal dein Beispiel, und sage mal wir geben dort immer n1, n2, n3 aus:
n1:0, n2:0, n3:0
n1:0, n2:0, n3:1
n1:0, n2:1, n3:0
n1:0, n2:1, n3:1
n1:1, n2:0, n3:0
n1:1, n2:0, n3:1
n1:1, n2:1, n3:0
n1:1, n2:1, n3:1Er kommt zuerst in den Anweisungsblock der äußersten Schleife, da dort eine weiterere Schleife ist wird diese ausgeführt, da dort wieder eine Schleife ist wird diese ausgeführt. Dann wird die innerste Schleife das erste mal vollständig abgearbeitet und es geht mit der zweiten Schleife weiter, diese startet den nächsten durchgang, wodurch die innere wieder komplett abgeschlossen wird, dann ist endlich die 2te das erste mal komplett, und es geht weiter mit der äußersten... usw.
cu André
-
@asc: Danke, meine Gedanken in die richtigen Worte gefasst.
-
ok ich glaube nun verstanden zu haben, wie diese for Schleife funktioniert (obwohl ich nicht wüsste, wie man das in Worte fassen soll, aber es erinnert mich irgendwo an die bitweise anzeige von zahlen, wenn es darum geht hochzuzählen [natürlich nru bei 0 und 1]
Wie genau müsste denn nun eine While schleife aussehen? Denn grundsätzlich ist eine for schleife ja mit einer while schleife realisierbar, nur das kein break und kein continue geht richtig?
-
Das hat @michme doch schon geschrieben.
Und so sieht es dann aus:while ( a <= 500 ) { b = 0; // hier b jedesmal initialisieren while ( b <= 500 ) { c = 0; // hier c jedesmal initialisieren while ( c <=500 ) { if ((a*a)+(b*b)==(c*c)) { total++; } c++; } b++; } a++; }So hast du 500 * 500 * 500 Vergleiche.
Bei deiner vorigen Version werden die beideren inneren while-Schleifen nur bei a=0 durchlaufen und danach dann nie wieder, da b und c jeweils den Wert 501 haben.P.S. Auch break und continue sind bei einer while- bzw. do-while-Schleife erlaubt (und genauso sinnvoll wie bei einer for-Schleife).
-
Ah okay verstehe... aber noch nicht so wirklich wie die schleifen sich nun auflösen... sehe ich es richtig das die innerste schleife nicht mehr läuft wenn die schleife von b durchgelaufen ist und somit c auch nicht mehr initalisiert wird? dann würde aber doch IMMER gegen c=500 verglichen?
Und wozu genau ist eine for schleife denn dann gut, ausser das sie kürzer zu schreiben ist? Wann sollte ich for und wann while benutzten?
-
ThaRealMatix schrieb:
Ah okay verstehe... aber noch nicht so wirklich wie die schleifen sich nun auflösen... sehe ich es richtig das die innerste schleife nicht mehr läuft wenn die schleife von b durchgelaufen ist und somit c auch nicht mehr initalisiert wird? dann würde aber doch IMMER gegen c=500 verglichen?
Nein gegen 501, da vor verlassen der Schleife nochmal inkrementiert wird, die while-Bedingung nochmal geprüft wird und dann erst die Schleife verlassen wird, weil c nicht mehr <=500 ist.
Lass mal folgendes laufen und schau dir die Ausgabe genau an:#include <iostream> int main() { int a=0, b=0, c=0, total=0; while ( a <= 3 ) { if(a > 0) { std::cout << "a wurde inkrementiert: b wird mit 0 (re)initialisiert!" << std::endl; } b = 0; // hier b jedesmal initialisieren while ( b <= 3 ) { if(b > 0) { std::cout << "b wurde inkrementiert: c wird mit 0 (re)initialisiert!" << std::endl; } c = 0; // hier c jedesmal initialisieren while ( c <= 3 ) { if ((a*a)+(b*b)==(c*c)) { std::cout << "if-Bedingung ergab true" << std::endl; total++; } std::cout << "if-Bedingung wurde gepueft, c wird inkrementiert" << std::endl; c++; } b++; } a++; } std::cout << "Alle Schleifen vollstaendig abgearbeitet"; std::cout << "\ntotal= " << total << std::endl; return 0; }Sollte deine Konsole sofort schliessen, schau in der FAQ nach "Schließen der Konsole verhindern"
-
Und wozu genau ist eine for schleife denn dann gut, ausser das sie kürzer zu schreiben ist? Wann sollte ich for und wann while benutzten?
Wozu ist "a[x]" gut wenn man auch "*(a+x)" schreiben kann?
Wozu ist "a->b" gut wenn man auch "(*a).b" schreiben kann?