Anzahl der Primzahlen,Zufallswerte

joner

Grünschnabel
Hallo erstmal,

Ich studiere Et und im ersten Semester haben wir Programmierungstechnik, zur weinachsferien haben wir eine Hausaufgabe bekommen, und da komm ich leider nicht weiter, obwohl ich mich seit tagen damit beschäftige, ich hoffe, ihr könnt mir helfen.





Und hier meine Quellcode, ist bisschen durcheinander, da ich noch beim experimentieren bin, Das Grösste problem ist es, dass ich nicht wirklich weiss, wie ich die erste funktion in die zweite integrieren soll.


C++:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int isPrime(int eingabe)
{
	int zahl,i,y=0;

	for(i=2;i<zahl/2 && !y;i++)	
	{
		if(zahl%i == 0)	
		{
			printf("\n Wert 0 = Keine Primzahl \n",i);
			y=1;


}
 
Zuletzt bearbeitet:
Hi und Willkommen bei tutorials.de,

zuerst mal zu isPrime:
schaut zwar prinzipiell richtig aus, aber:
Das Ergebnis 0 oder 1 soll ja im Programm weiterverwendet werden.
Du gibst es zwar aus, aber damit weißt nur du, ob es eine Primzahl war.

Damit man dann irgendwann schreiben kann
C++:
int i = isPrime(456);
//i ist jetzt 0 oder 1
muss die Funktion einen Wert zurückgeben, mit return.
Ca. da, wo zurzeit die printf sind.
Und da ein return die Funktion auch beendet brauchst du die Sache mit y nicht mehr.

Noch was: Du überprüfst ja gar nicht eingabe auf das Prim-sein, sondern zahl.
zahl hat nie irgendeinen Wert bekommen -> Sinnlos
C++:
int isPrime(int eingabe)
{
    int i;

    for(i = 2; i < (eingabe/2); i++) 
    {
        if((eingabe % i) == 0) 
            return 0;
    }

    return 1;
}

Dann, zum Konzeptuellen vom restlichen Programm:
In der Angabe steht dauernd "Liste". Du verwendest aber überall Arrays.
Bist du dir sicher, dass es nicht doch eine (einfach/doppelt verkettete) Liste sein soll?
Sowas, wo jeder Wert einen next-Pointer hat usw.?
 
Hallo und herzlich Willkommen im Forum ;)

Erstmal gehe ich davon aus, dass du in C programmierst.

Zunächst würde ich die Funktion isPrime() überarbeiten. Die besitzt überhaupt kein return-Statement.
Außerdem wird die for-Schleife immer sofort abgebrochen, da !y (für y=0) immer zu false evaluiert.
Brich doch lieber gleich die Funktion via return ab.

Noch dazu, was soll die Variable zahl darstellen? Du hast doch schon eingabe.
Sorry, wenn ich das jetzt so sage, aber diese Fkt. sieht mir ganz nach Copy & Paste aus ;)
C++:
int isPrime(int number) {
  int i;
  // Hälfte zwischenspeichern, damit
  // sie nicht bei jedem for-Durchlauf neu berechnet
  // werden muss
  int half = number/2;
  for (i=2; i<half; i++) {
    if (number % i == 0) {
      return 0;
    }
  }
  return 1;
}


Zur main()-Funktion:

Du musst die Liste mit n Einträgen erstellen, wobei n die Eingabe des Nutzers ist:
C++:
// BITTE gib deinen Variablen 
// besseren Namen so wie dieser hier:
int listLength;
int randomRange;

printf("\nLänge der Liste mit Zufallswerten: ");
scanf("%d", &listLength);
printf("Intervallgrenze K (maximal moeglicher Zufallswert): ");
scanf("%d",&randomRange);

int list[listLength];
Nun musst du noch in einer for-Schleife die Zufallswerte erzeugen.
Das solltest du hinbekommen.
Zufallszahlen kannst du (mehr oder weniger gut) so erzeugen:
C++:
// copied from http://www.cplusplus.com/reference/cstdlib/rand/

