C-Programm – Primzahlen & Makefiles

closeDieser Beitrag wurde vor mehr als drei Monaten veröffentlicht. Bedenke bitte, dass die hier angebotene Information nicht mehr aktuell und gültig sein könnte. Informiere dich daher bitte auch an anderer Stelle über dieses Thema. Sollten sich neue Informationen ergeben haben, so kannst du mich auch gerne auf diese über einen Kommentar hinweisen. Vielen Dank!

Das folgende Programm gibt alle Primzahlen von 1 bis 100 aus, dabei wurde die Berechnung in eine eigene Funktion ausgelager.

/*
primzahlen.c
*/

#include <stdio.h>
#include <math.h>

/*
gcc -Wall -lm primzahlen.c -o primzahlen -O3
*/

int ist_primzahl(int zahl) {
    int teiler=2;

    /* solange der 'teiler' kleiner/gleich der (²)Wurzel aus 'zahl' ist ...
    ...  denn Primzahlen haben -keinen- Teiler der kleienr als dessen Quadratwurzel ist */
    while (teiler <= sqrt(zahl)) {
    /* alternativ, dann ohne <math.h> */
    /* while (teiler*teiler <= zahl) { */
        /* wenn kein Rest, dann... */
        if (zahl % teiler == 0) {
            /* ... 'false' */
            return(0);  /* 'zahl' ist keine Primzahl */
        }
        /* teiler und einen erhoehen */
        teiler++;
    }
    /* ... ansonsten 'true' */
    return(1);          /* 'zahl' ist eine Primzahl */
}

int main() {
    int zahl;

    /* solange bis 1 nicht mehr kleiner/gleich 100 bis, 1 erhoehen */
    for (zahl=1; zahl<=100; zahl++) {
        /* wenn Funktion='true' dann ...*/
        if (ist_primzahl(zahl)) {
            /* ... Zahl ausgebn */
            printf("%d\n", zahl);
        }
    }
    return(0);
}


Bei großen Projekten kann es hilfreich sein, diese Funktionen in verschiedenen Dateien zu organisieren und später wieder zusammen zu fügen…

1.) Den Quellcode in einen beliebigen ASCII-Texteditor eintippen und abspeichern.

2.) Den Quellcode mit einem Compiler übersetzen, wodurch eine Objektdatei (*.pbj oder *.o) erzeugt wird.

3.) Die Objektdatei mit einem Linker binden, so dass eine ausführbare Datei erzeugt wird. Der Linker sucht außerdem alle benötigten Funktionen aus den Standard-Bibliotheken heraus und fügt diese anschließend dem fertigen Programm hinzu.


zu 2.)

gcc -c primz_haupt.c
gcc -c primz_math.c

zu 3.)

gcc primz_haupt.o primz_math.o -lm -O3 -Wall -o primzahl


/*
primz_haupt.c
*/

#include <stdio.h>
#include "primz_math.h"

int main() {
        int zahl;

        for(zahl=1; zahl<=100; zahl++) {
                if (ist_primzahl(zahl)) {
                        printf("%d\n", zahl);
                }
        }
        return(0);
}
/*
primz_math.c
*/

#include <math.h>

int ist_primzahl(int zahl) {
        int teiler=2;

        while(teiler <= sqrt(zahl)) {
                if(zahl % teiler == 0) {
                        return(0);
                }
                teiler++;
        }
        return(1);
}


Um die zuvor beschriebene Prozedur zu beschleunigen, gibt es die sogenannten Makefiles, welche alle Informationen zum kompilieren enthalten und den Prozess somit automatisch durchführen können.

Als erstes ein ausführliches Beispiel:

# Makefile
#

#4.) 'primz_haupt.o' + 'primz_math.o' zusammenfuehren
primzahl:       primz_haupt.o primz_math.o
                gcc primz_haupt.o primz_math.o -lm -o primzahl

#3.) 'primz_haupt.o' erzeugen + 'primz_math.h' einfuegen
# Info: 'primz_math.h' ist die Verknuepfung zu 'primz_math.c'
primz_haupt.o:  primz_haupt.c primz_math.h
                gcc -c primz_haupt.c

#2.) 'primz_math.o' erzeugen
primz_math.o:   primz_haupt.c
                gcc -c primz_math.c

#1.) aufraeumen
clean: 
                rm -f primz_haupt.o prinz_math.o

Und hier die komprimierte Version: :-)

# Makefile2
#

TARGET  = primzahl
OBJECTS = primz_haupt.o primz_math.o
HEADERS = primz_math.h
LIBS    = -lm

$(TARGET):      $(OBJECTS)
                gcc $^ $(LIBS) -o $@

primz_%.o:      primz_%.c $(HEADERS)
                gcc -c $&lt; -o $@

clean: 
                rm -f $(OBJECTS)
  • Faby

    Hallo,

    ich danke für diesen Beitrag. Das Programm scheint jedoch nicht zu funktionieren, sobald eine Zahl <=3 eingegeben wird. Damit ist die Bedingung der For-Schleife nicht erfüllt – sie wird übersprungen wegen teiler(2) <= zahl.

  • Faby

    *Update

    Kleiner Fehler, ist eine While-Schleife – keine For-Schleife.
    Damit besteht das Problem jedoch noch immer.