[gelöst] Endlosshleife
-
Hi,
ich bin neu hier und habe gestern mit C++ angefangen.
Ich bin nicht besonders gut
.
Auf jeden Fall habe ich eine Frage zu der For-Schleife.In "anderen" Programmiersprachen ist das ja meistens von;bis;step.
Das ist in C++ ja im Prinzip genauso. Das dumme ist nur, dass ich nicht weis, wie ich das "bis" in C++ zu schreiben habe
In meinem Fall wäre das dieser Code:#include <iostream> using namespace std; bool istPrim(int kandidat) { bool prim = false; int i; for(i=2;kandidat-1;i=i+1) { { if ((kandidat%i)==0) prim = false; else prim = true; } } return prim; } int main() { int i; for(i=1;i<=100;i=i+1) { { if ((istPrim(i))==true) cout<<"Die zahl "<<i<<" ist eine Primzahl"<<endl; } }; };In meinem Tutorial sollte ich alle Primzahlen von 1 bis 100 aufzählen.
Durch diesen Code
for(i=2;kandidat-1;i=i+1)hab ich natürlich ne Endlosschleife drin.
Ich bin m ir nicht sicher wie ich das schreiben muss, so vielleicht?for(i=2;i<kandidat;i=i+1)Es ist aber irgendwo noch en Denkfehler drin, den ich jetzt erst mal suchen muss.
Könnt ihr mir vielleicht noch sagen, was im am Syntax verbessern könnte, oder sonst vom Programmierstil her.
Ich danke euch schonmal ganz herzlich

Mfg. arnonym
PS. gibts hier Spoiler?
-
Ja, du hast einen Denkfehler. For-Schleifen in C++ haben folgende Semantik:
for (Initialisierung; Weiterführungsbedingung; Zuweisung für Schritt)Aber das sind nun wirklich ziemliche Grundlagen. Bitte schau dir ein Buch an, dort sollte alles gut erklärt werden. Zur Not tuts auch ein Tutorial, was ich aber nicht empfehle.
-
naja die Endlosschleife haste ja selbst rausgefunden - i< kandidat ist schonmal nicht schlecht.
Zum Stil: Leerzeichen können die Übersichtlichkeit erhöhen, z.B. in deinen for-Schleifenköpfen. Außerdem benutzt du teils zu viele Klammern (doppelt hält besser?) Ich schreib jetzt mal dein Programm nochmal hin mit einigen kleinen Verbesserungen die ich anbringen würde:#include <iostream> //using namespace std; //wenn der Namespace nicht grade übermäßig häufig benutzt wird würde ich using-direktiven rauslassen bool istPrim(int kandidat) { bool prim = true; //die Zahl ist so lange Prim wie du keinen Teiler findest, also true initialisieren! for (int i=2; i < kandidat; ++i) //schleifenzähler im schleifenkopf definieren, wenn du ihn nach der schleife nicht mehr brauchst // i = i+1 kann ersetzt werden durch den inkrementoperator ++ { // { //doppelt geschachtelter Block ist unnötig... if ((kandidat%i)==0) prim = false; // else // prim = true; //der else-zweig muss raus von der Logik her. sonst zäglt nur der letzte schleifendurchlauf, alle anderen davor werden sonst so oder so überschrieben // } } return prim; } int main() { for(int i=1; i<=100; ++i) //siehe oben { if (istPrim(i)) //vergleich auf true ist unsinnig, istPrim liefert doch schon den wahrheitswert std::cout << "Die Zahl " << i << " ist eine Primzahl" << std::endl; }; } //semikolon am Ende braucht nicht sein...Das soweit fürs erste. Danach ist immernoch einiges zu verbessern:
#include <cmath> bool istPrim(int kandidat) { for (int i = 2; i < std::sqrt(kandidat)+1; ++i) //es reicht bis sqrt(kandidat) zu testen, bzw. zur nächst größeren Ganzzahl //denn wenn kandidat einen Teiler größer als die wurzel hat, muss es einen zweiten Teiler kleiner als die Wurzel geben { if (kandidat%i == 0) return false; //Teiler gefunden, brauche nicht weiter suchen } //wenn ich hier hinkomme war die suche erfolglos, also: return true; }letzte kleine Verbesserung wäre jetzt noch, die Wurzel mittels static_cast in einen int zu casten, damit nicht bei jedem Schleifendurchlauf i in einen double gecastet wird, aber das fällt unter frühzeitige optimierung und verringert die leserlichkeit.
-
Danke für deine Mühe

Jetzt weis ich wie der Syntax funktioniert und hab eine Perfekt kommentierte Lösung.
Vielen Dank