none
Frage zum Code eines Primzahlengenerators

    Frage

  • Hallo,
    ich hätte ein kleine Frage zu dem Code eines Primzahlengenerators. Um folgenden Code handelt es sich:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace PrimzahlenGenerator
    {
        public partial class FDlgPrimaryNumberGen : Form
        {
            public FDlgPrimaryNumberGen()
            {
                InitializeComponent();
            }
    
            private bool isPrimaryNumber( int number ) // int Number in dieser Zeile verstehe ich nicht. Auch was im weiteren mit dieser Variable geschieht verstehe ich nicht.
            {
                int i;
                bool isPN;
    
                isPN = true;
                for( i=2; i<number/2; i++ )
                {
                    if ( number%i == 0 )
                    {
                        isPN = false;
                        break;
                    }
                }
                return isPN;
            }
    
            private void bGenerate_Click(object sender, EventArgs e)
            {
                int i, start, end;
    
                start = int.Parse(tbStart.Text);
                end = int.Parse(tbEnd.Text);
                rtbOut.Clear();
                Application.DoEvents();
                rtbOut.AppendText("Primzahlen im Intervall["  + start.ToString() + "," + end.ToString() + "]\n");
                for( i=start; i<=end; i++ )
                {
                    if (isPrimaryNumber(i))
                        rtbOut.AppendText(i.ToString() + "\n");
                }
            }
    
            private void FDlgPrimaryNumberGen_Load(object sender, EventArgs e)
            {
    
            }
    
            private void rtbOut_TextChanged(object sender, EventArgs e)
            {
                    
            }
        }
    }

    Soweit verstehe ich den Code auch ganz gut. Nur in der oberen Zeile wird plötzlich der Intenger "number" verwendet. Ihm wird soweit ich das verstehe auch kein Wert zugefügt. Ich verstehe nicht ganz was mit dieser Variable passiert, bzw. mit welchen Werten sie gefüllt wird. Und wieso wird das int number in die erste Zeile und nicht in den Codeblock geschrieben?

    Ich hoffe mir kann dies jemand erklären. Vielen Dank für jede Antwort im voraus :)



    • Bearbeitet Berger1012 Sonntag, 21. April 2019 19:44
    Sonntag, 21. April 2019 19:43

