Announcement

Collapse
No announcement yet.

Hilfe! Kommentare im Quelltext

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hilfe! Kommentare im Quelltext

    Hallo Leute!
    Ich habe ein riesen Problem. Wir müssen in der Schule einen Quelltext in Deplhi kommentieren. Und zwar jeden einzelnen Schritt bzw. jede Zeile! Hab schon einige Kommentare selbst gemacht,aber jede Zeile bekomm ich nicht hin.
    Kann mir bitte jemand helfen? Wäre sehr nett!

    Hier zunächst die Aufgabenstellung, zu welcher der Quelltext gefordert wurde.
    - Auf einen Datenbestand von maximal 100 ganzen Zahlen sollen 50 Zufallszahlen aus einem Bereich von 1..20 abgelegt werden.
    - Von diesem Datenbestand sollen folgende Aussagen gewonnen und ebenfalls im Speicher abgelegt werden:
    - kleinstes und größtes Element, Summe aller Zahlen
    - Mittelwert (arithmetisch)
    - Anzahl der Zufallszahlen
    - Anzahl der Zahlen, welche größer und kleines als Mittelwert sind

    Nun der Quelltext, welcher kommentiert werden soll:

    procedure TForm1.Button2Click(Sender: TObjekt);
    //der geforderte Datentyp

    type tfeld = array [1..100] of integer;
    tdaten = record
    feld : tfeld;
    anzahl : integer;
    max : integer;
    min : integer;
    Summe : integer;
    mittelw : real;
    anzminmw : integer; (Anzahl der Werte, die kleiner sind als Mittelwert)
    anzmaxmw : integer; (Anzahl der Werte, die größer sind als Mittelwert)
    end;

    //dies ist nur die lokale Prozedur zum Sortieren des Datenbestandes
    procedure sortiere (var daten : tdaten);
    var lauf, lauf1,hilf : integer;
    begin
    for lauf := 1 to daten.anzahl do
    begin
    for lauf1 := 1 to daten.anzahl-1 do
    begin
    if daten.feld[lauf1] > daten.feld[lauf1+1]
    then
    begin
    hilf := daten.feld[lauf1];
    daten.feld[lauf1] := daten.feld[lauf1+1];
    daten.feld[lauf1+1] := hilf;
    end;
    end;
    end;
    end;

    //die benötigten Variablen
    var daten : tdaten
    lauf : integer;
    zeile : string

    //beginnt die Klieckprozedur vom Button 2, also Start- Button
    begin

    //50 Zufallszahlen sollchen gespeichert werden
    daten.anzahl := 50;

    //Initialisierung der 50 Zufallszahlen
    randomize;
    for lauf := 1 to daten.anzahl do
    begin
    daten.feld[lauf] := random(20)+1;
    end;

    //Summe bilden
    daten.Summe := 0;
    for lauf := 1 to daten.anzahl do
    begin
    daten.Summe := daten.Summe+daten.feld[lauf]
    end;

    //Mittelwert bestimmen und ablegen
    daten.mittelw := daten.Summe/daten.anzahl;

    //kleinstes und größtes Element ermitteln
    daten.max := -maxint;
    daten.min := maxint;

    //Kontrollausgabe der Initialisierung
    memo1.Lines.add(IntToStr(daten.max)+'absolut kleinstes Element');
    memo1.Lines.add(IntToStr(daten.min)+'absolut größtes Element');
    For lauf := 1 to daten.anzahl do
    begin
    if daten.feld[lauf] > daten.max then daten.max := daten.feld[lauf];
    if daten.feld[lauf] < daten.min then daten.min := daten.feld[lauf];
    end;

    //Anzahl der Elemente kleiner Mittelwert ermitteln
    daten.anzminmw := 0;
    for lauf := 1 to daten.anzahl do
    begin
    if daten.feld[lauf] < daten.mittelw then daten.anzminmw :=aten.anzminmw+1;
    end;

    //Anzahl der Elemete größer Mittelwert ermitteln
    daten.anzmaxmw := 0;
    for lauf := 1 to daten.anzahl do
    begin
    if daten.feld[lauf] > daten.mittelw
    then daten.anzmaxmw :=daten.anzmaxmw+1;
    end;

    //Ausgabe der ermittelten Werte
    memo1.lines.add('Ergebnisübersicht')

    //Textausgabe des Feldes unsortiert
    zeile := '';
    for lauf := 1 to daten.anzahl do
    begin
    zeile := zeile+IntToStr(daten.feld[lauf]+'';
    if lauf mod 20=0 then
    begin
    memo1.lines.add(zeile);
    zeile := '';
    end;
    end;
    memo1.lines.add(zeile);

    //Textausgabe sortierter Datenbestand
    sortiere(daten);
    zeile := '';
    for lauf := 1 to daten.anzahl do
    begin
    zeile := zeile+IntToStr(daten.feld[lauf])+';';
    if lauf mod 20 = 0 then
    begin
    memo1.lines.add(zeile);
    zeile :='';
    end;
    end;
    memo1.lines.add(zeile);

    //Ausgabe der gespeicherten Informationen
    memo1.lines.add('Anzahl Elemente = '+IntToStr(daten.anzahl));
    memo1.lines.add('kleinstes Element = '+IntToStr(daten.min));
    memo1.lines.add('größtes Element = '+IntToStr(daten.max));
    memo1.lines.add('Summe = '+IntToStr(daten.Summe.));
    memo1.lines.add('Mittelwert = FloatToStr(daten.mittelw));
    memo1.lines.add('Anzahl > Mw = '+IntToStr(daten.anzmaxmw));
    memo1.lines.add('Anzahl < Mw = '+IntToStr(daten.anzminmw));
    end;

  • #2
    Wer soll sich das Gewurschtel ohne Codeformatierung ansehen?

    Wenn du den Quelltext erstellt hast, wo ist das Problem, diesen zu kommentieren?
    Christian

    Comment


    • #3
      Sinnlose Aktion, JEDE Zeile zu kommentieren. Abgesehen davon sind das über 110 Zeilen, davon 16 Kommentarzeilen, also etwa ein Sechstel - wenn du ein konkretes Problem zu einer bestimmten Zeile hättest, dann okay, aber sollen wir die restlichen fünf Sechstel deiner Hausaufgabe machen?

      bye,
      Helmut

      Comment


      • #4
        crosspost

        http://www.delphi-forum.de/viewtopic...8da7bca3427f3e
        Ich habs gleich!
        ... sagte der Programmierer.

        Comment


        • #5
          Also ich versuche es mal so.
          Ich habe die reingestellte procedure TForm1.Button2Click(Sender: TObjekt) nicht getestet aber so wie es aussieht müsste sie funktionieren.
          Ich nehme an, daß die eigentliche Aufgabe für Euch Schüler darin besteht Pascal zu kommentieren, also den Programmablauf zu verstehen.
          Dummerweise hilft das Zeilenweise einfügen von Kommentarzeilen im Programmtext nicht unbedingt diesen verständlich zu interpretieren. So mußte ich ebend auch erst zweimal schauen warum soviele Kommentare drin sind.
          Auch wenn ich seit Jahren kein Delphi mehr verwendet habe so erklärt sich diese Procedure auch ohne Kommentar.
          Ich möchte Dir jetzt etwas helfen.
          Damit Dein Lehrer erkennt, daß Du Pascal verstehst benötigst Du keinen weiteren Kommentar. Die jetzt schon vorhandenen erklären schon überdeutlich was passiert und sind nach meiner Auffassung sehr vorbildlich gesetzt.
          Ich fange mit dem Urschleim an
          Wenn Du etwas nicht verstehst dann lies einfach weiter und nehme es so hin wie ich es schreibe, damit fährst Du am besten.
          Variablen sind wichtig und ohne deren Verständnis kann Dir keiner ein Programm erklären.
          So ist es äußerst variabel ob es Morgen regnet oder nicht, ob der geliebte Mensch ja oder nein sagt. Beide Fälle erwarten eine Antwort. Wenn wir die Antwort vieleicht nicht akzeptieren dann sind wir selber ein Computer geworden.
          Ein Computer kann der Variablen Regen im einfachsten Fall eine 0 oder eine 1 zuordnen.
          Dies mache ich z.B.in Pascal mit
          Regen:=0; bzw. Regen:=False;
          Da es nur zwei Möglichkeiten gibt Declariere ich die Variable Regen mit
          Var Regen: boolean;
          Auch wenns so in Pascal nicht gemacht wird, aber die Variable Regen würde Platz finden in einem einzelnen Bit.
          Geht es um die Regenwahrscheinlichkeit dann erwartet der Mensch das eine Zahl von 100 ausgespuckt wird.
          Var Regenwahrscheinlichkeit:Shortint;
          Hiermit, muß man sich beschäftigen, wenn unter Delphi gearbeitet wird.
          Pascal arbeitet sich von oben nach unten Zeile für Zeile durch.
          Liest den Inhalt und interpretiert ihn und macht dann ebend irgendwas.
          Wenn nun zur Laufzeit des Programms der Anwender auf den Button2 klickt dann wird die procedure TForm1.Button2Click(Sender: TObjekt);
          ausgeführt.
          Der Sender ist der Button2 (ein Objekt aus der Klasse Tobjekt) und wird als Auslöser für die Aktion einfach mit übergeben. Somit ist die Procedure (das Unterprogramm) jederzeit in der Lage die Frage warum , wie und wer es denn ausgelöst hat, zu beantworten.

          nun Zeile für Zeile

          es wird ein Typ definiert. So gibt es Typen mit blauen Augen und blonden Haaren, und ebend auch welche mit braunen Augen und schwarzen Haaren , komische Typen und noch viele andere.
          Hier tfield als ein Schranktyp mit 100 Schubladen. Hätte auch als totaltollerSchrank declariert werden können da der Name dafür fast frei wählbar ist.
          Pascal weiß nun das es einen Typ tfield gibt für den es jetzt einfach mal 100 Speicherzellen für ganzeZahlen (32 bit *100) bei Bedarf (falls der Typ auftaucht) freimachen muß.
          Jetzt wird der Recorder eingeschaltet.
          Nach dem zurückspulen geht dieselbe Leier wieder los.
          In einem Record können unterschiedlichste Variablen der Reihe nach gespeichert werden.
          Fragt man später den Recorder ab dann spuckt er der Reihe nach die Variablen wieder aus.
          Sucht man später eine einzelne Variable im Record (in der Aufnahme) , dann muß man spulen.
          Die Definition des Records mit dem Namen: tdaten steht zwischen
          tdaten=record
          ..
          ..
          end;

          Hier taucht auch gleich mal der definierte Typ: tfeld auf und bekommt jetzt einen Namen und Pascal macht den Speicher dafür klar. feld ist also die Variable im Record die 100 Schubladen enthält. Also vom Namen her hätte ebend auch Schrank gepasst.
          Die Variablen die noch im Record aufgelistet sind, erklären sich schon vom Namen her und sind im Vergleich zur Variablen feld auch nicht so Speicherhungrig.
          Also alle integer Variablen wie min, max, Summe etc. können nur eine einzige ganze Zahl speichern. Diese ganze Zahl darf jedoch nicht kleiner als -2.147.483.648 bzw. größer als2.147.483.647 sein. Was aber in unserem Fall einfach auszuschließen ist. So sollten zB. alle 50 Zahlen zufällig die Zahl 20 sein so ist deren Summe 50*20=1000. Also kann Summe allerhöchstens 1000 sein.
          Und die Zahl 1000 passt locker in den Speicher(32 Bit= 4Byte) einer integer Variablen.
          Hier wäre sogar Smallint(16Bit=2Byte) als Variablentyp völlig ausreichend (-32768..+32767).
          Bei min und max da kann es sich ja schlimmstenfalls nur um die Zahl 1 bzw. bei max die Zahl 20 als Ergebnis drehen. Für so kleine Zahlen könnte man sogar einen noch kleineren Speicher reservieren. Der Variablentyp dafür in Delphi wäre der Shortint mit (8Bit= 1Byte) und mit ihm lassen sich ganze Zahlen zwischen -128...bis..+127 fehlerfrei speichern.
          Auch die Abweichungen vom Mittelwert als anzminmw und anzmaxmw passen ganz sicher in eine Shortint-Variable.
          So nun noch zum Mittelwert. Da dieser letztlich aus einer Bruchrechnung resultiert ist der Variablentyp richtig gewählt. Allerdings speichert und rechnet der Computer durch den realtyp ausgelöst in unserem Fall bis auf die 13te Stelle hinterm Komma genau und reserviert 8Byte zum speichern der Zahl. Hier würde eine Single-Variable (5 bis 6 Stellen hinterm Komma genau) die nur 4 Byte reserviert ausreichen.
          Nun haben wir den Record durchleuchtet.
          Nach dem end; des records sind alle angesprochenen Variablen im Speicher des Rechners reserviert. Dies bedeutet aber nicht, daß sie vorhanden sind.
          Ich kann die Variablen noch nicht abfragen,sie sind Teil eines Records.
          ZB existiert feld nicht im Rechnerspeicher es ist Teil einer Aufnahme im Rekorder. Ich muß also erst auf play oder Aufnahme drücken um die Variable feld mit ihren ganzen Schubladen zu verändern oder auszulesen. Nur die Kassette für den Record liegt jetzt bereit, ist beschriftet und hat die richtige Bandlänge um die Daten aufzunehmen. Auch gibt es noch ein kleines Problem es ist noch gar nicht klar welcher Rekorder die Kassette mit der Aufnahme(mit dem Record) zum arbeiten enthält, also verwendet werden soll.
          Dies ist im weiteren mit zB. daten.feld[lauf1] richtig beachtet.
          Doch zurück zum Ablauf nach der Declaration des Records tdaten.
          Nun wird ein weiteres Unterprogramm vollständig in unsere
          procedure TForm1.Button2Click(Sender: TObjekt);
          eingebunden
          Hier passiert jetzt etwas kurioses.
          Pascal liest Zeile für Zeile und macht gar nichts.
          Merkt sich einfach nur, das da ein paar Zeilen sind die für den Fall das irgendwann
          sortiere(irgendwas) aufgerufen wird.
          Das machen wir jetzt auch und landen bei Var .
          var daten; tdaten
          Endlich ist der Rekorder Klar wir nehmen den aus der Schlafstube und der Rekorder heißt (Phillips) daten.
          Wir stecken den Stecker rein schalten den Netzschalter ein ,öffnen die Klappe und schieben unsere tdaten-kassette rein.
          Wir initialisieren kurz unsere Kassette durch und spulen danach zurück zu Anfang.
          Jetzt existieren alle angesprochenen Variablen und jede Variable enthält in unserem Fall schon eine Zahl. Wenn wir sie jetzt abfragen würden (Play) so enthält jede Variable die Zahl Null. So geschrieben -> 0.
          Für den Programmablauf werden noch 2 Variablen declariert.
          Die Variable lauf kann eine ganze Zahl im angesprochenen integer Bereich speichern und wird
          im weiteren Verlauf in den Zählschleifen eingesetzt.
          Die Variable zeile wird als Schleifenvariable und damit temporärer Zwischenspeicher zur Ergebnisausgabe eingesetzt.
          Bin mir ganz sicher das da eine schließende Klammer vor dem Plus fehlt.
          zeile := zeile+IntToStr(daten.feld[lauf]+'';
          Doch nun zurück nach der Variblendeclaration.
          Mit begin startet die Programmausführung mit den nun mitgegebenen Variablen.
          Das Herzstück der Procedure habe ich erklärt, was jetzt folgt wird ganz einfach.
          Von oben nach unten
          Zuweisung aller Zahlen zu den Variablen im Rekorder.
          Zuerst Rekorder vorspulen zur Variablen -> anzahl , Aufnahme drücken und 50 speichern.

          daten.anzahl:=50;

          also schreibe ich jetzt hier im weiteren Verlauf anstatt daten.anzahl einfach die 50
          den Zufallsgenerator starten
          randomize;

          for lauf:=1 to daten.anzahl
          also
          von 1 bis 50
          anders gesagt
          hole 50 zufällige Zahlen die zwischen 1 und 20 liegen und speichere sie nacheinander
          im rekorder unter feld
          daten.feld[1] bis daten.feld[50] enthalten nach der Schleife alle eine Zufallszahl von 1-20.

          addiere zur 0 von daten.Summe 50 mal den nächsten Inhalt von feld.
          Beginne mit daten.feld[1]

          daten.mittelw:=daten.Summe / 50
          errechnet und speichert im rekorder die Variable mittelw

          speichere mit dem rekorder für max die Zahl - 2.147.483.648
          speichere mit dem rekorder für min die Zahl 2.147.483.647

          kontrolliere jetzt jede der 50 Schubladen von feld aufwärts Beginne mit der ersten Schublade.
          Wenn die enthaltene Zahl größer als max ist dann korrigiere max im Rekorder auf die gefundene Zahl.
          Nach kontrolle aller Schubladen enthält max die größte zufällige Zahl aus feld.
          So wird auch daten.min aktualisiert.

          Reiße nu nochmal alle 50 Schubladen der reihe nach auf schau rein und wenn die enthaltene Zahl größer als der Mittelwert (daten.mittelw) ist dann addiere 1 in der anzmaxmw Schublade zu der Zahl die dadrinliegt.

          Mach das ganze nochmal doch kiek nu ob ob kleiner als der Mittelwert und wenn ja dann addiere 1 in der anzminmw - Schublade.

          Jetzt sind alle Daten im Record fertig, müssen nur entsprechend zu Anzeige gebracht werden.
          also zur Textausgabe

          geht gleich weiter

          Comment


          • #6
            So wie es aussieht werden wieder die ersten 50 Schubladen nacheinander rausgezogen.
            Die in der Schublade gefundene Zahl wird zum String umgewandelt und an den String Zeile einfach drangehängt.
            Das bedeutet das der String (Zeichenkette) immer länger wird.
            Damit dieser nicht zu lang wird wird die Anzahl der schon ausgelesenen Schubladen ständig überwacht.
            Während der Abarbeitung wird mit jedem Schleifendurchlauf die Variable lauf
            um 1 erhöht
            for lauf := 1 to daten.anzahl do
            Also beim ersten Durchlauf ist lauf=1
            beim 2. ten Durchlauf ist lauf=2
            usw.

            Sowie lauf =20 ist dann besitzt das Ergebnis der Division durch 20 keinen Rest.
            (in Delphi bedeuted mod: zeige den Rest der division durch)
            if lauf mod 20=0 then
            wenn 20 dividiert durch 20 keinen Rest (20/20=1, Rest=0) besitzt dann tue

            begin
            memo1.lines.add(zeile);
            zeile :='';
            end;

            also nach jedem 20-sten Durchlauf wird in der Memo1 des Formulars
            die Variable zeile (also 20 Zahlen in einer Zeile) hinzugefügt, und die Variable :zeile wird wieder zu einem leeren String gemacht.
            zeile := '';

            Wenn nun das Programm wieder zum Schleifenanfang springt
            for lauf := 1 to daten.anzahl do
            wird lauf wieder um 1 erhöht also zur 21
            wenn ich nun 21 /20 teile dann ist das Ergebnis 1 und Rest 1. Da der Rest nicht 0 ist
            wird keine Zeile ausgegeben.
            der Block
            begin
            memo1.lines.add(zeile);
            zeile :='';
            end;
            wird dann also nicht ausgeführt

            der nächste Auslöser ist wenn die Variable lauf den Wert 40 besitzt
            denn 40 /20 =2 und der Rest ist wieder 0.

            Natürlich werden die Zahlen 41 bis 50
            so nicht ausgegeben. Wenn die Schleife lauf bis 50 hochgezählt hat, dann
            stehen in der Variablen string noch die Zahlen 41 bis 50 in einer Zeile.
            Diese Zeile wird dann durch das seperate commando
            memo1.lines.add(zeile);
            ausgegeben.

            Nachdem die Ausgabe der Zufallszahlen unsortiert erfolgte läuft nochmal das gleiche ab.
            Nur mit einem Unterschied vorher wird mit
            sortiere(daten);

            das anfangs überlesene Unterprogramm

            procedure sortiere (var daten : tdaten);
            var lauf, lauf1,hilf : integer;
            begin
            for lauf := 1 to daten.anzahl do
            begin
            for lauf1 := 1 to daten.anzahl-1 do
            begin
            if daten.feld[lauf1] > daten.feld[lauf1+1]
            then
            begin
            hilf := daten.feld[lauf1];
            daten.feld[lauf1] := daten.feld[lauf1+1];
            daten.feld[lauf1+1] := hilf;
            end;
            end;
            end;
            end;

            aufgerufen
            Der Rekorder wird an das Unterprogramm sortiere übergeben.

            -interessantist das es hier auch eine Variable lauf gibt.
            Das Unterprogramm besitzt damit eine eigene Variable lauf die nicht
            mit der Variablen lauf aus dem Hauptprogramm identisch ist.
            Dies hätte so nicht sein müssen, da ohne erneute Declaration auch die Variable des Haupt-
            programms hätte genutzt werden können. Generell sind Variablen-Mehrfachdeclarationen kein guter Programmierstiel und oft Ursache für unvorhergesehene Ereignisse.
            Aber egal Pascal erstellt nun
            var lauf, lauf1,hilf : integer;

            die Variablen lauf, lauf1 und hilf

            nach begin geht es los.
            for lauf := 1 to daten.anzahl do
            begin
            for lauf1 := 1 to daten.anzahl-1 do
            begin
            if daten.feld[lauf1] > daten.feld[lauf1+1]
            then
            begin
            hilf := daten.feld[lauf1];
            daten.feld[lauf1] := daten.feld[lauf1+1];
            daten.feld[lauf1+1] := hilf;
            end;
            end;
            end;
            aud deutsch
            von lauf:=1 bis 50 tue
            von lauf1:= 1 bis 49 tue
            Wenn in Schublade[lauf1]die Zahl größer ist als in der Nächsten dann
            nimm die Zahl aus der ersten Schublade und gib die Zahl der Variablen hilf
            in die nun leere erste Schublade packe die kleinere Zahl aus der 2-ten
            Packe die größere Zahl der Variablen hilf in die 2-te
            springe zurück (und mache das ganze ebend durch alle Schubladen durch)
            springe zurück und wiederhole

            die innere Schleife die 2 Schubladen aufzieht kann ja nur den Wert von der Vorgängerschublade mit dem Wert der Nachfolgerschublade vergleichen und den
            größeren Wert um eine Schublade versetzt nach hinten tauschen.
            Wenn also dummerweise vor der Ausführung die Größte zufällige Zahl zB. 20 in
            daten.feld[1] war und die kleinste zufällige Zahl in daten.feld[50] war dann wird das Ergebnis
            nach dem ersten Durchlauf so aussehen das die größte Zahl von der Schublade 1 bis in die Schublade 50 durchgereicht wurde. Allerdings ist die kleinste Zahl, die 1 , die in der 50-sten Schublade befand nun in der 49-sten Schublade zu finden. Deshalb wird die innere Schleife
            50 mal aufgerufen um sicherzugehen das die 1 bis zur ersten Schublade durchgereicht wird.

            Nach dem verlassen des Unterprogramms
            liegen die 50 zufälligen Zahlen also aufsteigend sortiert im Array daten.feld vor.
            Nach erneuter Ausgabe der sortierten Zahlen, werden noch die restlichen Variablen in Memo1
            zu anzeige gebracht, und das wars dann auch.
            LG

            Bitte zerreißt mich net falls es nicht ganz stimmig ist.

            Comment

            Working...
            X