Autor Beitrag
bluebutton38
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 27.04.10 09:58 
Ein freundliches "Hallo!" an euch Programmierer,

ich soll für meinen Informatik-Lehrer eine Binäruhr schreiben und bin auch so gut wie fertig, jedoch habe ich das Problem, dass meine Shapes (die sollen die einsen bzw. nullen durch eine rote bzw. weiße Farbe ausdrücken) mir lediglich die erste Zahl, also 1, korrekt anzeigen, aber danach werden alle Shapes geleert und es fängt wieder von vorne an (normalerweise sollten ja dann 10, 11, 100,... folgen). Ich weis einfach nicht, warum das ganze nicht funktioniert.

Hier mal der Quelltext für euch:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
unit Binaeruhr;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
    procedure ShapesErzeugen;
    procedure Zahlenlesen(a:array of integer; Shapes:array of TShape);

var
  Form1: TForm1;
  minZaehler, stuZaehler:integer;
  sek, min, stu:array [0..10of integer;
  sekShapes, minShapes, stuShapes:array of TShape; 

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
 var clear, Zaehler : integer;
begin
  ZaehlerStellen;
  for Zaehler:=0 to 9 do
    sek[Zaehler]:=Dualzaehlen(sek);
  {auf das array, auf dem die
   Sekunden sind wird die neue
   Zeit geschrieben}


  inc(minZaehler); //stellt fest, wann eine minute um ist
  Zahlenlesen(sek, sekShapes);
  if minZaehler=60 then//hier passiert das gleiche wie bei den sekunden
  begin                //nur für die minuten
    ZaehlerStellen;
    for Zaehler:=0 to 9 do
    min[Zaehler]:=Dualzaehlen(min);
    inc(stuZaehler); //stellt fest, wann die stunde um ist
    for clear:=0 to 9 do
    sek[clear]:=0//die sekunden werden wieder auf null gestellt
    Zahlenlesen(min, minShapes);
    minZaehler:=0;//damit die Zählung bis zur nächsten minute klappt
  end;
  if stuZaehler=60 then //das selbe, wie bei den minuten nur für die stunden
  begin
    ZaehlerStellen;
    for Zaehler:=0 to 9 do
    stu[Zaehler]:=Dualzaehlen(stu);
    for clear:=0 to 9 do
    min[clear]:=0;
    Zahlenlesen(stu, stuShapes);
    StuZaehler:=0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
  var clear : integer;
begin
  minZaehler:=0//initialisierung
  stuZaehler:=0;
  ShapesErzeugen;
  for clear:= 0 to 9 do
  begin
    sek[clear]:=0;
    min[clear]:=0;
    stu[clear]:=0;
  end;
end;

procedure ShapesErzeugen;  //macht die benutzung der shapes in schleifen
var i, oben, links:integer;//einfacher, da ich ein Shape mit Shape[]
begin                      //aufrufen kann
  SetLength(sekShapes, 6);
  SetLength(minShapes, 6);
  SetLength(stuShapes, 5);
  oben:=32;
  links:=24;
  for i:=0 to 5 do   //erstellt die Shapes der Sekunden
  begin
    sekShapes[i]:= TShape.Create(nil);
    sekShapes[i].Parent:=Form1;
    sekShapes[i].Shape:=stCircle;
    sekShapes[i].Top:=oben;
    sekShapes[i].Left:=links;
    oben:=oben+16;
    sekShapes[i].Width:=9;
  end;
  oben:=32;
  links:=88;
  for i:=0 to 5 do  //erstellt die Shapes für die Minuten
  begin
    minShapes[i]:= TShape.Create(nil);
    minShapes[i].Parent:=Form1;
    minShapes[i].Shape:=stCircle;
    minShapes[i].Top:=oben;
    minShapes[i].Left:=links;
    oben:=oben+16;
    minShapes[i].Width:=9;
  end;
  oben:=32;
  links:=166;
  for i:=0 to 4 do  //erstellt die Shapes für die Stunden
  begin
    stuShapes[i]:= TShape.Create(nil);
    stuShapes[i].Parent:=Form1;
    stuShapes[i].Shape:=stCircle;
    stuShapes[i].Top:=oben;
    stuShapes[i].Left:=links;
    oben:=oben+16;
    stuShapes[i].Width:=9;
  end;
end;


procedure Zahlenlesen(a:array of integer; Shapes:array of TShape);
var lauf, Zahl:integer;
begin
  zahl:=length(Shapes);
  for lauf:= 0 to zahl-1 do
  begin
    if a[lauf] = 1 then               //wenn die momentane zahl eine eins ist
      Shapes[lauf].Brush.Color:=clred;//wird das dazu passende Shape rot
    if a[lauf] = 0 then                 //wenn sie jedoch null ist
      Shapes[lauf].Brush.Color:=clwhite;//wird das Shape weiß
  end;
end;


end.





//Header-Datei

unit BinaeruhrHeader;

interface

  function Dualzaehlen (a:array of integer): integer;
  procedure ZaehlerStellen;

  var Nr, Zaehlerb:integer;

implementation

procedure ZaehlerStellen;
begin
  Zaehlerb:=0//stellt den zaehler für die function darunter
end;


function Dualzaehlen (a:array of integer):integer;
var lauf:integer;
begin
  if Zaehlerb=0 then    //function soll nur beim ersten mal die zeit erhöhen
  begin
    lauf:=-1;
    repeat
      inc(lauf);
      if a[lauf]=0 then //wenn die Zahl gleich null ist wird
        a[lauf]:=1      //sie eins
      else
        a[lauf]:=0;     //wenn die zahl eins ist wird sie null
    until a[lauf]=1;    //dann muss sich auch die nächste zahl
  end;                              //erhöhen. deswegen die schleife
      result:=a[Zaehlerb];//am ende werden die einsen und nullen
      inc(Zaehlerb);                  //an das sekunden-, minuten- oder stunden-
end;                                 //feld abgegeben und der zaehler erhöht
                                     //sich, damit die nächste zahl gelesen
end.                                 //wird, sobald die function von der
                                     //Schleife noch mal aufgerufen wird


Vielen Dank für jegliche Antworten und Lösungsvorschläge schon einmal im voraus

euer bluebutton

Moderiert von user profile iconKlabautermann: Quote- durch Delphi-Tags ersetzt.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 27.04.10 11:14 
:welcome:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure Zahlenlesen(a:array of integer; var Shapes:array of TShape);
var lauf, Zahl:integer;
begin
  zahl:=length(Shapes);
  for lauf:= 0 to zahl-1 do
  begin
    if a[lauf] = 1 then               //wenn die momentane zahl eine eins ist
      Shapes[lauf].Brush.Color:=clred;//wird das dazu passende Shape rot
    if a[lauf] = 0 then                 //wenn sie jedoch null ist
      Shapes[lauf].Brush.Color:=clwhite;//wird das Shape weiß
  end;
end;



Da muss ein "var" hin. Sonst werden nur innerhalb der procedure die Shapes verändert...und nach Beendigung der procedure wieder verworfen. Der var-parameter sagt, dass die Veränderungen auch nach außen (also in deine globalen Arrays) übernommen werden soll. Ich denke zumindest, dass es daran liegt.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 27.04.10 11:16 
Stellt sich natürlich wieder die Frage, warum global? Warum ist die Prozedur keine Methode der Form, wo sie doch offensichtlich auf deren Elemente zugreift. Hätte man gleich ein richtiges Konzept verfolgt, wäre das Problem wahrscheinlich gar nicht aufgetreten.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 27.04.10 11:21 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Hätte man gleich ein richtiges Konzept verfolgt, wäre das Problem wahrscheinlich gar nicht aufgetreten.

user profile iconbluebutton38 hat folgendes geschrieben Zum zitierten Posting springen:
ich soll für meinen Informatik-Lehrer eine Binäruhr [...]

Du warst von Anfang an perfekt, richtig? :mrgreen:

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Stellt sich natürlich wieder die Frage, warum global? Warum ist die Prozedur keine Methode der Form, wo sie doch offensichtlich auf deren Elemente zugreift.

Das Problem wäre das selbe, da für 3 arrays nur eine procedure verwendet wird (weßhalb die Elemente auch als parameter übergeben würden).
Ehrlich gesagt find ich den Programmierstil relativ gut. Ich habe sofort kapiert, wie das Programm funktioniert.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 27.04.10 11:46 
user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
Du warst von Anfang an perfekt, richtig? :mrgreen:

Das habe ich nicht behauptet.

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Stellt sich natürlich wieder die Frage, warum global? Warum ist die Prozedur keine Methode der Form, wo sie doch offensichtlich auf deren Elemente zugreift.

Das Problem wäre das selbe, da für 3 arrays nur eine procedure verwendet wird (weßhalb die Elemente auch als parameter übergeben würden).
Ehrlich gesagt find ich den Programmierstil relativ gut. Ich habe sofort kapiert, wie das Programm funktioniert.[/quote]
Aber wenn ich da die ganzen globalen Variablen sehe, dann weiß ich, dass da was nicht stimmt mit dem Konzept.
SvenAbeln
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 334
Erhaltene Danke: 3



BeitragVerfasst: Di 27.04.10 11:54 
Sorry user profile iconXion, aber das array shapes wird doch gar nicht verändert, also brauch dort auch kein var hin.
Aber hier muss eins hin:
ausblenden Delphi-Quelltext
1:
function Dualzaehlen(var a: array of integer): integer;					

Im Timer wird diese Funktion 10 mal aufgerufen, aber nur beim erstem mal wird die Zahl erhöht. Bei den 9 anderen aufrufen wird halt wieder mit dem alten Wert (0,0,0,0...) gearbeitet.
So wird das Array wirklich geändert und man braucht dir Prozedur auch nur noch einmal aufrufen:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
procedure Dualzaehlen(var a: array of integer);
var lauf: integer;
begin
  lauf := -1;
  repeat
    inc(lauf);
    if a[lauf] = 0 then // wenn die Zahl gleich null ist wird
      a[lauf] := 1 // sie eins
    else
      a[lauf] := 0// wenn die zahl eins ist wird sie null
  until a[lauf] = 1// dann muss sich auch die nächste zahl
end;


procedure TForm13.Timer1Timer(Sender: TObject);
var clear, Zaehler: integer;
begin
  ZaehlerStellen;
  Dualzaehlen(sek);
  { auf das array, auf dem die
    Sekunden sind wird die neue
    Zeit geschrieben }


  inc(minZaehler); // stellt fest, wann eine minute um ist
  Zahlenlesen(sek, sekShapes);
  if minZaehler = 60 then // hier passiert das gleiche wie bei den sekunden
  begin // nur für die minuten
    ZaehlerStellen;
    Dualzaehlen(min);
    inc(stuZaehler); // stellt fest, wann die stunde um ist
    for clear := 0 to 9 do
      sek[clear] := 0// die sekunden werden wieder auf null gestellt
    Zahlenlesen(min, minShapes);
    minZaehler := 0// damit die Zählung bis zur nächsten minute klappt
  end;
  if stuZaehler = 60 then // das selbe, wie bei den minuten nur für die stunden
  begin
    ZaehlerStellen;
    Dualzaehlen(stu);
    for clear := 0 to 9 do
      min[clear] := 0;
    Zahlenlesen(stu, stuShapes);
    stuZaehler := 0;
  end;
end;
bluebutton38 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 27.04.10 13:23 
Zunächst mal ein herzliches Danke dafür, dass ihr mein Problem gelöst habt und ich bin heilfroh, dass ich jetzt nur noch eine genaue Zeiteinstellung vornehmen muss, also, dass das Programm die momentane Zeit des PCs abliest und diese dann direkt auf die Zeitarrays gibt.

Dann noch ein kleines Wort zu meinem Programmierstil: Ich versuche mir anzugewöhnen selbst gemachte functions und procedures in Header-Dateien zu schreiben, da dadurch meiner Meinung nach der Quellcode übersichtlicher wird, aber bei den zweien, die noch in der MainUnit sitzen, hat Delphi noch ein wenig rumgemeckert, aber das Problem habe ich erst mal hinter das gestellt, das ihr mir gerade beantwortet habt :wink:
Außerdem bin ich eher der Typ, der nicht sofort aufräumt, sondern gegen Ende oder, wenn ich ma kurz ne Denkpause brauch^^, also habe ich manche Variablen noch global vereinbart, obwohl ich sie auch lokal vereinbaren könnte (Ich habe manche global, weil unser Lehrer Initialisierungen mag :roll: , aber ich glaub das mach ich auch ma weg), sowie einige Variablen, die durch andere ersetzt werden könnten.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 27.04.10 13:28 
Was verstehst du unter Header-Dateien bei Delphi?

Aber eigentlich sollte man das ganze in eine Klasse verpacken, dann braucht es auch keine globalen Variablen, denn das wären dann private Felder der Klasse.

Und bitte nimm diesen Kommentar:inc(minZaehler); // stellt fest, wann eine minute um ist da weg. Das tut in den Augen weh. Inc prüft nichts und stellt auch nichts fest, sondern inkrementiert eine Ganzzahl. Und das muss man nicht kommentieren, das sehe am Code.
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Di 27.04.10 13:42 
Ich muss user profile iconLuckie beipflichten, als ich mit dem Programmieren angefangen habe verwendete ich auch oft globale Variablen, die Folge davon waren ärgerliche Fehlersuchen.;)

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.