Problem mit Primzahl und abundantZahl programm



  • Hallo!
    Ich bin ein ziemlicher newbie in Sachen C uznd hab deswegen auch Probleme:-).

    Ich hab 2 Programme geschrieben; eins für die Berechnung von Primzaheln (ich weiß, es ist ein ineffizienter Algorithmus) und ein Programm zum berechnen von abundanten zahlen.

    Prim:

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    
    double a,b,c,d,e,f,von,bis;
    
    int isprime(double number)
    {
     a=sqrt(number);
     for(b=3;b<=a;b+2)
     {
      c = number/b;
      if(c=(int)c)
      {
       return 1;
       goto noprime;
      }
     }
     return 0;
     noprime:;
    }
    
    int main()
    {
     f=0;
     printf("\nBitte geben sie an, von wo bis wo getestet werden soll!");
     printf("\nVon?");
     scanf("%lf",&von);
     printf("\nBis?");
     scanf("%lf",&bis);
     for(d=von;d<=bis;von++)
     {
      e = isprime(d);
      if(e=0)
      {
       printf("\n%lf",d);
       f++;
      }
     }
     printf("\n\nEs wurden %lf Primzahlen gefunden!",f);
    }
    

    da hängt er irgendwie in einer der forschleifen, wahrscheinlich in der der int main().

    Abundant:

    include <stdio.h>
    #include <stdlib.h>
    
    long a,b,c,d,e,f,g,h,i,von,bis;
    
    int isabu(int number)
    {
     a=number/2;
     for(b=1;b<=a;b++)
     {
      c=number % b;
      if(c=0)
      {
       d = d + b;
      }
     }
     if(d>number)
     {
      return 0;
     }
     if(d=number)
     {
      return 1;
     }
     if(d=number+1)
     {
      return 2;
     }
    }
    
    int main()
    {
     printf("geben sie bitte an, von wo bis wo getestet werden soll");
     scanf("/d",von);
     scanf("/d",bis);
     for(e=von;e<=bis;e++)
     {
      f = isabu(e);
      if(f = 1)
      {
       printf("/d ist perfekt",e);
       h = h+1;
      }
      if(f = 0)
      {
       g = g+1;
      }
      if(f = 2)
      {
       printf("/d ist leicht abundant",e);
       i = i+1;
      }
     }
     printf("Es wurden /d abundante, /d leicht abundante und /d perfekte zahlen im Bereich von /d bis /d gefunden",g,i,h,von,bis);
    }
    

    Könnte mir da wer helfen? denn wenn ich das kompilieren möchte gibt er folgendes aus(unter linux mit gcc):

    gcc ABUNDANTC.C -o abundant
    /tmp/ccgsPZyh.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
    collect2: ld returned 1 exit status
    

    MfG

    hannes



  • hanneshoch3 schrieb:

    Prim:

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    
    double a,b,c,d,e,f,von,bis;
    
    int isprime(double number)
    {
     a=sqrt(number);
     for(b=3;b<=a;b+2)
     {
      c = number/b;
      if(c=(int)c)
      {
       return 1;
       goto noprime;
      }
     }
     return 0;
     noprime:;
    }
    
    int main()
    {
     f=0;
     printf("\nBitte geben sie an, von wo bis wo getestet werden soll!");
     printf("\nVon?");
     scanf("%lf",&von);
     printf("\nBis?");
     scanf("%lf",&bis);
     for(d=von;d<=bis;von++)
     {
      e = isprime(d);
      if(e=0)
      {
       printf("\n%lf",d);
       f++;
      }
     }
     printf("\n\nEs wurden %lf Primzahlen gefunden!",f);
    }
    

    Der Algorithmus ist zwar nicht der schnellste, aber das ist nicht wirklich das Problem - viel schwerwiegender ist, daß du ihn falsch impmentiert hast:

    • = ist eine Zuweisung - Vergleiche erledigst du mit ==
    • Prinzahlen-Untersuchungen solltest du besser mit int-Typen durchführen
    • die Aktualisierungsanweisung der Schleife "b+2" macht gar nichts - damit erhältst du eine erstklassische Endlosschleife
    • das goto in der Funktion ist völlig überflüssig - das Programm kommt nicht mal an diese Stelle.
    • und lokal benötigte Variablen solltest du auch nur lokal definieren

    da hängt er irgendwie in einer der forschleifen, wahrscheinlich in der der int main().

    Das solltest du mal etwas genauer einschränken - ich würde übrigens eher auf die Schleife in der isprime() tippen (s.o.)

    Abundant:

    include <stdio.h>
    #include <stdlib.h>
    
    long a,b,c,d,e,f,g,h,i,von,bis;
    
    int isabu(int number)
    {
     a=number/2;
     for(b=1;b<=a;b++)
     {
      c=number % b;
      if(c=0)
      {
       d = d + b;
      }
     }
     if(d>number)
     {
      return 0;
     }
     if(d=number)
     {
      return 1;
     }
     if(d=number+1)
     {
      return 2;
     }
    }
    
    int main()
    {
     printf("geben sie bitte an, von wo bis wo getestet werden soll");
     scanf("/d",von);
     scanf("/d",bis);
     for(e=von;e<=bis;e++)
     {
      f = isabu(e);
      if(f = 1)
      {
       printf("/d ist perfekt",e);
       h = h+1;
      }
      if(f = 0)
      {
       g = g+1;
      }
      if(f = 2)
      {
       printf("/d ist leicht abundant",e);
       i = i+1;
      }
     }
     printf("Es wurden /d abundante, /d leicht abundante und /d perfekte zahlen im Bereich von /d bis /d gefunden",g,i,h,von,bis);
    }
    

    Könnte mir da wer helfen? denn wenn ich das kompilieren möchte gibt er folgendes aus(unter linux mit gcc):

    Das strotzt ja noch mehr von Fehlern - du hast ebenfalls Zuweisung und Vergleich verwechselt, der letzte if()-Zweig der Funktion wird (wenn er korrigiert ist) niemals erreicht - und in den printf()/scanf() Aufrufen hast du / anstelle von % verwendet.



  • also zunächst einmal zu deinem primzahl programm:
    benutz bitte keine sprünge (goto) sondern lieber break oder so was.
    wobei des goto eh nie ausgeführt wird, da davor schon der wert zurückgegeben wird.
    das hängen in der schleife ist auch irgendwie klar, da du zwar im schleifenkopf in isprime()

    for(b=3;b<=a;b+2)
    

    stehen hast, allerdings bewirkt das, dass die schleife nie abbricht, da b immer den wert 3 enthält. ich habe das alles nicht so genau überprüft, schreibe bloß, was mir auffällt.
    das müsste dann

    for(b = 3; b <= a; b+=2)
    

    heißen.
    bei der überprüfung

    if(c = (int) c)
    

    ist auch ein fehler, das müsste

    if(c == (int) c)
    

    heißen, da "=" eine zuweisung darstellt und "==" einen vergleich.
    ich schreibe jetzt lediglich was mir syntaxmäßig dazu auffällt.
    ansonsten, bei der überprüfung auf

    if(e = 0)
    

    wieder das gleiche mit dem vergleich.
    bei dem anderen programm stimmen die vergleiche auch nicht und abgesehen davon ist die formatangabe kein slash ("/") sondern ein prozent-zeichen ("%") für ein- und ausgaben
    was genau der linker error, den du gepostet hast, aussagt, weiß ich nicht, könnte allerdings von einem der erwähnten punkte stammen.



  • Hallo!
    Wie gesagt, ich bin ein ziemlicher Newbie, also entschuldige ich mich für meine Fehler :-).Das Primzahlprogramm läuft jetzt einwandfrei, doch das Programm zum berechnen abundanter zahlen nicht.Hab da auch nochmal drüber geguckt und alles korrigiert, allerdings gibt er mir noch immer dieselbe Meldung aus.

    #include <stdio.h>
    #include <stdlib.h>
    
    long a,b,c,d,e,f,g,h,i,von,bis;
    
    int isabu(long number)
    {
     a=number/2;
     for(b=1;b<=a;b++)
     {
      c=number % b;
      if(c==0)
      {
       d = d + b;
      }
     }
     if(d>number)
     {
      return 0;
     }
     if(d==number)
     {
      return 1;
     }
     if(d==number+1)
     {
      return 2;
     }
    }
    
    int main()
    {
     printf("Geben sie bitte an, von wo bis wo getestet werden soll");
     scanf("%ld",von);
     scanf("%ld",bis);
     for(e=von;e<=bis;e++)
     {
      f = isabu(e);
      if(f == 1)
      {
       printf("%ld ist perfekt",e);
       h = h+1;
      }
      if(f == 0)
      {
       g = g+1;
      }
      if(f == 2)
      {
       printf("%ld ist leicht abundant",e);
       i = i+1;
      }
     }
     printf("Es wurden %ld abundante, %ld leicht abundante und %ld perfekte zahlen im Bereich von %ld bis %ld gefunden",g,i,h,von,bis);
    }
    

    Fällt euch da noch was ein?



  • Kannst du vielleicht mal die Verwendung von globalen Variablen auf ein Minimum beschränken - das hilft zwar vermutlich nichts bei deinem Problem, aber es verbessert die Struktur deiner Programme (und der intensive Gebrauch von globalen Variablen ist einfach nur schlechter Stil).

    Zu dem Fehler: Der Linker findet die angegebene Funktion nicht (vom Namen nach ist das irgendwas, was hinter den Kulissen benötigt wird). Wie du diesen Fehler beheben kannst, sollte die Hilfe des Compilers eigentlich auch erklären - oder Google: Google: __gxx_personality_v0



  • Hallo Hannes³,

    ich habe mir mal deinen Code hergenommen und ihn ein wenig umgeschrieben:

    #include <stdio.h> 
    #include <stdlib.h>
    
    enum Zahl {PERFEKT, ABUNDANT, LEICHT_ABUNDANT, DEFIZIENT, ERR};
    
    static enum Zahl isabu(long number) {
        long a, teiler, summe;
        summe = 0L;
        a=number/2L;
        for (teiler=1L; teiler<=a; ++teiler) {
            if (number%teiler == 0) summe = summe + teiler;
        }
    
        if (summe==number) return PERFEKT;
        if (summe==number+1) return LEICHT_ABUNDANT;
        if (summe>number) return ABUNDANT;  /* die Reihenfolge ist wichtig, da gilt: summe==number+1 dann auch summe > number */
        if (summe < number) return DEFIZIENT;
    
        /* hier sollte das Programm nie hinkommen*/
        return ERR;
    }
    
    int main(void) {
        long von, bis, i, perf, abu, labu, defi;
        perf = 0L;   /* Die Variablen müssen initialisiert werden! */
        abu  = 0L;   /* s.o. */
        labu = 0L;   /* s.o. */
        defi = 0L;   /* s.o. */
    
        printf("Geben sie bitte an, von wo bis wo getestet werden soll\n");
        printf("   von: ");
        scanf("%ld",&von);   /* <- hier wird der Pointer auf long benötigt */
        printf("   bis: ");
        scanf("%ld",&bis);   /* <- s.o. */
    
        printf("Scanne Zahlen von %ld  bis  %ld\n", von, bis);
        for(i=von; i<=bis; ++i) {
            switch(isabu(i)) {
            case PERFEKT:
                printf("%ld ist perfekt\n", i);
                perf++;
                break;
            case LEICHT_ABUNDANT:
                printf("%ld ist leicht abundant\n", i);
                labu++;
                break;
            case ABUNDANT:
                printf("%ld ist abundant\n", i);
                abu++;
                break;
            case DEFIZIENT:
                /* printf("%ld ist defizient\n", i); */
                defi++;
                break;
            default:
                printf("ERROR: %ld\n", i);
                break;
            }
        }
        printf("Es wurden %ld abundante, %ld leicht abundante und %ld perfekte zahlen im Bereich von %ld bis %ld gefunden\n",
                abu, labu, perf, von, bis);
        printf("%ld Zahlen sind defizient\n", defi);
    
        return 0;  /* main benötigt einen return value */
    }
    

    Wie schon CStoll dir geschrieben hat, solltest du auf globale Variablen
    möglichst verzichten. Ich habe hier keine gebraucht.

    Nun zu ein paar deiner Fehler:
    - scanf bekommt einen Zeiger auf das Element, welches du einlesen möchtest.
    - Du hast deine Variablen nicht initialisiert. Beispiel:
    d = d+b;
    Der erste Wert für d ist nicht definiert. Da steht beim Ausführen irgendeine
    Zahl drinnen.
    - Wenn d == number+1 dann ist auch d > number, somit ist die Reihenfolge
    der if-Anweisungen in isabu wichtig.

    Noch ein paar Tips:
    - Benenne deine Variablen und Funktionen klingend. Z.B. d und b sieht man
    nicht an, was die machen sollen.
    - Füge ein paar Kommentare ein, damit du auch später weisst, was eine
    Funktion macht. 😉

    Gruss mcr



  • Ach ja, habe ich noch vergessen.

    Soweit ich weiss, werden C-Files mit einem kleinen c und Headerfiles
    mit einem kleinen h bezeichnet. Der gcc unter Linux unterscheidet
    da zwischen hugo.c und hugo.C (C++).


Anmelden zum Antworten