von c standard in Klassenstruktur übertragen



  • Hallo liebe C-Freunde,
    Ich habe das Problem , dass Ich zu Übungszwecken ein Programm das schon etwas komplexer ist und die Faktorisierung einer Primzahl durführt, in die normale Struktur einer Klasse in c++ überführen möchte. Das Problem Ich kann zwar flüssig c, aber in c++ kommt Fachwissen bezüglich Klassen hinzu, dass mich überfordert. Der Compiler gibt jede Menge Fehlermeldungen aus, die Ich nicht/noch nicht kenne.
    Hier mal die Programme, Original C (lauffähig) , der Transferreversuch , und die Fehlermeldungen des Compilers...
    Originalprogramm

    /* Primfaktorzerlegung einer positiven natuerlichen Zahl n */
    #include <stdlib.h>
    #include <stdio.h>
    void div_potenz(unsigned int *, unsigned int);
    int main( ) {
       unsigned int n,i,l;
       unsigned int r[3]={2,3,5}, 
          q[8]={7,11,13,17,19,23,29,31};
       printf("\nBerechnung der Primfaktorzerlegung \
    von n\n\n");
       printf("n = ");
       scanf("%u",&n);
       if (n!=1) {
          printf("Die Primfaktoren von %u sind:\n\n",n);
          for (i=0; i<3; i=i+1) {
    	 div_potenz(&n,r[i]);
          }
          l=0;
          do {
    	 for (i=0; i<8;i=i+1) {
    	    div_potenz(&n,30*l+q[i]);
    	 }
             l=l+1;
          } while ((30*l+7)*(30*l+7)<=n);
          if (n>1) {
    	 printf("%u Exp.: 1\n",n);
          }
       }
       exit(EXIT_SUCCESS);
    }
    /* Pruefen, ob p|x, Bestimmen und Herausdividieren der 
     * groessten p-Potenz */
    void div_potenz(unsigned int *x, unsigned int p) {
       unsigned int e=0;
       while (*x%p==0) {
          e=e+1;
          *x=*x/p;
       }
       if (e>0) {
          printf("%u Exp.: %u\n",p,e);
       }
    }
    

    geändertes Programm in c++

    #include<iostream>
    using namespace std;
    /**********************************************************/
    class factordevice{
    private:
    unsigned int n,i,l;
    unsigned int r[3]={2,3,5}, q[8]={7,11,13,17,19,23,29,31};
    
    public:
    void div_potenz(unsigned int *, unsigned int);
    void modullaeufer();
    void factortool();
    };
    void factordevice::modulabfrage(){cout<<"Bitte geben Sie n ein: "; cin >> n}
    
    /**********************************************************/
    /**********************************************************/
    void factordevice::modullauefer(){
     if (n!=1) {
          printf("Die Primfaktoren von %u sind:\n\n",n);
          for (i=0; i<3; i=i+1) {
    	 div_potenz(&n,r[i]);
          }
          l=0;
          do {
    	 for (i=0; i<8;i=i+1) {
    	    div_potenz(&n,30*l+q[i]);
    	 }
             l=l+1;
          } while ((30*l+7)*(30*l+7)<=n);
          if (n>1) {
    	 printf("%u Exp.: 1\n",n);
          }
       }
       exit(EXIT_SUCCESS);
    }
    /*********************************************************/
    void factordevice::factortool(){
    void div_potenz(unsigned int *x, unsigned int p) {
       unsigned int e=0;
       while (*x%p==0) {
          e=e+1;
          *x=*x/p;
       }
       if (e>0) {
          printf("%u Exp.: %u\n",p,e);
       }
    }
    /**********************************************************/
    main(){
    factordevice test;
    test.modulabfrage;
    return 0;
    }
    /**********************************************************/
    

    und noch was der Compiler zu dem Versuch sagt:

    soko@soko-HP-Compaq-dx2300-Microtower:~/Arbeitsfläche/Trpl/Trplc++/class1$ g++ primefact.cpp 
    primefact.cpp:7:19: error: a brace-enclosed initializer is not allowed here before ‘{’ token
    primefact.cpp:7:25: error: ISO C++ forbids initialization of member ‘r’ [-fpermissive]
    primefact.cpp:7:25: error: making ‘r’ static [-fpermissive]
    primefact.cpp:7:25: error: invalid in-class initialization of static data member of non-integral type ‘unsigned int [3]’
    primefact.cpp:7:33: error: a brace-enclosed initializer is not allowed here before ‘{’ token
    primefact.cpp:7:56: error: ISO C++ forbids initialization of member ‘q’ [-fpermissive]
    primefact.cpp:7:56: error: making ‘q’ static [-fpermissive]
    primefact.cpp:7:56: error: invalid in-class initialization of static data member of non-integral type ‘unsigned int [8]’
    primefact.cpp:14:33: error: no ‘void factordevice::modulabfrage()’ member function declared in class ‘factordevice’
    primefact.cpp:18:33: error: no ‘void factordevice::modullauefer()’ member function declared in class ‘factordevice’
    primefact.cpp: In member function ‘void factordevice::factortool()’:
    primefact.cpp:39:50: error: a function-definition is not allowed here before ‘{’ token
    primefact.cpp:54:1: error: expected ‘}’ at end of input
    soko@soko-HP-Compaq-dx2300-Microtower:~/Arbeitsfläche/Trpl/Trplc++/class1$
    

    Kann mir jemand helfen das Programm so in C++ Klassenstruktur zu implementieren wie es eigentlich sein sollte ...?



  • softpad schrieb:

    Kann mir jemand helfen das Programm so in C++ Klassenstruktur zu implementieren wie es eigentlich sein sollte ...?

    Eigentlich braucht dieses Programm keine Klasse. Dein factordevice hat keinen Zustand, die Member gehören in die einzelnen Funktionen.

    C++ bedeutet nicht, dass man alles zwanghaft in Klassen steckt.

    Ich würde mich hier eher darum kümmern, die Berechnung von der Ein/Ausgabe zu trennen.



  • Ich wollte es nur zu Übungszwecken in die Klassenstruktur übertragen...

    ,aber Ich verstehe ungefähr was du mit Zustand meinst ... Ich glaube die Programmidee/Aufgabe eine Zahl zu faktorisieren hat keinen Zustand. Es gibt ja nur 1 Zahl, die eingegeben werden muss... und der Algorithmus fuehrt seine Aufgabe durch...

    Objetkorientierung in Klassen erzeugt Objekte, die im Programmablauf unterschiedliche Zustände einnehmen ? Am besten/schnellsten kann man sich dies mit Spieleprogrammen veranschaulichen, in denen ja unterschiedliche graphische Objekte ihren Zustand verändern... ?

    Wäre es denn möglich auch dieses Programm in einer Klassestruktur zum laufen zu bringen?



  • softpad schrieb:

    Wäre es denn möglich auch dieses Programm in einer Klassestruktur zum laufen zu bringen?

    1. Wenn man die Formatierung aufräumt, dann sieht man die Flüchtigkeitsfehler gleich viel besser.

    2. Für den Anfang würde ich mit einem leeren Programm anfangen, das nach und nach erweitern und dafür sorgen, das das immer kompiliert und wie geplant funktioniert.

    3. Du musst noch c++11 support aktivieren (-std=c++11)



  • wozu is c++ suport gut ? Ich arbeite im Moment in Linux im Terminal
    g++ primfact.cpp -std ?



  • softpad schrieb:

    Wäre es denn möglich auch dieses Programm in einer Klassestruktur zum laufen zu bringen?

    Ja, mit Gewalt!

    Anfänger bauen Klassen, die man benutzt wie

    cout<<"Die Wurztel aus 25 ist";
    Wurzelberechnung wb;
    wb.setWuadrat(25);
    w.rechne();
    cout<<wb.getWurzel()<<'\n';
    

    statt

    cout<<"Die Wurztel aus 25 ist";
    cout<<sqrt(25)<<'\n';
    

    In Java schreint man wenigstens ein wenig netter

    class Mathematik
    {
       static double sqrt(double);
       …
    };
    //nebst
    [code="cpp"]
    cout<<"Die Wurztel aus 25 ist";
    cout<<Mathematik::sqrt(25)<<'\n';
    

    und freut sich ein Loch in den Bauch, daß sqrt jetzt innerhalb einer Klasse ist und sagt "Java ist eien rein objekt orientierte Sprache".

    Ich hoffe, Du willst nicht sowas machen.

    Gleich schick ich nen Vorschlag für ne passende Übungsklasse. Ich bau sie nur kurz schnell selber, um zu schauen, ob sie Probleme bereitet…



  • softpad schrieb:

    wozu is c++ suport gut ? Ich arbeite im Moment in Linux im Terminal
    g++ primfact.cpp -std ?

    C++ ist 40(?) Jahre alt. Da wurde schon mal das Eine oder das Andere geändert. Teile deines Programms funktionieren nach dem 2011 verabschiedeten Standard. Du musst --std=c++11 angeben, wenn der Compiler diese Sprachversion unterstützen soll.



  • Mein Vorschlag:

    int main() {
    	Primzahlengenerator pg(100);
    	while(!pg.isEmpty()){
    		cout<<pg.peek()<<'\n';
    		pg.pop();
    	}
    }
    

    gibt die 25 Primzahlen zwischen 2 und 100 aus.
    Entsprechend wird

    int main() {
    	Primzahlengenerator pg(10000000);
    	int c=0;
    	while(!pg.isEmpty()){
    		++c;
    		pg.pop();
    	}
    	cout<<c<<'\n';
    }
    

    zur Ausgabe führen

    664579
    
    Process returned 0 (0x0)   execution time : 7.119 s
    Press ENTER to continue.
    

    Ok, der Generator HAT einen Zustand und das ist auch gut so.
    Zur Zeit nur zwei Variablen: n(aktuelle Zahl) und max(die Obergrenze).

    Ich führe noch einen vector<int> primes ein, in dem ich alle Primzahlen, die kleiner als sqrt(n) sind sammle und in der Schleife laufe ich über primes statt über alle Teiler zwischen 2 und sqrt(n).

    664579
    
    Process returned 0 (0x0)   execution time : 3.678 s
    Press ENTER to continue.
    

    Ok, geht ja. Aber der Weg fühlt sich für mich total doof an. Den mag ich nicht.

    Ich will mit dem Trick von q[8]={7,11,13,17,19,23,29,31}; arbeiten.
    [code]
    664579

    Process returned 0 (0x0) execution time : 2.339 s
    Press ENTER to continue.
    [/quote]
    Jo, das geht erstmal. unsiged int statt int führt zu 2.035.

    Wenn ich mehr Speed brauche, bastele ich eine PrimzahlengeneratorNachEratostenes, der wirs richtig fix rennen. Und das beste dran ist, die Schnittstelle ändert sich gar nicht. Hab bei allen Optimierungen die main() nicht mehr anfassen müssen.

    Ok, jetzt weiß ich, was schief lief. Siehste mal, wie gut, daß ichs ausprobiert habe. Es braucht die Klasse Modulläufer! Die kann ich gut in der globalen bool isPrime(unsigned int) und in der class PrimeGenerator benutzen. Aber ebenso in der void factortool(unsigned int). Mein jetziger Code hat die Klasse Primzahlengenerator und ModulLaeufer gemixt, was zu komplizierterem Code führte, als eigentlich notwendig war.

    Viel Spaß!



  • Danke für die Diskussion und Danke an MFK der Beitrag hat mir die Bedeutung dessen wozu eine Klasse da ist klar(er) gemacht...(...Verzweigung, Funktion , main(Funktion) , Klasse , u.s.w.) Ich werde mich hinsetzten und versuchen mal die Vorschläge umzusetzen ....


Anmelden zum Antworten