Frage zu Typdeklaration

Forum für alles rund um die MSEide und MSEgui
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Frage zu Typdeklaration

Beitrag von fliegermichl »

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 Di 26. Sep 2017, 11:14, insgesamt 1-mal geändert.
Grund: richtigen Highlighter ausgewählt

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Typdeklaration

Beitrag von mse »

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.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Frage zu Typdeklaration

Beitrag von fliegermichl »

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.

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Frage zu Typdeklaration

Beitrag von braunbär »

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.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Frage zu Typdeklaration

Beitrag von Mathias »

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 grün
Mit Java und C/C++ sehe ich rot

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Typdeklaration

Beitrag von mse »

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.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Frage zu Typdeklaration

Beitrag von m.fuchs »

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

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Typdeklaration

Beitrag von mse »

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?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Frage zu Typdeklaration

Beitrag von m.fuchs »

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

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Typdeklaration

Beitrag von mse »

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.

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Frage zu Typdeklaration

Beitrag von braunbär »

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.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Frage zu Typdeklaration

Beitrag von fliegermichl »

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.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Frage zu Typdeklaration

Beitrag von fliegermichl »

Ich würde das Array Alledachtypenty ja auch statisch deklarieren aber wie?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Frage zu Typdeklaration

Beitrag von mse »

Warum brauchst du denn für die Definition des Eingabeformulars drei verschiedene Arrays? "array[dachtypenty] of dacheingabeformrecty" wäre doch ausreichend?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Frage zu Typdeklaration

Beitrag von fliegermichl »

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.

Antworten