C Programm verstehen lernen

  • Ersteller Ersteller Slix1995
  • Erstellt am Erstellt am
Status
Für weitere Antworten geschlossen.
S

Slix1995

Gast
Hallo zusammen,
Ich habe ein kleines Programm zur Primfaktorzerlegung , dieses zerlegt eine beliebige Zahl in die möglichst kleinsten teiler(Primfaktoren) und möchte dies bzw. den Programmablauf besser verstehen, da wollte ich mal Fragen ob mir einer den Quellcode vielleicht etwas erklären könnte.
Der Code ist unten mit dabei würde mich über ein paar Antworten freuen!

Mit freundlichen Grüßen
Ein kleiner Programmieranfänger
C:
#include <stdio.h>           
#include <math.h>          
#include <time.h>          
unsigned long long kTeiler(unsigned long long n);              
unsigned long long leseULongLong(char *string);
void prim(unsigned long long n);

int main(void)
{
    unsigned long long n;
    clock_t start, end;

    start = clock();

    while (n>0)
    {
        n = leseULongLong("Geben Sie eine natuerliche Zahl ein");
        printf("Eingegeben wurde: %I64u \n", n);

        if (n>1)
        {
            prim(n);
        }
        else if (n==1)
        {
            printf("1 = 1\n");
        }
        else
        {
            printf("Eingegebene Zahl kleiner 0: PROGRAMM-ENDE \n\n");
            break;
        }
    }
    end = clock();
    printf("TIME: %.2f s\n", (double) (end - start) / CLOCKS_PER_SEC);
    return 0;
}

void prim(unsigned long long n)
{
    unsigned long long m;

    m = kTeiler(n);
    printf("%I64u = %I64u", n, m);
    n = n/m;
    while(n != 1)
    {
        m = kTeiler(n);
        printf(" * %I64u", m);
        n = n/m;
    }
    printf("\n");
}

unsigned long long kTeiler(unsigned long long n)
{
    unsigned long long max, k;
    if (n<4)
    {
        return n;
    }
    if (n%2 == 0)
    {
        return 2;
    }
    if (n%3 == 0)
    {
        return 3;
    }
    if (n%5 == 0)
    {
        return 5;
    }

    k=7;
    max=sqrt(n)+1;
    while(n%k != 0)
    {
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+6;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+6;
        if(k > max)
        {
            k = n;
        }
    }
    return k;
}

int flushStdin(void)
{
    int c;

    do
    {
        c = getchar();
        //printf(":%d:\n",c);  // Debug-Ausgabe
    }
    while(c != '\n' && c != EOF);

    return c;
}




unsigned long long leseULongLong(char *string)
{
    unsigned long long ein = 0;

    printf("Eingabe >> %s: ", string);
    while(scanf("%I64u",&ein) != 1)
    {
        if(flushStdin() != EOF)
        {
            printf("Erneute Eingabe >> %s: ", string);
        }
        else
        {
            printf(stderr, " Falscher Eingabewert!\n");
            break;
        }
    }
    return ein;
}
 
Hmm. Ist eine menge code - mach doch mal über jede Zeile einem kommentar in dem du erklärst was sie deiner meinung nach tut - Wo du es nicht verstehst schreib dran was du glaubst / bzw schreib das du es nicht verstehst
Bei repetativen dingen ruhig für den ganzen block :) bei ifs musst du nicht jede bedingung kommentieren, ausser du weist nicht was sie tut :D
 
  • Gefällt mir
Reaktionen: T3mp3sT1187, GTrash81 und BeBur
Und beschreibe mal mit "Pseudo-Code" den groben Ablauf. Die Lücken füllen wir dann schon.
Ist schließlich eine "Hausaufgabe" für dich von der Uni oder nicht?

Edit: Vermute ich das richtig, dass die Aufgabe darin bestand, genau dieses Programm zu schreiben, du hast es aber von irgend woher kopiert aber musst es auch erklären können und um genau das zu tun fragst du uns jetzt hier? Dann solltest du stattdessen einfach selber programmieren anstatt uns hier zu fragen dir beim Abschreiben zu helfen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Zerstoerer, GTrash81 und abcddcba
BeBur schrieb:
Und beschreibe mal mit "Pseudo-Code" den groben Ablauf.
ganz genau - das ganze auf nem Stueck Papier reicht eigentlich schon um den Code zu verstehen.

Die Methoden-Namen sind auch selbst-erklaerend. Zudem ist das Ganze auch noch prozedural, also muss man sich nicht mal um Objekte kuemmern.
Einfach mal Zettel und Stift, das reicht. Schadet auch nicht zu verstehen, wie man das ganze mathematisch macht. Nichts anderes ist naemlich hier quasi 1:1 in Code ungeschrieben
 
  • Gefällt mir
Reaktionen: Slix1995
madmax2010 schrieb:
Hmm. Ist eine menge code - mach doch mal über jede Zeile einem kommentar in dem du erklärst was sie deiner meinung nach tut - Wo du es nicht verstehst schreib dran was du glaubst / bzw schreib das du es nicht verstehst
Bei repetativen dingen ruhig für den ganzen block :) bei ifs musst du nicht jede bedingung kommentieren, ausser du weist nicht was sie tut :D

Code:
#include <stdio.h>           //Header Datei stdio.h
#include <math.h>          //Header Datei math.h
#include <time.h>          //Header Datei time.h für (end - start) / CLOCKS_PER_SEC
unsigned long long kTeiler(unsigned long long n);  // long long kTeiler          
unsigned long long leseULongLong(char *string);
void prim(unsigned long long n);

int main(void)                                                  // Start -Hauptprogramm
{
    unsigned long long n;
    clock_t start, end;

    start = clock();                                           // Start - Laufzeitmessung

    while (n>0)                                               // While schleife Bedingung : wenn n größer 0
    {
        n = leseULongLong("Geben Sie eine natuerliche Zahl ein");                       // Eingabe Aufforderung
        printf("Eingegeben wurde: %I64u \n", n);                                            // %I64u wegen unsigned long long
                                                                                                                    // unsigned long long anstatt long long
                                                                                                                    // da schneller
        if (n>1)                                                                                                //wenn n größer 1 start prim(n)
        {
            prim(n);
        }
        else if (n==1)                                                                                   //wenn n = 1 print 1 = 1/n
        {
            printf("1 = 1\n");
        }
        else                                                                                                 // dann Programm Ende da Zahl kleiner 1
        {
            printf("Eingegebene Zahl kleiner 0: PROGRAMM-ENDE \n\n");
            break;
        }
    }
    end = clock();                                                                                          // Zeitmessung Ende
    printf("TIME: %.2f s\n", (double) (end - start) / CLOCKS_PER_SEC);       // Ausgabe Zeitmessung
    return 0;                                                                                                 //Zurück auf start
}

void prim(unsigned long long n)                                                         // Programmteil prim falls n größer 1
{
    unsigned long long m;                                  // Variable m dem Datentyp unsigned long long zuordnen

    m = kTeiler(n);                                              // m = kleinster teiler von n?
    printf("%I64u = %I64u", n, m);
    n = n/m;                                                                
    while(n != 1)
    {
        m = kTeiler(n);
        printf(" * %I64u", m);
        n = n/m;
    }
    printf("\n");
}

unsigned long long kTeiler(unsigned long long n)                                 //Funktion für suche der kleinsten Teiler
{
    unsigned long long max, k;                                                                // ?        
    if (n<4)                                                                                                // Wenn n größer 4
    {
        return n;
    }
    if (n%2 == 0)
    {
        return 2;
    }
    if (n%3 == 0)
    {
        return 3;
    }
    if (n%5 == 0)
    {
        return 5;
    }

    k=7;
    max=sqrt(n)+1;               //Optimierung ?
    while(n%k != 0)
    {
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+4;
        if (n%k==0)
        {
            break;
        }
        k=k+6;
        if (n%k==0)
        {
            break;
        }
        k=k+2;
        if (n%k==0)
        {
            break;
        }
        k=k+6;
        if(k > max)
        {
            k = n;
        }
    }
    return k;
}

int flushStdin(void)                                      // Funktion flushStdin : Alle im Eigabepuffer vorhandenen Zeichen  
{                                                                       werden zum nächsten Zeilenumbruch oder Datei ende eingelesen
    int c;

    do
    {
        c = getchar();
        //printf(":%d:\n",c);  // Debug-Ausgabe
    }
    while(c != '\n' && c != EOF);

    return c;
}




unsigned long long leseULongLong(char *string)
{
    unsigned long long ein = 0;

    printf("Eingabe >> %s: ", string);
    while(scanf("%I64u",&ein) != 1)
    {
        if(flushStdin() != EOF)      // Wenn Funktion flushStdin ungleich "End of File"  Dateiende ,print Falscher                                                               Eingabe wert und Erneute Eingabe
        {
            printf("Erneute Eingabe >> %s: ", string);
        }
        else
        {
            printf(stderr, " Falscher Eingabewert!\n");
            break;
        }
    }
    return ein;
}
 
Verstehe ich gerade die Welt nicht mehr oder hat das Programm wirklich einen Randomizer eingebaut, so dass es mit einer sehr kleinen Chance nicht wirklich läuft und die Eingabe übersprungen wird?

Oder wird n in der main() irgendwie auf magische Weise initialisiert, so dass es nicht 0 sein kann wenn die Schleife läuft?
 
Sollst du das nicht selber programmieren in Aufgabe 3?
22222.png


KingLz schrieb:
Verstehe ich gerade die Welt nicht mehr oder hat das Programm wirklich einen Randomizer eingebaut, so dass es mit einer sehr kleinen Chance nicht wirklich läuft und die Eingabe übersprungen wird?
Wird einfach von einem anderen Studenten kopiert worden sein, der selber auch nicht so richtig gut ist oder es von woanders kopiert hatte.
Ergänzung ()

Wobei es sieht auch so aus als wenn jemand, der nicht programmieren kann versucht hat zu verschleiern, dass er ein Programm einfach nur kopiert hat.
Ergänzung ()

PS.: Jetzt hat der TE schiss bekommen. Zu recht :D.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Zerstoerer, mental.dIseASe, Hayda Ministral und 3 andere
Status
Für weitere Antworten geschlossen.
Zurück
Oben