Antworten

  • Hallo,

    // int number in dieser Zeile verstehe ich nicht. 
    // Auch was im Weiteren mit dieser Variable geschieht,  
    // verstehe ich nicht.
    private bool isPrimaryNumber( int number ) 
    {
      // Code zur Prüfung, ob eine Primzahl vorliegt
    }

    Das ist eine sogenannte "Methode" mit dem Namen isPrimaryNumber, der als Parameter ein Integer mit der Bezeichnung "number" übergeben wird.

    In der Methode soll geprüft werden, ob number eine Primzahl ist. Falls das so ist, soll der logische (-> bool) Wert "wahr" zurückgegeben werden, anderenfalls "false".

    Der Wert wird in der aufrufenden Methode (hier: bGenerate_Click(...)) übergeben.

    Nebenbei arbeitet die Prüfmethode (isPrimaryNumber(...)) im konkreten Fall nicht immer korrekt.

    Falls du gerade erst anfängst mit dem Programmieren, findest du hier möglicherweise interessante (Lern-Videos).

    Gruß

    Sonntag, 21. April 2019 23:13
  • Hi,
    ergänzend zu den anderen Antworten:

    Eine Methode kapselt eine Funktionalität, in Deinem Fall soll isPrimaryNumber einen übergebenen Wert prüfen und dann ein Ja/Nein (True/False) zurückgeben. Einer Methode können Werte im Aufruf übergeben werden, indem im Methodenkopf eine Liste sog. formaler Parameter deklariert wird, was auch als Signatur einer Methode bezeichnet wird. In Deinem Fall erwartet die Methode isPrimaryNumber beim Aufruf eine ganze Zahl (int). Diese ganze Zahl wird bei "... if (isPrimaryNumber(i)) …" aus dem Wert der Variablen "i" übergeben. Beim Aufruf der Methode isPrimaryNumber wird in Deinem Fall der reale Wert aus der Variablen "i" dem formalen Parameter "number" zugewiesen. Dieser formale Parameter "number" kann dann in der Methode isPrimaryNumber wie eine lokale Variable genutzt werden. Mit diesem Mechanismus ist eine Methode an unterschiedlichen Stellen einsetzbar, wobei beim Aufruf der Methode jeweils Werte anderer Variablen der Methode übergeben werden können. Die Methode nutzt dabei immer nur den formalen Parameter. Damit die an die Methode beim Aufruf übergebenen Bytes auch richtig durch die Methode interpretiert werden, prüft die Laufzeitumgebung, ob die Typen passen. 

    Hier mal eine Konsolen Demo:

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp1
    {
      class Program68
      {
        static void Main(string[] args)
        {
          try
          {
    
            Demo c = new Demo();
            //
            // Alle Primzahlen ausgeben mit dem Sieb des Eratosthenes
            Console.WriteLine("--- Sieb des Eratosthenes");
            foreach (int prime in c.Primzahlen1(100)) Console.WriteLine(prime);
            //
            // Alle Primzahlen ausgeben
            Console.WriteLine("--- brute-force");
            foreach (int prime in c.Primzahlen2(100)) Console.WriteLine(prime);
          }
          catch (Exception ex) { Console.WriteLine(ex.ToString()); }
          Console.WriteLine("Fertig, Abschluss mit beliebiger Taste");
          Console.ReadKey();
        }
    
        class Demo
        {
          /// <summary>
          /// Primzahlen mit dem Sieb des Eratosthenes ermitteln
          /// </summary>
          /// <param name="max">Maximalzahl, bis zu der zu ermitteln ist</param>
          /// <returns>Liste der bis Max ermittelen Primzahlen</returns>
          internal List<int> Primzahlen1(int max)
          {
            bool[] prime = new bool[max+1];
            /// Zuerst alle Zahlen von 2 bis n als Primzahl markieren
            for (int i = 2; i <= max; i++) prime[i] = true;
            /// Alle Produkte des Teilers i, angefangen bei 2, bis kleiner n durchlaufen
            /// Wenn n = 50, dann ist bei i = 7 Schluss, weil das Produkt = 49 ist
            for (int i = 2; i <= Math.Sqrt(max) - 1; i++)
              /// Wenn die Zahl im Array als Primzahl markiert ist
              /// Das ist bei den ersten beiden (2 und 3) definitiv der Fall
              if (prime[i])
                /// Alle weiteren Produkte des Teilers i
                /// angefangen beim Produkt i * i bis kleiner n durchlaufen
                /// j wird mit i beim nächsten Durchlauf (Vielfaches) addiert
                for (int j = i * i; j <= max; j += i) prime[j] = false;
            /// Alle Primzahlen ausgeben
            List<int> folge = new List<int>();
            for (int i = 1; i <= max; i++) if (prime[i]) folge.Add(i);
            return folge;
          }
    
          /// <summary>
          /// Primzahlen mit brute-force-Version ermitteln (ohne Array)
          /// </summary>
          /// <param name="max">Maximalzahl, bis zu der zu ermitteln ist</param>
          /// <returns>Liste der bis Max ermittelen Primzahlen</returns>
          internal List<int> Primzahlen2(int max)
          {
            /// Ergebnisliste vorbereiten
            List<int> folge = new List<int>();
            /// alle Zahlen ab 2 bis Maximalzahl überprüfen
            for (int i = 2; i <= max; i++)
            {
              /// erst einmal die zu prüfende Zahl bis auf Widerruf als Primzahl setzen
              bool primzahl = true;
              /// bis zur Wurzel aus der zu prüfenden Zahl alle Möglichkeiten prüfen
              for (int j = 2; j <= Math.Sqrt(i); j++)
              {
                /// prüfen, ob sich die zu prüfende Zahl ohne Rest teilen lässt 
                if (i % j == 0)
                {
                  /// wenn Rest = 0 dann Prüfung beenden, da keine Primzahl
                  primzahl = false;
                  break;
                }
              }
              /// Wenn kein Abbruch der Prüfung war, dann wurde Primzahl gefunden
              if (primzahl) folge.Add(i);
            }
            /// Ergebnisliste zurückgeben
            return folge;
          }
        }
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Montag, 22. April 2019 07:42

Alle Antworten

  • Hallo,

    // int number in dieser Zeile verstehe ich nicht. 
    // Auch was im Weiteren mit dieser Variable geschieht,  
    // verstehe ich nicht.
    private bool isPrimaryNumber( int number ) 
    {
      // Code zur Prüfung, ob eine Primzahl vorliegt
    }

    Das ist eine sogenannte "Methode" mit dem Namen isPrimaryNumber, der als Parameter ein Integer mit der Bezeichnung "number" übergeben wird.

    In der Methode soll geprüft werden, ob number eine Primzahl ist. Falls das so ist, soll der logische (-> bool) Wert "wahr" zurückgegeben werden, anderenfalls "false".

    Der Wert wird in der aufrufenden Methode (hier: bGenerate_Click(...)) übergeben.

    Nebenbei arbeitet die Prüfmethode (isPrimaryNumber(...)) im konkreten Fall nicht immer korrekt.

    Falls du gerade erst anfängst mit dem Programmieren, findest du hier möglicherweise interessante (Lern-Videos).

    Gruß

    Sonntag, 21. April 2019 23:13
  • Hi,
    ergänzend zu den anderen Antworten:

    Eine Methode kapselt eine Funktionalität, in Deinem Fall soll isPrimaryNumber einen übergebenen Wert prüfen und dann ein Ja/Nein (True/False) zurückgeben. Einer Methode können Werte im Aufruf übergeben werden, indem im Methodenkopf eine Liste sog. formaler Parameter deklariert wird, was auch als Signatur einer Methode bezeichnet wird. In Deinem Fall erwartet die Methode isPrimaryNumber beim Aufruf eine ganze Zahl (int). Diese ganze Zahl wird bei "... if (isPrimaryNumber(i)) …" aus dem Wert der Variablen "i" übergeben. Beim Aufruf der Methode isPrimaryNumber wird in Deinem Fall der reale Wert aus der Variablen "i" dem formalen Parameter "number" zugewiesen. Dieser formale Parameter "number" kann dann in der Methode isPrimaryNumber wie eine lokale Variable genutzt werden. Mit diesem Mechanismus ist eine Methode an unterschiedlichen Stellen einsetzbar, wobei beim Aufruf der Methode jeweils Werte anderer Variablen der Methode übergeben werden können. Die Methode nutzt dabei immer nur den formalen Parameter. Damit die an die Methode beim Aufruf übergebenen Bytes auch richtig durch die Methode interpretiert werden, prüft die Laufzeitumgebung, ob die Typen passen. 

    Hier mal eine Konsolen Demo:

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp1
    {
      class Program68
      {
        static void Main(string[] args)
        {
          try
          {
    
            Demo c = new Demo();
            //
            // Alle Primzahlen ausgeben mit dem Sieb des Eratosthenes
            Console.WriteLine("--- Sieb des Eratosthenes");
            foreach (int prime in c.Primzahlen1(100)) Console.WriteLine(prime);
            //
            // Alle Primzahlen ausgeben
            Console.WriteLine("--- brute-force");
            foreach (int prime in c.Primzahlen2(100)) Console.WriteLine(prime);
          }
          catch (Exception ex) { Console.WriteLine(ex.ToString()); }
          Console.WriteLine("Fertig, Abschluss mit beliebiger Taste");
          Console.ReadKey();
        }
    
        class Demo
        {
          /// <summary>
          /// Primzahlen mit dem Sieb des Eratosthenes ermitteln
          /// </summary>
          /// <param name="max">Maximalzahl, bis zu der zu ermitteln ist</param>
          /// <returns>Liste der bis Max ermittelen Primzahlen</returns>
          internal List<int> Primzahlen1(int max)
          {
            bool[] prime = new bool[max+1];
            /// Zuerst alle Zahlen von 2 bis n als Primzahl markieren
            for (int i = 2; i <= max; i++) prime[i] = true;
            /// Alle Produkte des Teilers i, angefangen bei 2, bis kleiner n durchlaufen
            /// Wenn n = 50, dann ist bei i = 7 Schluss, weil das Produkt = 49 ist
            for (int i = 2; i <= Math.Sqrt(max) - 1; i++)
              /// Wenn die Zahl im Array als Primzahl markiert ist
              /// Das ist bei den ersten beiden (2 und 3) definitiv der Fall
              if (prime[i])
                /// Alle weiteren Produkte des Teilers i
                /// angefangen beim Produkt i * i bis kleiner n durchlaufen
                /// j wird mit i beim nächsten Durchlauf (Vielfaches) addiert
                for (int j = i * i; j <= max; j += i) prime[j] = false;
            /// Alle Primzahlen ausgeben
            List<int> folge = new List<int>();
            for (int i = 1; i <= max; i++) if (prime[i]) folge.Add(i);
            return folge;
          }
    
          /// <summary>
          /// Primzahlen mit brute-force-Version ermitteln (ohne Array)
          /// </summary>
          /// <param name="max">Maximalzahl, bis zu der zu ermitteln ist</param>
          /// <returns>Liste der bis Max ermittelen Primzahlen</returns>
          internal List<int> Primzahlen2(int max)
          {
            /// Ergebnisliste vorbereiten
            List<int> folge = new List<int>();
            /// alle Zahlen ab 2 bis Maximalzahl überprüfen
            for (int i = 2; i <= max; i++)
            {
              /// erst einmal die zu prüfende Zahl bis auf Widerruf als Primzahl setzen
              bool primzahl = true;
              /// bis zur Wurzel aus der zu prüfenden Zahl alle Möglichkeiten prüfen
              for (int j = 2; j <= Math.Sqrt(i); j++)
              {
                /// prüfen, ob sich die zu prüfende Zahl ohne Rest teilen lässt 
                if (i % j == 0)
                {
                  /// wenn Rest = 0 dann Prüfung beenden, da keine Primzahl
                  primzahl = false;
                  break;
                }
              }
              /// Wenn kein Abbruch der Prüfung war, dann wurde Primzahl gefunden
              if (primzahl) folge.Add(i);
            }
            /// Ergebnisliste zurückgeben
            return folge;
          }
        }
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Montag, 22. April 2019 07:42