Frage zu Typdeklaration

Forum für alles rund um die MSEide und MSEgui

Frage zu Typdeklaration

Beitragvon fliegermichl » 26. Sep 2017, 10:06 Frage zu Typdeklaration

Hallo,

ich arbeite ja gerade an der Portierung unseres DachCAD Programms.
Um nun nicht das Eingabeformular für jeden Dachtyp hart codiert erstellen zu müssen, wollte ich mir ein Array mit den Dachtypen, deren Namen und Klasse des Eingabeformulares erstellen.
Das habe ich bis jetzt so gemacht:
Code: Alles auswählen
 
type
 dacheingabeformrecty = packed record
  Name  : msestring;
  formclass : custommseformclassty;
 end;
 
 dachtypenty = (dtpultdach, dtsatteldach, dtwalmdach, dtkrueppelwalmdach, dtzeltdach,
              dtturm, dtmansarddach1, dtmansarddach2, dtwinkelbau, dt3giebelbau,
              dttbau, dttonnendach, dtrechteckbau, dtlbau, dthbau, dtschleppgaube, dtsattelgaube, dtwalmgaube,
              dtkrueppelwalmgaube, dtspitzgaube, dttrapezgaube, dttonnengaube,
              dtschweifgaube, dtfledermausgaube, dtkamin, dtdachfenster);
 
 
 steildachtypen = dtpultdach..dttonnendach;
 flachdachtypen = dtrechteckbau..dthbau;
 gaubentypen = dtschleppgaube..dtfledermausgaube;       
 
const
 DacheingabeSteildach : array[steildachtypen] of dacheingabeformrecty = (
  (Name : 'Pultdach'; formclass : tdacheingabepultdachfo),
  (Name : 'Satteldach'; formclass : tdacheingabepultdachfo),
  (Name : 'Walmdach'; formclass : nil),
  (Name : 'Krüppelwalmdach'; formclass : nil),
  (Name : 'Zeltdach'; formclass : nil),
  (Name : 'Turm'; formclass : nil),
  (Name : 'Mansarddach Typ 1'; formclass : nil),
  (Name : 'Mansarddach Typ 2'; formclass : nil),
  (Name : 'Winkelbau'; formclass : nil),
  (Name : '3 Giebel Bau'; formclass : nil),
  (Name : 'T - Bau'; formclass : nil),
  (Name : 'Tonnendach'; formclass : nil)
 );
 
const
 DacheingabeFlachdach : array[flachdachtypen] of dacheingabeformrecty = (
  (Name : 'Rechteckbau'; formclass : nil),
  (Name : 'L - Bau'; formclass : nil),
  (Name : 'H - Bau'; formclass : nil)
 );
 
 DacheingabeGauben : array[gaubentypen] of dacheingabeformrecty = (
  (Name : 'Schleppgaube'; formclass : nil),
  (Name : 'Sattelgaube'; formclass : nil),
  (Name : 'Walmgaube'; formclass : nil),
  (Name : 'Krüppelwalmgaube'; formclass : nil),
  (Name : 'Spitzgaube'; formclass : nil),
  (Name : 'Trapezgaube'; formclass : nil),
  (Name : 'Tonnengaube'; formclass : nil),
  (Name : 'Schweifgaube'; formclass : nil),
  (Name : 'Fledermausgaube'; formclass : nil)
 );
 
type
 Alledachtypenty = array[0..2] of array of dacheingabeformrecty;
 
var
 mainmo: tmainmo;
 Alledachtypen : Alledachtypenty;
implementation
uses
 mainmodule_mfm;
 
initialization
 Alledachtypen[0] := DacheingabeSteildach;
 Alledachtypen[1] := DacheingabeFlachdach;
 Alledachtypen[2] := DacheingabeGauben;
 
end.
 


Der Compiler meckert bei der zweiten Zeile im initialization Teil.
Die erste akzeptiert er!?

Compiling mainmodule.pas
mainmodule.pas(78,22) Error: Incompatible types: got "Array[flachdachtypen] Of dacheingabeformrecty" expected "{Dynamic} Array Of dacheingabeformrecty"
mainmodule.pas(79,22) Error: Incompatible types: got "Array[gaubentypen] Of dacheingabeformrecty" expected "{Dynamic} Array Of dacheingabeformrecty"
mainmodule.pas(82) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted
Error: D:\lazarus\fpc\3.0.0\bin\i386-win32\ppc386.exe returned an error exitcode

Kann mir jemand sagen, wie ich das lösen kann?
Zuletzt geändert von m.fuchs am 26. Sep 2017, 10:14, insgesamt 1-mal geändert.
Grund: richtigen Highlighter ausgewählt
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 26. Sep 2017, 12:11 Re: Frage zu Typdeklaration

