Wieso kann ich das hier nicht ausführen ?

  • #1
G

Game12

Bekanntes Mitglied
Themenersteller
Dabei seit
07.01.2005
Beiträge
436
Reaktionspunkte
0
Code:
#include <iostream>
#include <math.h>
using namespace std;

int main ()
{

 double ergebnis;
 double gerundetesergebnis;
 for(double zahln=3.0;zahl <=10.0;zahl=zahl+1.0)
 {
  for(double teiler =2.0;teiler <= zahl;teiler=teiler+1.0)
  {
   if(teiler==zahl)
   {
    cout << zahl << endl;
    continue;
   }
   ergebnis = zahl / teiler;
   gerundetesergebnis=floor(ergebnis);

   if(ergebnis==gerundetesergebnis)
   {
    continue;
   }
  }
 }
 return 0;
}

oder wie kann ich den Fehler beheben ?

das Programm soll alle Primganzzahlen zwischen 3.0 und 10.0 auflisten...
 
  • #2
  • #3
nein aber das ist nicht der fehler
 
  • #4
wenn ich das programm mit Borland starten will stürtzt Borland ersteinmal ab und in Ms Visual C++ 6.0 kommt eine meldung :

Programm kann nicht ausgeführt werden ...???
 
  • #5
falls es jemand weiter bringt :

Code:
1
CLS
INPUT Anfang (Max. 32767) :, b
IF b <= 0 THEN END
IF b <> CINT(b) THEN END
INPUT Maximum (Max. 32767) :, v
IF v <= b THEN END
IF v <> CINT(v) THEN END


x = b
a = 0
y = 2
10  IF x = v THEN GOTO 50
  
  
30 y = 2
35 IF y < x THEN GOTO 20 ELSE PRINT x: a = a + 1: c = x: e = 0: GOTO 40
36
20  z = x / y
  z = CINT(z)


  IF x / y = z THEN e = 1: GOTO 40


  y = y + 1

GOTO 35

40
 IF a = 1 THEN IF e = 0 THEN d = x
  
  
  
  
  
  
  
  
  
  
  
   x = x + 1
   GOTO 10


  
50 PRINT 
  PRINT  ===========================================================================
  PRINT   erste gepr￾üfte Zahl   :; b
  PRINT   letzte gepr￾üfte Zahl   :; v
  PRINT   gepr￾üfte Zahlen     :; v - b
  PRINT 
  PRINT   gefundene Primzahlen   :; a
  PRINT   letzte gefundene Primzahl:; c
  PRINT   erste gefundene Primzahl :; d
  PRINT  ===========================================================================

i$ = INPUT$(1)






GOTO 1

END
 
  • #6
Wenn ich den Code den du am Anfang gepostet hast verbesser (also das n weg mache) und ihn dann mit Dev-C++ compiliere funktioniert das Programm, es gibt die Priemzahlen aus. ???
 
  • #7
in dev-c++ gibt das programm bei mir alle zahlen bis 10 aus .
 
  • #8
Game12 schrieb:
in dev-c++ gibt das programm bei mir alle zahlen bis 10 aus .

if(ergebnis==gerundetesergebnis)
  break;

BTW: Du kannst auch den Modulo-Operator (%) verwenden (statt mit Fließkommazahlen zu arbeiten).
a%b
Wenn die Division a/b aufgeht, ist der Ausdruck= 0.
 
  • #9
DANKE!

Ich hab mich so geärgert :mad: , weil mein Programm wegen 1 einzigen Syntaxverwechslung gleich so schlimme Fehler macht , aber was solls ,Danke

edit :

ich glaube mit diesem programm hat sich die Varible: HöchstePrimzahlDieIchKenne stark vergrößert ;D

Code:
#include <iostream>
#include <math.h>
using namespace std;