v1 = rand() % 100;         // v1 in the range 0 to 99
v2 = rand() % 100 + 1;     // v2 in the range 1 to 100
v3 = rand() % 30 + 1985;   // v3 in the range 1985-2014

Danach übergibst du das Array ("list") und dessen Länge (listLength) an numPrimes().

numPrimes()
Füge eine for-Schleife ein, welche über alle Einträge des Array iteriert und jeweils isPrime() aufruft.

@sheel:
sheel hat gesagt.:
Dann, zum Konzeptuellen vom restlichen Programm:
In der Angabe steht dauernd "Liste". Du verwendest aber überall Arrays.
Bist du dir sicher, dass es nicht doch eine (einfach/doppelt verkettete) Liste sein soll?
Sowas, wo jeder Wert einen next-Pointer hat usw.?
Das dachte ich mir auch zuerst, allerdings steht bei der Angabe, dass numPrimes() auch die Länge der Liste übergeben werden soll.
Das ist allerdings bei richtigen einfach oder doppelt verketteten Liste nicht erforderlich.
 
Zuletzt bearbeitet:
Danke für die Antworten,

@ Comfreak
Copy & Paste, hast mich erwischt xD

ich habe versucht zufallswerte zwischen 0 bis k zu erzeugen und es funktioniert
 
Zuletzt bearbeitet:
Schön, dass du main() erstmal alleine hinbekommen hast.
Ich würde dir allerdings raten, Code-Blöcke (mit if, for, while, ...) immer in geschweifte Klammern zu setzen.
Sonst kann es ganz leicht zu anderen Logik-Fehlern kommen.

Außerdem kannst du damit mehr als ein Befehl reinschreiben, sodass du z.B. hier die Zufallswerte gleich ausgeben kannst:
C++:
// Übrigens haben kleinere Zahlen bei rand() % k eine höhere
// Wahrscheinlichkeit, sollte aber für deine Zwecke reichen.

for (i=0; i<listLength; i++) {
  list[i] = rand() % k;
  printf("list[%d]=%d\n", i, list[i]);
}

Zu numPrimes()
Du musst die Länge des Array auch als Parameter der Funktion angeben, also int numPrimes(int list[], int listLength);.
Das liegt daran, dass eine Array-Variable an sich nichts anderes ist als ein Pointer, also ein Zeiger auf irgendeine Speicherstelle im Arbeitsspeicher.
list zeigt also nur auf eine Stelle im Arbeitsspeicher, an der das erste int des Arrays gespeichert ist.

Um nun festzustellen, wann das Ende des Arrays erreicht worden ist, braucht man immer eine Länge oder ein "Schlusszeichen" (z.B. \0 bei char*, falls du diese schon kennst).

Außerdem bin ich mir gerade nicht sicher, ob du wirklich weißt, dass Variablennamen zweimal in anderen Codeblöcken (Funktionen) vorkommen dürfen und völlig unabhängig voneinander sind.
Das heißt, dass listLength innerhalb numPrimes() (so wie du es jetzt hast) mit 0 initialisiert ist. Es ist einfach eine neue Variable für den Compiler.

Zusätzlich brauchst du auch noch eine Zählvariable, die einfach die Anzahl der Primzahlen speichert.
Und wenn isPrime() 1 zurückgibt, inkrementierst (um 1 hochzählen) diese Variable.

So müsste es richtig lauten:
C++:
int numPrimes(int list[], int listLength) {
  int i, numberOfPrimes = 0;

  // NICHT list[listLength], das wäre
  // a) nicht mehr im Array, da list[listLength - 1] das letzte Element ist,
  // b) willst du ja die Länge haben und nicht den letzten Zufallswert (sofern du a) schreiben würdest)
  for (i=0; i<listLength; i++) {
    if ( isPrime(list[i]) ) {
      numberOfPrimes++;
      // auch möglich: numberOfPrimes += 1 oder numberOfPrimes = numberOfPrimes + 1
    }
  }
  return numberOfPrimes;
}