Das Problem ist, dass ord(low(DacheingabeFlachdach)) und ord(low(DacheingabeGauben)) nicht Null sind. Falls Delphi die Umwandlung von den Arraykonstanten zu dynamischen Arrays kann, sollte ein Bug-Report unter "Compiler" und mit Hinweis auf Delphi-Kompatibilität gemacht werden:
https://bugs.freepascal.org/my_view_page.php
Es bleibt im Moment nichts anderes übrig, als die Umwandlung im Code vorzunehmen. Etwa so:
Code: Alles auswählen
 
procedure init();
var
 t1: dachtypenty;
 ar1: array of dacheingabeformrecty;
 
begin
 Alledachtypen[0] := DacheingabeSteildach;
 
 setlength(ar1,length(DacheingabeFlachdach));
 for t1:= low(DacheingabeFlachdach) to high(DacheingabeFlachdach) do begin
  ar1[ord(t1)-ord(low(DacheingabeFlachdach))]:= DacheingabeFlachdach[t1];
 end;
 Alledachtypen[1]:= ar1;
 
 setlength(ar1,length(DacheingabeGauben));
 for t1:= low(DacheingabeGauben) to high(DacheingabeGauben) do begin
  ar1[ord(t1)-ord(low(DacheingabeGauben))]:= DacheingabeGauben[t1];
 end;
 Alledachtypen[2]:= ar1;
end;
 
initialization
 init();
end.
 

Edit: setlength() konnte vereinfacht werden.
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 26. Sep 2017, 14:47 Re: Frage zu Typdeklaration

Ich hab es gerade versucht. Delphi macht das auch nicht. Das meckert schon bei der ersten Zeile "inkompatible typen 'array' und 'dynamic array'"

Aber Danke für den Tip. So bekomme ich meine Struktur immerhin initialisiert.
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

Beitragvon braunbär » 26. Sep 2017, 20:11 Re: Frage zu Typdeklaration

Es ist halt ein Krampf, dass dynamische Arrays zwingend mit Index 0 anfangen müssen. Die Einschränkung ist immer wieder lästig, und völlig überflüssig. Speicheradressen richtig umrechnen sollte für einen Compiler wirklich in keinem Fall ein Problem sein.
braunbär
 
Beiträge: 164
Registriert: 8. Jun 2017, 17:21

Beitragvon Mathias » 26. Sep 2017, 20:59 Re: Frage zu Typdeklaration

Es ist halt ein Krampf, dass dynamische Arrays zwingend mit Index 0 anfangen müssen. Die Einschränkung ist immer wieder lästig,

Da bin ich anderer Meinung, ich bin froh, das die immer bei 0 anfangen, ansonsten wird es unübersichtlich und Fehler sind vorprogrammiert.
Ich beginne auch statische Array in der Regel immer bei 0.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3262
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon mse » 27. Sep 2017, 06:19 Re: Frage zu Typdeklaration

Mathias hat geschrieben:Ich beginne auch statische Array in der Regel immer bei 0.

Ich auch. Meiner Meinung nach sollten auch Strings null-basiert sein. Dass das erste Zeichen in Pascal beim Index 1 liegt kommt vermutlich daher, dass im ursprünglichen Pascal-String bei [0] das Längenbyte liegt.
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon m.fuchs » 27. Sep 2017, 08:14 Re: Frage zu Typdeklaration

mse hat geschrieben:
Mathias hat geschrieben:Ich beginne auch statische Array in der Regel immer bei 0.

Ich auch. Meiner Meinung nach sollten auch Strings null-basiert sein.


Eigentlich programmiert man ja deshalb in Pascal (und nicht in C oder Perl) weil man verständlichen Code schreiben will. Warum ist es eurer Meinung nach verständlicher wenn das 1. Element den Index 0 hat?

Code: Alles auswählen
for i := 0 to (Length(MyString) - 1) do
 
(* vs. *)
 
for i := 1 to Length(MyString) do
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1691
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.6, FPC 3.0) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon mse » 27. Sep 2017, 08:33 Re: Frage zu Typdeklaration

Weil man sich beim Programmieren auf ein einziges Indexsystem beschränken sollte. 0 als Start eines Wertebereichs ist universell brauchbar, auch z.B. in Grafik-Koordinatensystemen. Mit 1 oder anderen Startwerten mache ich immer wieder ärgerliche und zum Teil schwer zu findende Fehler.
Code: Alles auswählen
 
for i := 0 to High(MyString) do
 

würde doch auch nicht schlecht aussehen?
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon m.fuchs » 27. Sep 2017, 08:56 Re: Frage zu Typdeklaration

mse hat geschrieben:Weil man sich beim Programmieren auf ein einziges Indexsystem beschränken sollte. 0 als Start eines Wertebereichs ist universell brauchbar, auch z.B. in Grafik-Koordinatensystemen.

Nein, es ist eben nicht universell brauchbar, sondern in bestimmten Fällen. Genauso wie beim Startindex 1. Der bei Strings definitiv sinnvoll ist. Genauso sinnvoll kann er auch bei anderen Anwendungsfällen sein. Das spräche also durchaus dafür, dass auch bei dynamischen Arrays irgendwie ein Startpunkt übergeben werden könnte.