int main ()
{
 long max,start;

 cout<< Start:;
 cin >> start;
 cout <<Max :;
 cin >> max;

 long gerundetesergebnis;
 for(long zahl=start;zahl <=max;zahl++)
 {
  for(long teiler =2;teiler <= zahl;teiler++)
  {
   if(teiler==zahl)
   {
    cout << zahl << endl;
    continue;
   }



   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }
 cin.get();
 return 0;
}
 
  • #10
Die neue Version Deines Programms ist deutlich schneller als die alte. Man könnte vielleicht noch ein bischen optimieren - ohne die Methode grundsätzlich zu verändern - indem man ausnutzt, dass nur jede 2. Zahl (wenn man mit einer ungeraden Zahl >2 anfängt) überhaupt eine Primzahl sein kann und außerdem die innere Schleife nur bis maximal Wurzel(zahl) laufen lässt. So in der Art:

Code:
void prim(int start, int end) {

  if(start <= 2) {
    cout << 2 << endl;
    start= 3;
  }

  if(start%2 == 0)
    start++;

  for(int zahl= start; zahl<=end; zahl+=2)
  {
    int maxteiler= (int)sqrt((float)zahl);
    bool prim= true;
    for(int teiler=2; teiler<=maxteiler; teiler++)
    {  
      if(zahl%teiler == 0) {
        prim= false;
        break;
      }
    }

    if(prim)
      cout << zahl << endl;
  }
}
 
  • #11
ich glaube aber,dass der Computer länger braucht die paar befehle mehr auszuführen als teiler bzw start um 1 bzw 2 zu erhöhen ....

edit:

ist es wirklich schon schlechter Stil wenn man ein goto wie folgt verwendet ?:

Code:
#include <iostream>
#include <math.h>
using namespace std;

int main ()
{
 anfang: long max,start;

 cout<< Start:;
 cin >> start;
 if(start<=0)
 {
  return 1;
 }

 cout <<Max :;
 cin >> max;
 if(max<=0)
 {
  return 1;
 }


 for(long zahl=start;zahl <=max;zahl++)
 {
  for(long teiler =2;teiler <= zahl;teiler++)
  {
   if(teiler==zahl)
   {
    cout << zahl << endl;
    break;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }
  goto anfang;


}
 
  • #12
ich glaube aber,dass der Computer länger braucht die paar befehle mehr auszuführen als teiler bzw start um 1 bzw 2 zu erhöhen ....

Meinst Du jetzt wegen der Wurzelberechnung? Die wird ja nur in der äußeren Schleife ausgeführt, also->max' mal bzw. bei +=2 dann->max/2' mal. Die innere Schleife dagen wird sehr, sehr [noch viele sehr dranhängen :)] oft aufgerufen bei größeren Werten von->max'.

'max' jeweils von 1 bis ...


Äußere Schleife (max)

,  Innere Schleife (2..zahl)

10

19

100

1.158

1000

78.190

10.000

5.776.452

100.000

455.198.742

Wenn max= 100.000 ist, wird die innere Schleife mehr als 455 Millionen mal abgearbeitet. Deswegen ist ein kleiner Rechenaufwand in der äußeren Schleife kein Problem, wenn damit die Anzahl der Durchläufe der inneren Schleife deutlich herabgesetzt werden kann:

start: 1
max: 100000

1. Version: 37.3234 Sekunden
2. Version: 9.06279 Sekunden
3. Version: 0.0555713 Sekunden

// Edit: Jeweils ohne Ausgabe natürlich

ist es wirklich schon schlechter Stil wenn man ein goto wie folgt verwendet ?:

Es gibt sicher schlimmere Fälle ;), aber man sollte es einfach vermeiden. Die einzige Situation, in der man goto verwenden kann/sollte, ist der Ausbruch aus einer wirklich tiefen Verschachtelung. Allerdings habe ich es noch nie gebraucht.

Bei Deinem Programm lässt sich das Problem lösen (ohne das Programm unübersichtlich zu machen), indem Du nicht alles in main packst, sondern zusätzliche Funktionen schreibst. Natürlich ist das bei einem so kleinen Programm nicht unbedingt nötig, aber bei nur etwas komplexeren Programmen kann es die Übersichtlichkeit schon erhöhen. Selbst bei diesem Programm hier hat es den Vorteil, dass man weitere Methoden zur Berechnung von Primzahlen testen kann, ohne in der Hauptfunktion viel zu ändern oder irgendwas auskommentieren zu müssen (weil man es nicht löschen möchte). Einfach eine neue Funktion schreiben und den Funktionsaufruf ändern.

Code:
#include <iostream>
#include <cmath>

using namespace std;

bool valtest(int start, int max) 
{
  if((start >= max) || (max<0) || (max<0))
    return false;
  else
    return true;
}

void prim(int start, int max) 
{
  for(int zahl= start; zahl<=max; zahl++)
  {
    for(int teiler=2; teiler<=zahl; teiler++)
    {
      if(teiler==zahl)
      {
        cout << zahl << endl;
        break;
      }
      if((zahl%teiler)==0)
        break;
    }
  }
}

int main ()
{
  int start, max;
  
  for(;;) 
  {    
    cout << Max 0 = Ende << endl << endl;
    cout << Start: ;
    cin >> start;
    cout << Max: ;
    cin >> max;

    if(max==0)
      break;
    else 
    {
      if(valtest(start, max)) 
      {
        prim(start, max);
        cout << endl << endl;
      } else
        cout << Eingabe fehlerhaft << endl << endl;
    }
  }

  return 0;
}
 
  • #13
Würdest du dieses Programm akzeptieren?

Entschuldigung das ich dich nerve, Entschuldigung: :-*


Code:
#include <iostream>
#include <math.h>
using namespace std;

void berechnung(long start,long max)
{
 long maxteiler;
 if((start%2)==0)
 {
  start++;
 }

 for(long zahl=start;zahl <=max;zahl+=2 )
 {
  maxteiler=sqrt(zahl)+1;

  for(long teiler =2;teiler <= zahl;teiler++)
  {
   if(teiler>=maxteiler)
   {
    cout << zahl << endl;
    break;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }
}

long eingeben(string ausgeben)
{
 long eingabe;

 cout<< ausgeben;
 cin >> eingabe;

 return eingabe;
}

int main ()
{
 long eingabe1,eingabe2;


 while(1)
 {
  while(1)
  {

   eingabe1=eingeben(Start (0 zum beenden):);
   if (eingabe1 ==0)
   {
    return 1;
   }
   else if(eingabe1<0)
   {
    cout <<endl<<Falsche Eingabe, bitte wiederholen....<<endl<<endl;
    continue;
   }
   break;
  }
  while(1)
  {

   eingabe2=eingeben(Max  (0 zum beenden):);
   if (eingabe2 ==0)
   {
     return 1;
   }
   else if(eingabe2<eingabe1)
   {
    cout<<endl<<Falsche Eingabe, bitte wiederholen....<<endl<<endl;
    continue;
   }
   break;

  }
  berechnung(eingabe1,eingabe2);
 }
}

edit:

Code:
#include <iostream>
#include <math.h>
using namespace std;

void berechnung(long start,long max)
{
 long maxteiler;
 if((start%2)==0)
 {
  start++;
 }

 for(long zahl=start;zahl <=max;zahl+=2 )
 {
  maxteiler=sqrt(zahl)+1;

  for(long teiler =2;teiler <= zahl;teiler++)
  {
   if(teiler>=maxteiler)
   {
    cout << zahl << endl;
    break;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }
}

long eingeben(string ausgeben)
{
 long eingabe;

 cout<< ausgeben;
 cin >> eingabe;

 return eingabe;
}

int varpruef(long eingabe ,long vergl1,long vergl2)
{
 if (eingabe ==vergl1)
   {
    return 2;
   }
   else if(eingabe<vergl2)
   {
    cout <<endl<<Falsche Eingabe, bitte wiederholen....<<endl<<endl;
    return 1;
   }
   return 0;


}

int main ()
{
 long eingabe1,eingabe2;


 while(1)
 {
  int brake=1;

  while(brake == 1)
  {
   eingabe1=eingeben(Start (0 zum beenden):);
   brake =varpruef(eingabe1,0,0);
  }
  if(brake==2)
   return 1;

  brake =1;
  while( brake==1 )
  {
   eingabe2=eingeben(Max  (0 zum beenden):);
   brake=varpruef(eingabe2,0,eingabe1);
  }
  if(brake==2)
   return 1;


  berechnung(eingabe1,eingabe2);
 }
}
 
  • #14
Würdest du dieses Programm akzeptieren?

Na ja, was heisst akzeptieren; bin ja nicht der Kaiser von China ;). Ich kann Dir ja auch nur ein paar Tipps geben (und ob diese gut sind, liegt im Auge des Betrachters).

Zum Programm: Ist doch schon gut; sogar mit Abbruch an beliebiger Stelle.

Ein paar Details:

Der Typ long ist eigentlich nicht nötig, da auch int (unter Win32 und halbwegs aktuellen Compilern) 32 Bit groß ist.

Evtl.->#include <cmath>' statt des älteren->#include <math.h>.

'maxteiler= sqrt(zahl)+1;'
Gibt Dein Compiler da weder eine Warnung noch einen Fehler aus? Mit VC6 habe ich es nicht probiert, aber VC2003 kompiliert das so nicht:
warning conversion from->float' to->long', possible loss of data
error:->sqrt' : ambiguous call to overloaded function
Die Bedeutung der Warnung ist Dir sicher klar. Der Fehler hat folgenden Hintergrund: In C++ kann man Funktionen überladen. Das bedeutet, man kann Funktionen schreiben, die identische Namen haben, aber verschiedene Parameter entgegennehmen. Der Compiler versucht herauszufinden, welche Parameter passen würden; die entsprechende Funktion wird dann zur Laufzeit des Programmes aufgerufen. Die Wurzelfunktion ist überladen:
double sqrt(double x);
float sqrt(float x);
Da aber der Parameter->zahl' vom Typ->long' ist, versucht der Compiler,->zahl' implizit (also ohne ausdrückliche Angabe des Zieltyps wie in der Beispielfunktion oben irgendwo) in eine Fließkommazahl umzuwandeln. Allerdings kann er nicht entscheiden, ob sie in ein double oder ein float konvertiert werden soll. Darum der Fehler Mehrdeutiger Aufruf einer überladenen Funktion.

string: Ist das aus der STL (std::string) oder irgendwo als char* definiert?
Wenn std::string, dann besser noch->#include <string>' einfügen.

Ich würde nicht 1 zurückgeben, da es sich ja nicht um einen Fehler handelt, wenn der Anwender beenden will. Du kannst statt->return 0' /->return 1' übrigens auch schreiben->return EXIT_SUCCESS' /->return EXIT_FAILURE'. Dazu musst Du stdlib.h (oder besser cstdlib) einbinden. Ist aber natürlich nicht zwingend notwendig. Überhaupt ist ein Rückgabewert ungleich 0 nur dann wirklich sinnvoll, wenn dieser Wert ausgewertet wird bzw. eine Chance besteht, dass er irgendwann einmal ausgewertet werden könnte. Unter Windows z.B. könntest Du Dein Programm von einer Batchdatei aus starten und dann per errorlevel den Rückgabewert prüfen.

Zu->while(1)'. Da habe ich Dich ja zu was angestiftet :). Solche bedingungslosen Schleifen besser nur sehr sporadisch verwenden. In diesem Programm in der äußeren Schleife finde ich es ok, in den beiden inneren sollte man es vielleicht anders machen.
// Edit: Kannst Du hellsehen? :)
Du könntest nun noch statt der magische Zahlen (1, 2) zwei sinnvoll benannte Konstanten in->varpruef' und->main' verwenden (unter using namespace std; jeweils definieren mit const int variablenname= wert;)

Entschuldigung das ich dich nerve

Nein, ich muss mich wohl eher dafür entschuldigen, dass ich immer so viel schreibe ...
 
  • #15
Vielen Dank Dings,

Also VC6 funktioniert bei mir gerade nicht wirklich aber in Borland CBuilderX kommt weder eine Warnung noch eine Fehlermeldung, aber sobald ich math.h durch cmath ersetze kommt die von dir erklärte Fehlermeldung :-\ ,naja dann binde ich eben beides ein ;D


Code:
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;

int berechnung(int start,int max)
{
 int maxteiler;
 int primzahlen=0;
 if (start==1)
 {
  cout << 1 <<endl<<2<<endl;
  primzahlen =2;
 }
 if(start==2)
 {
  cout <<2<<endl;
  primzahlen=1;
 }



 if((start%2)==0)
 {
  start++;
 }

 for(int zahl=start;zahl <=max;zahl+=2 )
 {
  maxteiler=sqrt(zahl)+1;

  for(int teiler =3;teiler <= zahl;teiler+=2)
  {
   if(teiler>=maxteiler)
   {
    primzahlen++;
    cout << zahl << endl;
    break;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }
 return primzahlen;
}

int Ersteprimzahl(int start,int max)
{
 int maxteiler;
 if(start==1)
  return 1;
 else if (start==2)
  return 2;

 if((start%2)==0)
 {
  start++;
 }

 for(int zahl=start;zahl <=max;zahl+=2 )
 {
  maxteiler=sqrt(zahl)+1;

  for(int teiler =2;teiler <= zahl;teiler++)
  {
   if(teiler>=maxteiler)
   {



    return zahl;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }




 if (start==max)
  return start;
 else
  return 0;


}
int Letzteprimzahl(int start,int max)
{
 int maxteiler;

 if((max%2)==0)
 {
  max--;
 }

 for(int zahl=max;zahl >=start;zahl-=2 )
 {
  maxteiler=sqrt(zahl)+1;

  for(int teiler =2;teiler < zahl;teiler++)
  {
   if(teiler>=maxteiler)
   {



    return zahl;
   }

   if((zahl%teiler)==0)
   {
     break;
   }
  }
 }




 if (start==max)
  return start;
 else
  return 0;


}


int eingeben(string ausgeben)
{
 int eingabe;

 cout<< ausgeben;
 cin >> eingabe;

 return eingabe;
}

string varpruef(int eingabe ,int vergl1,int vergl2)
{
 if (eingabe ==vergl1)
   {
    return end;
   }
   else if(eingabe<vergl2)
   {
    cout <<endl<<Falsche Eingabe, bitte wiederholen....<<endl<<endl;
    return wiederh;
   }
   return brake;


}

void auswertung(int start,int max,int primzahlen)
{
 int erstePrimzahl=Ersteprimzahl(start,max);
 int letztePrimzahl=Letzteprimzahl(start,max);
 cout <<endl<<endl;
 cout <<Erste gepruefte Zahl : <<start<<endl;
 cout <<Letzte gepruefte Zahl: <<max<<endl;
 cout <<gepruefte Zahlen   : <<max-start<<endl;
 cout <<Erste Primzahl    : << erstePrimzahl<<endl;
 cout <<Letzte Primzahl   : <<letztePrimzahl<<endl;
 cout <<gefundene Primzahlen : <<primzahlen <<endl;
 cout <<endl;




}

int main ()
{
 int eingabe1,eingabe2;


 while(1)
 {
  string brake=wiederh;
  while(brake == wiederh)
  {
   eingabe1=eingeben(Start (0 zum beenden):);
   brake =varpruef(eingabe1,0,0);
  }
  if(brake==end)
   return EXIT_SUCCESS;

  brake =wiederh;
  while( brake==wiederh )
  {
   eingabe2=eingeben(Max  (0 zum beenden):);
   brake=varpruef(eingabe2,0,eingabe1);
  }
  if(brake==end)
   return EXIT_SUCCESS;


  int primzahlen=berechnung(eingabe1,eingabe2);
  auswertung(eingabe1,eingabe2,primzahlen);
 }
}
Dings schrieb:
string: Ist das aus der STL (std::string) oder irgendwo als char* definiert?
Wenn std::string, dann besser noch->#include <string>' einfügen.

tut mir Leid ,das versteh' ich nicht :(
 
  • #16
naja dann binde ich eben beides ein

Hehe. Bitte nicht :). Einfach cmath einbinden (nicht das für C++ veraltete math.h) und casten. Man sollte sich natürlich immer überlegen, wo und warum man castet, aber in diesem Fall ist es korrekt und so gewollt. Wie dem auch sei, Du weisst ja nun, was dieser Fehler bedeutet.

Das andere meinte ich so:

Du hast hier den Typ string benutzt:
Code:
int eingeben(string ausgeben)

Dieser Typ muss natürlich irgendwo definiert sein. Des Rätsels Lösung: Er ist Teil der Standard Template Library (*)  [ Lesen und vorerst vergessen: er ist bloß ein per typedef spezialisierter base_string:
typedef basic_string<char, char_traits<char>, allocator<char> > string; ]

und wird hier nur indirekt über das Einbinden von->iostream' Deinem Programm (besser gesagt: dem Compiler) bekannt.
Dann kommt:

Code:
cout << ausgeben;

Das funktioniert aber, je nach Auslegung der Headerdateien, nicht immer. Wenn Du den Typ string verwendest, solltest Du auf jeden Fall auch (zusätzlich) den entsprechenden Header einbinden:

Code:
#include <string>

(*)
Die STL ist eine generische C++ Bibliothek, die Container, Algorithmen, Iteratoren und einige Hilfsklassen bereitstellt. In Deinem Programm gehören z.B. iostream und string zur STL. Du solltest Dich aber erst intensiver mit der STL beschäftigen, wenn Du die Themen Klassen und Templates durchgearbeitet hast, denke ich. Natürlich ist es trotzdem sinnvoll, wenn Du Streams zur Ein- und Ausgabe schon jetzt verwendest (was Du ja auch tust).

---

string varpruef(int eingabe, int vergl1, int vergl2)

Hier könntest Du evtl. besser statt eines Strings Konstanten verwenden, z.B. so:

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

const int PRUEFERGEBNIS_ENDE= 0;
const int PRUEFERGEBNIS_FEHLER= 1;

...

int varpruef(int eingabe, int vergl1, int vergl2)
...
return PRUEFERGEBNIS_ENDE;
...
return PRUEFERGEBNIS_FEHLER;
...

Und unten dann statt Strings einfach int-Werte mit diesen Konstanten vergleichen.


Eine Winzigkeit: Du könntest noch darauf achten, nach jedem Komma und Semikolon (außer beim Zeilenende) ein Leerzeichen zu setzen ...

varpruef(eingabe2,0,eingabe1);
varpruef(eingabe2, 0, eingabe1);

... sowie vor und nach den Operatoren << und >> je ein Leerzeichen:

cout<<endl<<Falsche Eingabe, bitte wiederholen....<<endl<<endl;
cout << endl << Falsche Eingabe, bitte wiederholen.... << endl << endl;
 
Thema:

Wieso kann ich das hier nicht ausführen ?

ANGEBOTE & SPONSOREN

Statistik des Forums

Themen
113.839
Beiträge
707.962
Mitglieder
51.492
Neuestes Mitglied
Janus36
Oben