Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Variable für const array (https://www.delphipraxis.net/193980-variable-fuer-const-array.html)

Benmik 1. Okt 2017 17:00

Variable für const array
 
Ich habe mehrere Arrays eines selbst definiertes Typs, die als Konstanten deklariert sind.
Je nach Bedarf möchte ich eins der Arrays an eine Funktion verfüttern.

Es gelingt mir aber nicht, eine Variable zu definieren, der ich so ein konstantes Array zuweisen und dann als Parameter an die Funktion senden könnte, da eine solche Variable ja als dynamische Variable deklariert werden muss (die Länge ist ja je nach const array verschieden), aber die Arrays eben const sind, und das ist mit dem Compiler nicht zu machen.
Ich habe mir unter anderem dies hier zu Gemüte geführt, aber mein Problem löst das nicht. Auch mit Generics kriege ich das nicht hin.

Ich vermute mal stark, dass ihr das aus dem Ärmel schüttelt.

Übrigens geht es um eine Enumeration mit mehr als 256 Items, und ich möchte feststellen, ob ein bestimmtes Item dieser Enumeration in einem konstanten Subset vorhanden ist.

Delphi-Laie 1. Okt 2017 21:19

AW: Variable für const array
 
Zitat:

Zitat von Benmik (Beitrag 1382411)
Ich vermute mal stark, dass ihr das aus dem Ärmel schüttelt.

Anscheinend nicht, denn bisher antwortete niemand.

Gib doch mal am besten ausreichend Quelltext preis und markiere die Zeile, in der der Compiler stehenbleibt, und gib auch die Compilermeldung mit an.

Das alles sagt mehr als tausend (Deiner) Wörter.

Redeemer 1. Okt 2017 22:12

AW: Variable für const array
 
Ich habe keine Ahnung, wo das Problem sein soll, denn ich verwende derzeit konstante Arrays eines Records in meinem SVG-Interpreter, da für einen XPM-Interpreter auch X11-Farben benötigt werden:
Delphi-Quellcode:
type
  TColorName = record
    Color: TColor;
    Name: string;
  end;

function HTMLToColor(HTML: string; out Color: TColor; const ColorNames: array of TColorName): Boolean;

const
  CSSColors: array[0..146] of TColorName = ((Color: $00FFF8F0; Name: 'aliceblue'),
  (* here be 145 dragons *)
                                            (Color: $0032CD9A; Name: 'yellowgreen'));

implementation

begin
  HTMLToColor('rebeccapurple', tempcolor, CSSColors); // funktioniert einwandfrei
end;
Wenn's gar nicht anders geht:
Delphi-Quellcode:
packed array
s mit Pointern verwenden wie Windows das macht. Aber das sollte doch eigentlich ganz normal gehen.

Benmik 2. Okt 2017 13:29

AW: Variable für const array
 
War natürlich ein Fehler, keinen Beispielcode mitzuliefern.
Delphi-Quellcode:
type
  TEnum =(eEins,eZwei,eDrei,eVier,eFünf,eSechs,eSieben,eAcht,eNeun,eZehn);
const
  Enum1 : array[0..4] of TEnum = (eEins,eDrei,eSechs,eSieben,eZehn);
  Enum2 : array[0..6] of TEnum = (eZwei,eVier,eFünf,eSechs,eAcht,eNeun,eZehn);

function IstDrin(VarE:TEnum;const AEnum:array of TEnum):Boolean;
var VEnum:TEnum;
begin
  Result := False;
  For VEnum in AEnum do
    If VEnum = VarE
      then exit(True);
end;

procedure MachWas(AEnumNr:integer);
var i:integer; AEnum:array of TVarEnum;
begin
  case AEnumNr of
    1  : AEnum := Enum1;
    2  : AEnum := Enum2;
  end;
  If IstDrin(eDrei,AEnum)
    then ... ;
end;
Der Knackpunkt ist
Delphi-Quellcode:
AEnum := Enum1
. Der Compiler sagt (zu Recht), dass ein
Delphi-Quellcode:
array[0..4] of TEnum
nicht das Gleiche ist wie ein dynamisches Array von TEnum.
Ich suche eine Möglichkeit, die verschiedenen Enum1..Enum10 mit einer Variable an die Funktion zu übergeben.

Mavarik 2. Okt 2017 13:34

AW: Variable für const array
 
emm...

Delphi-Quellcode:
Setlength(AEnum,length(Enum1))
For i:=0 to high(Enum1) do
  AEnum[i] := Enum1[i];

Benmik 2. Okt 2017 13:49

AW: Variable für const array
 
Äh... das habe ich vornehm ausgelassen.
Die Möglichkeit ist mir schon bewusst.
Ich habe mich dummerweise darauf verbissen herauszukriegen, wie man diese Zuweisung hinbekommt.
Ich gestehe also, dass ich nicht ratlos bin, wie man das überhaupt macht, sondern dass ich nicht verstehe, wie man hier mit Delphi umgeht.
Schuld ist natürlich dieser elegante Code, der hier dauernd gepostet wird.

BerndS 2. Okt 2017 13:51

AW: Variable für const array
 
Oder so, ich habe es aber nicht getestet...
Delphi-Quellcode:
type
  TEnum = (eEins, eZwei, eDrei, eVier, eFünf, eSechs, eSieben, eAcht, eNeun, eZehn);
  TEnumArray = array of TEnum;
  PEnumArray = ^TEnumArray;

const
  Enum1: array [0 .. 4] of TEnum = (eEins, eDrei, eSechs, eSieben, eZehn);
  Enum2: array [0 .. 6] of TEnum = (eZwei, eVier, eFünf, eSechs, eAcht, eNeun, eZehn);

function IstDrin(VarE:TEnum;const AEnum: TEnumArray):Boolean;
var VEnum:TEnum;
begin
  Result := False;
  For VEnum in AEnum do
    If VEnum = VarE
      then exit(True);
end;

procedure MachWas(AEnumNr:integer);
var
AEnum: PEnumArray;
begin
  case AEnumNr of
    1 : AEnum := @Enum1;
    2 : AEnum := @Enum2;
    else
      Exit;
  end;
  If IstDrin(eDrei,AEnum^)
    then ;
end;

Uwe Raabe 2. Okt 2017 14:07

AW: Variable für const array
 
Zumindest in Berlin/Tokyo kannst du es so machen:
Delphi-Quellcode:
type
  TEnum = (eEins, eZwei, eDrei, eVier, eFünf, eSechs, eSieben, eAcht, eNeun, eZehn);

  TEnumArr = TArray<TEnum>;

const
  Enum1: TEnumArr = [eEins, eDrei, eSechs, eSieben, eZehn];
  Enum2: TEnumArr = [eZwei, eVier, eFünf, eSechs, eAcht, eNeun, eZehn];

function IstDrin(VarE: TEnum; const AEnum: TEnumArr): Boolean;
var
  VEnum: TEnum;
begin
  Result := False;
  For VEnum in AEnum do
    If VEnum = VarE then
      exit(True);
end;

procedure MachWas(AEnumNr: integer);
var
  i: integer;
  AEnum: TEnumArr;
begin
  case AEnumNr of
    1:
      AEnum := Enum1;
    2:
      AEnum := Enum2;
  end;
  If IstDrin(eDrei, AEnum) then;
end;

Mavarik 2. Okt 2017 14:16

AW: Variable für const array
 
Mit dem Pointer finde ich auch nicht so schön...

Enum1 und Enum2 sind ja wie globale Variablen...

Also warum nicht auch so benutzen...

Delphi-Quellcode:
Enum1,
Enum2 : Array of TEnum;

Procedure Init
begin
  Enum1 := [eEins, eDrei, eSechs, eSieben, eZehn];
  Enum2 := [eZwei, eVier, eFünf, eSechs, eAcht, eNeun, eZehn] ;
end;
Müsste doch auch gehen... Hab gerade keinen Compiler... :stupid:

Benmik 2. Okt 2017 14:36

AW: Variable für const array
 
@BerndS:
Auf die Zeigeridee war ich auch schon gekommmen, konnte es aber nicht umsetzen.
Dies hier funktioniert auch nicht.
Zum einen geht For..in nicht, was nicht weiter schlimm ist.
Aber in
Delphi-Quellcode:
AEnum^
steht nur Unsinn, tausend Werte, alle außerhalb des Bereichs?
Warum ist das so?

@Uwe:
Und auch das hatte ich probiert. Ich hoffe, ich habe jetzt keinen Flüchtigkeitsfehler begangen, aber der Compiler sagt bei
Delphi-Quellcode:
AEnum := Enum1;
: "Inkompatible Typen: TArray<TEnum> und array[0..4] of TEnum.


Haaaalt, alles zurück! Ich hatte das
Delphi-Quellcode:
Enum1: TEnumArr = [eEins, eDrei, eSechs, eSieben, eZehn];
nicht angepasst!
So geht es. Wie konnte ich daran zweifeln.
Danke!

Uwe Raabe 2. Okt 2017 14:40

AW: Variable für const array
 
Zitat:

Zitat von Benmik (Beitrag 1382493)
@Uwe:
Und auch das hatte ich probiert. Ich hoffe, ich habe jetzt keinen Flüchtigkeitsfehler begangen, aber der Compiler sagt bei
Delphi-Quellcode:
AEnum := Enum1;
: "Inkompatible Typen: TArray<TEnum> und array[0..4] of TEnum.

Dann weicht dein Code noch irgendwo von meinem ab. Dort gibt es nämlich nirgendwo ein
Delphi-Quellcode:
array[<irgendwas>] of
.

Benmik 2. Okt 2017 15:00

AW: Variable für const array
 
Wie schon geschrieben, du hast Recht. Danke dir.

Benmik 2. Okt 2017 17:42

AW: Variable für const array
 
Darf ich noch fragen, warum die Lösung von BerndS nicht funktioniert?

Redeemer 2. Okt 2017 20:50

AW: Variable für const array
 
Noch 'ne Variante:
Delphi-Quellcode:
type
  TEnum =(eEins,eZwei,eDrei,eVier,eFünf,eSechs,eSieben,eAcht,eNeun,eZehn);
type
  TEnumarray = packed array[0..4711] of TEnum;
const
  Enum1 : packed array[0..4] of TEnum = (eEins,eDrei,eSechs,eSieben,eZehn);
  Enum2 : packed array[0..6] of TEnum = (eZwei,eVier,eFünf,eSechs,eAcht,eNeun,eZehn);


function IstDrin(VarE:TEnum;const AEnum: TEnumarray; Size: Integer):Boolean;
var
i: Integer;
begin
  Result := False;
  For i := 0 to Size - 1 do
    If AEnum[i] = VarE
      then exit(True);
end;

procedure MachWas(AEnumNr:integer);
var
  i:integer;
  AEnum: ^TEnumarray;
  ASize: Integer;
begin
  case AEnumNr of
    1: begin
         AEnum := @Enum1;
         ASize := Length(Enum1);
    end;
    2: begin
         AEnum := @Enum2;
         ASize := Length(Enum2);
    end;
  end;
  If IstDrin(eSieben,AEnum^, ASize) then
  writeln('ist drin');
end;

Uwe Raabe 2. Okt 2017 22:05

AW: Variable für const array
 
Zitat:

Zitat von Benmik (Beitrag 1382513)
Darf ich noch fragen, warum die Lösung von BerndS nicht funktioniert?

Weil ein Pointer auf ein dynamisches Array nicht mit einem Pointer auf ein statisches Array kompatibel ist. Ein dynamisches Array ist selbst schon ein Pointer auf den Array-Speicher mit einem Verwaltungsblock davor. Dieser Block fehlt bei einem statischen Array, deswegen kann man keinen Pointer auf ein statisches Array verwenden, wenn ein dynamisches erwartet wird - selbst wenn man versucht, die Pointer auszutricksen und womöglich noch hard-zu-casten. Das ist in den aktuellen Delphi-Versionen ja wie gezeigt auch nicht nötig.

Benmik 2. Okt 2017 22:59

AW: Variable für const array
 
Du liebe Zeit. Auf sowas soll man kommen. Danke.

BerndS 4. Okt 2017 06:24

AW: Variable für const array
 
Ja, da hätte ich es doch besser vorher testen sollen, was ich nachträglich noch gemacht habe.
Allerdings hätte ich es wahrscheinlich den Beispielprojekt nicht mit einem Array sondern per Set gemacht.
Delphi-Quellcode:
type
  TEnum = (eEins, eZwei, eDrei, eVier, eFünf, eSechs, eSieben, eAcht, eNeun, eZehn);
  TEnumSet = set of TEnum;

const
  Enum1 = [eEins, eDrei, eSechs, eSieben, eZehn];
  Enum2 = [eZwei, eVier, eFünf, eSechs, eAcht, eNeun, eZehn];

function IstDrin(VarE:TEnum;const AEnum: TEnumSet):Boolean;
var VEnum:TEnum;
begin
  Result := False;
  For VEnum in AEnum do
    If VEnum = VarE
      then exit(True);
end;

procedure MachWas(AEnumNr:integer);
var
AEnum: TEnumSet;
begin
  case AEnumNr of
    1 : AEnum := Enum1;
    2 : AEnum := Enum2;
    else
      Exit;
  end;
  If IstDrin(eDrei,AEnum)
    then ;
end;

Uwe Raabe 4. Okt 2017 07:35

AW: Variable für const array
 
Zitat:

Zitat von BerndS (Beitrag 1382538)
Allerdings hätte ich es wahrscheinlich den Beispielprojekt nicht mit einem Array sondern per Set gemacht.

Das ist aber nicht immer möglich: Im Gegensatz zu einem Set kann in einem Array ein Element mehrfach vorkommen und die Elemente können in bestimmter Weise angeordnet sein.

Benmik 6. Okt 2017 19:06

AW: Variable für const array
 
Die Variante gefällt mir aber auch gut.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:40 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