PS: Ich muss dich loben, dass du selbst die [ code=cpp ]-Tags gefunden hast ! Achte aber bitte auf Groß- und Kleinschreibung, dies erleichtert das Lesen ;)
 
PS: Ich muss dich loben, dass du selbst die code-Tags gefunden hast ! Achte aber bitte auf Groß- und Kleinschreibung, dies erleichtert das Lesen ;)

Danke, es liegt daran, dass ich seit langem hier reingucke, wenn ich Hilfe brauche =)

- Noch mal ne ganz kleine frage, Ich hoffe, dass ich dich nicht nerve =), wenn ich in meiner Main-funktion die Anzahl der Primzahlen(numPrimes) ausgeben möchte, funktioniert das wie bei normalen Variablen?
Also;
C++:
printf("Anzahl der Primzahlen: %d",numPrimes)

weil ich ja möchte, dass meine Funktion numPrimes die Anzahl der Primzahlen in meiner Main-funktion ausgibt.
 
Nein, so kann das leider nicht funktionieren.

Zuerst willst du nicht die Funktion an sich, sondern ihren Rückgabewert, sprich den Wert von numPrimes() (mit Klammern!). Nun wird die Funktion auch wirklich aufgerufen, das andere wäre nur eine Referenz auf die Funktion, mehr nicht.

Allerdings fordert numPrimes() auch zwei Parameter: int list[] und int listLength
Beide hast du in deiner main() bereits deklariert, initialisiert und gefüllt, sie haben sogar den gleichen Variablennamen.

So müsste es lauten:
C++:
printf("Anzahl der Primzahlen: %d", numPrimes(list, listLength));

// oder so mit einem Zwischenschritt
int nrOfPrimes = numPrimes(list, listLength);
printf("Anzahl der Primzahlen: %d", nrOfPrimes);
 
Danke für deine Hilfe, es hat mir echt geholfen.

Eine letzte Frage habe ich noch =) , nämlich, Reservierung von Speicherplatz(Heap) . Ich weiss, dass ich dafür malloc-funktion brauche und dann wieder freigeben muss
 
Zuletzt bearbeitet:
Du brauchst dich bei deinem Code nicht selber um Speicherreservierung kümmern, denn du nutzt momentan Variable-Length-Arrays (VLA), um Arrays mit dynamischer Größe zu erstellen.
Die Größe/Länge ist ja nicht zur Compilezeit festgelegt, sonder erst wenn das Programm läuft und der Nutzer sie eingibt.

Wenn du es mit malloc() machen willst, musst du es so schreiben:
C++:
printf("\nLaenge der Liste mit Zufallswerten: ");
scanf("%d", &laenge);
printf("Intervallgrenze K (maximal moeglicher Zufallswert): ");
scanf("%d",&Grenze);

int *list = (int*) malloc(sizeof(int) * laenge);
if (!list) {
  printf("Allocation of %d bytes failed!", (sizeof(int) * laenge));
}
else {
  numPrimes(list, laenge);
  // Freigeben und sicherheitshalber auf 0 setzen
  free(list);
  list = NULL; 
}
Du kannst hier nicht die Variable k nutzen, denn du hast sie davor ja gar nicht benutzt. Und wenn schon müsste k die gewünschte Länge des Arrays sein, denn sonst würde es logisch gesehen keinen Sinn ergeben.
 
Zuletzt bearbeitet:
Danke für eure Hilfsbereitschaft, und so ist dieses Thema abgehackt, nochmal danke




aber es hat nicht geklappt, hab die ganze Zeit Fehler meldung bekommen "in Konflikt stehende Typen für >>list<<" usw. Dann habe ich mir gedacht na gut, jetzt versuche ich mit eine Variable "p" und ausserdem habe ich paar Modifikationen gemacht , ich kriege zwar keine Fehlermeldung aber ich weiss es auch nicht, ob es richtig ist, Auf jeden Fall stürzt das Programm nicht ab
 
Zuletzt bearbeitet:
Zurück