mse hat geschrieben:Mit 1 oder anderen Startwerten mache ich immer wieder ärgerliche und zum Teil schwer zu findende Fehler.

Das tut mir leid, ist aber auch kein Argument. Denn umgekehrt geht es ja vielen auch so mit einem Startindex 0.

mse hat geschrieben:
Code: Alles auswählen
for i := 0 to High(MyString) do 

würde doch auch nicht schlecht aussehen?

Code: Alles auswählen
for i := Low(Wasauchimmer) to High(Wasauchimmer) do

Das wäre doch dann die Lösung für alle Probleme.

Es gibt einfach für beides gute Gründe.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1691
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.6, FPC 3.0) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon mse » 27. Sep 2017, 09:11 Re: Frage zu Typdeklaration

m.fuchs hat geschrieben:Es gibt einfach für beides gute Gründe.

Ich habe sowohl das 1- als auch das 0-System intensiv angewendet. Über alles gesehen überwiegen die Vorteile des 0-Systems bei weitem und meiner Meinung nach sollte man Programmier-Anfängern von Anfang an das 0-System beibringen.
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon braunbär » 27. Sep 2017, 23:57 Re: Frage zu Typdeklaration

Definitiv nein.
Felder sollten den natürlichen, der Aufgabenstellung entsprechenden Indexbereich haben, das kann manchmal 0 als Anfang haben, meistens 1 und manchmal etwas ganz anderes, wie in diesem Beispiel des TE. Dann macht man auch keine "schwer zu findenden Fehler".
Der Sinn einer HÖHEREN Programmiersprache liegt darin, dass der Programmcode der Anwendung angepasst ist, und dass man nicht ums Eck denken muss, wenn man den Code schreibt und den Code liest. Und der Sinn des Programmieren Lernens besteht nicht darin, sich sein Denken von Anfang an so verbiegen zu lassen, dass man nachher gar nicht mehr merkt, wie verbogen man denkt. Das erste Element eines Feldes standardmäßig mit 0 zu nummerieren, setzt schon ein ordentlich verbogenes Denken voraus.
Und im Beispiel des TE ist völlig klar, dass es wesentlich einfacher und lesbarer wäre, wenn die Felder nicht zwangsweise mit dem Index 0 anfangen müssten.

Wer unbedingt alles bei 0 anfangen lassen will, könnte das bei variablen Feldgrenzen genauso wie jetzt. Behindert werden nur die, die das nicht wollen. Zum "froh sein" über eine derartige Einschränkung besteht also überhaupt kein Anlass.
braunbär
 
Beiträge: 164
Registriert: 8. Jun 2017, 17:21

Beitragvon fliegermichl » 28. Sep 2017, 07:33 Re: Frage zu Typdeklaration

Sehe ich auch so weil
Code: Alles auswählen
 
Showmessage(Alledachtypen[1][dtRechteckbau].Name);
 


ergibt eine Fehlermeldung weil das dynamische Array meinen Indextyp nicht mehr akzeptiert.

Überhaupt ist die "Typsicherheit" in Pascal oft eher Typgefangenheit.
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

Beitragvon fliegermichl » 28. Sep 2017, 07:50 Re: Frage zu Typdeklaration

Ich würde das Array Alledachtypenty ja auch statisch deklarieren aber wie?
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 28. Sep 2017, 08:07 Re: Frage zu Typdeklaration

Warum brauchst du denn für die Definition des Eingabeformulars drei verschiedene Arrays? "array[dachtypenty] of dacheingabeformrecty" wäre doch ausreichend?
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 28. Sep 2017, 09:20 Re: Frage zu Typdeklaration

Es sind ja alles erst mal Dachtypen.
Bei der Oberfläche werden die aber unterschieden.

Ich hab ein ttabwidget mit 3 ttabpages. Steildächer, Flachdächer und Gauben. Um nun die richtigen Buttons auf die jeweilige Seite zu bekommen und das jeweils passende Eingabeformular laden zu können wollte ich mit
AlledachTypen[ttabwidget1.activepage.tag][sender.tag].formclass usw. zugreifen.

Kann man in Pascal ein mehrdimensionales Array mit unterschiedlich langen Reihen definieren?

mit php ist sowas ganz einfach
Code: Alles auswählen
 
 alledachtypen = array("Steildaecher" -> array("Pultdach", "Satteldach"...),
                                "Flachdaecher" -> array("Rechteckbau", "L Bau"...),
                                "Gauben" -> array("Schleppgaube", "Sattelgaube"...);
 


wobei die Dachtypen hier jetzt der Übersichtlichkeit wegen Strings sind. Die können natürlich auch wieder Arrays oder andere Datentypen sein.
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu MSEide und MSEgui



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried