Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Zufällige Zahlen im Array + Ausgeben in Stringgrid (https://www.delphipraxis.net/184051-zufaellige-zahlen-im-array-ausgeben-stringgrid.html)

CShepard 21. Feb 2015 20:52

Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Liste der Anhänge anzeigen (Anzahl: 2)
Guten Abend, ich bräuchte etwas Hilfe bei meiner Hausaufgabe. Eigentlich habe ich alles gemacht, nur ist alles irgendwie verbuggt. Es wäre sehr nett, wenn mir jemand sagen könnte, was ich machen soll, damit das Programm richtig läuft. :-D
______

Genau so steht unsere Aufgabe auf dem Arbeitsblatt da und wir müssen es LEIDER genau so machen:
-> beim Starten des Programmes sollen 20 Zufallszahlen in ein Array eingelesen werden
-> beim Drücken des Buttons "Zahlen einlesen" werden die Zahlen aus dem Array in die 1. Spalte geschrieben.
-> mithilfe des Buttons "Zahl" kann man sich jede beliebige Zahl des Arrays ansehen
-> man soll die Zahlen in der Tabelle ändern können und diese testen
-> welche Zahl erscheint nach dem Ändern nun im Edit-Objekt?
-> Wir brauchen noch den Button "Änderungen merken", damit die Änderung aus der Tabelle im Array abgespeichert werden.
______

Das ist mein Code:

Code:
procedure TForm1.FormCreate(Sender: TObject);
var i:byte;
zufallszahl: array[1..20] of integer;
begin
randomize;
for i:=1 to 20 do
begin
zufallszahl[i]:=random(256);
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var i:byte;
zufallszahl: array[1..20] of integer;
begin
for i:=1 to 20 do
begin
stringgrid1.cells[1,i]:=inttostr(zufallszahl[i]);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var z:integer;
zufallszahl: array[1..20] of integer;
begin
z:=strtoint(edit1.Text);
edit2.text:=inttostr(zufallszahl[z]);
end;

procedure TForm1.Button3Click(Sender: TObject);
 var i:integer;
 zufallszahl: array[1..20] of integer;
begin
for i:=1 to 20 do
begin;
zufallszahl[i]:=strtoint(stringgrid1.cells[1,i]);
end;
end;
_______________

Das ist mein Problem:
1.) Für die Zufallszahlen habe ich den Bereich 0-255 gewählt (random(256)), doch es werden größere Zahlen angezeigt.
2.) Die Zahlen in dem Stringgrid ergeben immer das selbe Muster (z.B. tauchen in Zeile 4 und 6 IMMER die 0 auf, in einer anderen Zeile immer -2).
3.) Obwohl ich im Stringgrid eine Zelle ändere und "Änderung merken" klicke, ändern sich nie der zugehörige Wert bei den Array (z.B.:Ändere ich Zelle Nummer 5, ändert sich nicht Zufallszahl[5])

Es sind 2 verschiedene Screenshots im Anhang, damit ihr das Zahlenmuster im Stringgrid, sowie das gesamte Programm von außen seht.

himitsu 21. Feb 2015 21:18

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Was fällt dir gleich auf?
Du schreibst die Werte in eine Variable rein und liest sie aus einer ganz anderen Variable aus.
(auf Blatt A drauf schreiben und dann "halbzufällige" Speicherwerte von Blatt B auslesen)

Du wolltest diese Variable doch bestimmt in Form > private deklarieren?



Und sagt dir dein Compiler denn nicht ein paar nette Meldungen? (vonwegen nicht initialisiert und so)

BadenPower 21. Feb 2015 22:23

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Und beim lesen des Quellcode hab' ich Augenkrebs bekommen.
Das kann man doch Übersichtlicher und lesbarer gestalten:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    StringGrid1: TStringGrid;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FZufallsZahl: array[1..20] of Integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Byte;
begin
  Randomize;
  for I := 1 to 20 do
   begin
    FZufallsZahl[I] := Random(256);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Byte;
begin
  for I := 1 to 20 do
   begin
    StringGrid1.Cells[1,I] := IntToStr(FZufallsZahl[I]);
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit2.Text := IntToStr(FZufallsZahl[StrToInt(Edit1.Text)]);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 1 to 20 do
   begin;
    FZufallsZahl[I] := StrToInt(StringGrid1.Cells[1,I]);
   end;
end;


end.
Übrigens funktioniert der Code oben, so wie Du es wolltest.
Und noch besser: man kann ihn lesen

Dein Problem war die "Sichtbarkeit" der Variable zufallszahl.

In jeder Prozedur erstellst Du diese Variabel neu und wunderst Dich, warum es nicht so will, wie es soll.

Wenn Du eine Variabel in einer Prozedur erstellst, also im var-Abschnitt der Prozedur, dann ist diese nur in dieser Prozedur gültig, auch wenn sie den gleichen Namen hat wie in einer anderen Prozedur.

Sir Rufo 21. Feb 2015 22:35

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Ein weiterer Tipp für mehr Übersichtlichkeit und quasi Dokumentieren durch Programmieren:
Delphi-Quellcode:
TForm1 = class( TForm )
...
private
  procedure InitArrayWithRandomData;
  procedure ShowArrayInGrid;
  procedure StoreGridInArray;
  ...
end;

procedure TForm1.FormCreate( Sender : TObject );
begin
  InitArrayWithRandomData;
end;

procedure TForm1.Button1Click( Sender : TObject );
begin
  ShowArrayInGrid;
end;

procedure TForm1.Button2Click( Sender : TObject );
begin
  StoreGridInArray;
end;
Schon kannst du dir einen grossen Teil der Kommentare sparen und jeder (auch du nach ein paar Tagen/Wochen/Monaten) sieht sofort, welche Aktion beim Klick auf den Button passieren soll bzw. was in der Methode selber vonstatten geht.

himitsu 21. Feb 2015 22:41

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Kann man auch, ohne dafür extra Prozeduren zu machen, aber man sollte sowieso den Komponenten ordentliche Namen geben, und damit auch deren Events. :stupid:
(Button1 und Button1Click sagen ja sowas von garnichts zu dem, was sie machen)

CShepard 22. Feb 2015 17:47

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Danke an alle für die Hilfe. :-D
Sorry, ich wusste nicht, wo Arrays deklariert werden müssen. Hab das unter type über private versucht und sonst irgendwo, doch es hat nie geklappt... darum wurde ich etwas erfinderisch und habe den Array immer in jeder Prozedur deklariert. Dann hielt ich es für richtig, da keine Zeile mehr rot war. :roll:
Im Unterricht haben wir erklärt bekommen, wie der Syntax aussieht und was Arrays bewirken. Nur WO wir Arrays deklarieren müssen- das wurde nicht erklärt und wir haben dazu auch nichts aufgeschrieben.

@Sir Rufo: Guter Tipp, ich hoffe, ich darf im Unterricht später auch solche Befehle anwenden. Bis jetzt dürfen wir alles nur so aufschreiben, wie wir es gelehrt bekommen haben... leider, denn mit diesen Befehlen spart man etwas Arbeit.:thumb:

@Baden Power: Tut mir leid, ich verspreche, ich werde beim nächsten Mal mehr auf Anschaulichkeit achten, bin noch neu hier. :wink:

Sir Rufo 22. Feb 2015 18:00

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Zitat:

Zitat von CShepard (Beitrag 1291001)
@Sir Rufo: Guter Tipp, ich hoffe, ich darf im Unterricht später auch solche Befehle anwenden. Bis jetzt dürfen wir alles nur so aufschreiben, wie wir es gelehrt bekommen haben... leider, denn mit diesen Befehlen spart man etwas Arbeit.:thumb:

Es sind ja gar keine Befehle, sondern Methoden der Klasse, die du selber schreibst.

Ziel ist es dabei den eigenen Code in besonders übersichtliche und möglichst kleine Häppchen zu teilen und eben keine Happen oder ganze Brocken zu erstellen.

Ich kann mir nicht vorstellen, dass das verboten ist. Das verwechselst du anscheinend mit der Verwendung von irgendwelchen Delphi-Units, wo einiges/vieles schon fertig existiert, ihr aber diese Grundlagen ja lernen sollt -> selber implementieren.

BadenPower 22. Feb 2015 19:46

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Zitat:

Zitat von CShepard (Beitrag 1291001)
Im Unterricht haben wir erklärt bekommen, wie der Syntax aussieht und was Arrays bewirken. Nur WO wir Arrays deklarieren müssen- das wurde nicht erklärt und wir haben dazu auch nichts aufgeschrieben.

Es geht hierbei nicht um Array, sondern um alle Variable-Typen.

Wo etwas deklariert wird ist entscheident für die Sichtbarkeit der Variable.

Unten einmal ein kleines Beispiel in welchem ich 3 Variablen mit dem Namen ZufallsZahl erstellt habe, welche jeweils verschiedene Gültigkeitsbereiche haben.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, Forms, Classes, Controls,;

var
  ZufallsZahl: Integer; // gültig in der ganzen Anwendung

type
  TForm1 = class(TForm)
    procedure Button1Click(Sender: TObject);
  private
   ZufallsZahl: Integer; // gültig in der ganzen Klasse Form1
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm.Button1Click(Sender: TObject);
var
  ZufallsZahl: Integer; // nur gültig in diese Procedure
begin
//
end;
Als Laie könnte man meinen, dass dies ein und dieselbe Variable wäre, die ist aber nicht so.

Es sind tatsächlich 3 verschiedene Variablen, welche jeweils einen eigenen Wert haben können.

Durch eine erneute Variabledeklaration mit dem gleichen Namen in einem untergeorneteten Bereich wird die übergeordnete Variable verdeckt.

Sir Rufo 22. Feb 2015 22:26

AW: Zufällige Zahlen im Array + Ausgeben in Stringgrid
 
Du hattest noch zeigen können, wie man auf die anderen Varaiblen zugreifen kann, wenn benötigt
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, Forms, Classes, Controls,;

var
  ZufallsZahl: Integer; // gültig in der ganzen Anwendung, wo dise Unit in den uses steht

type
  TForm1 = class(TForm)
    procedure Button1Click(Sender: TObject);
  private
   ZufallsZahl: Integer; // gültig in der ganzen Klasse Form1
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm.Button1Click(Sender: TObject);
var
  ZufallsZahl: Integer; // nur gültig in diese Procedure
begin
  ZufallsZahl := 1; // lokale Variable
  Self.ZufallsZahl := 2; // Feld der Klasse TForm1
  Unit1.ZufallsZahl := 3; // Unit Variable
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz