Im Set of die Reihenfolge erkennen (gelöst) Danke

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Ralph59
Beiträge: 145
Registriert: So 22. Mär 2009, 07:48
OS, Lazarus, FPC: WIN 11 (momentan )
CPU-Target: 64 und 32Bit
Wohnort: Hessen
Kontaktdaten:

Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von Ralph59 »

Hallo,

ich weiß ja, wahrscheinlich schon wieder eine ziemlich einfache Frage :oops:

Ich habe folgende Typen erstellet:

Code: Alles auswählen

type
 
  TMeinTest = (c1, c2, c3, c4, c5, c6);
  TSetMeinTest = Set of TMeinTest;
eine kleine Testprozedut geschrieben:

Code: Alles auswählen

procedure ShowInfoGrid(cTest: TSetMeinTest) overload;
 
begin
  if c1 in cTest then ShowMessage('C1');
  if c2 in cTest then ShowMessage('C2');
  if c3 in cTest then ShowMessage('C3');
  if c4 in cTest then ShowMessage('C4');
  if c5 in cTest then ShowMessage('C5');
  if c6 in cTest then ShowMessage('C6');
end;
Natürlich gibt es auch einen Aufruf der Prozedur

Code: Alles auswählen

ShowInfoGrid([c5, c3, c4]);
So weit, so einfach, nun würde ich allerdings gerne wissen, in welcher Reihenfolge cTest an die Prozedur übergeben wurde :?:

Habe hierzu allerdings nichts gefunden, vielleicht hat ja jemand eine Idee. Mir geht es nach möglichkeit darum, dass ich folgendes nicht machen muss (der Einfachheit halber schreibe ich nur den Aufruf:

Code: Alles auswählen

var
  Testarray: Array[0..6] of integer;
  // oder
  TestArray: Array[0..6] of string;  //wobei das mit den Strings in Set of auch nicht funktionier
 
begin
  TestArray[0] := 1;
  TestArray[1] := 2;
  TestArray[2] := 4;
  ...
 
  ShowInfoGrid(TestArray);
...
Mit freundlichem Gruß

Ralph
Zuletzt geändert von Ralph59 am Sa 30. Okt 2010, 18:22, insgesamt 1-mal geändert.
Fehler sind wie Berge, man steht auf dem Gipfel seiner eigenen und redet über die der anderen.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Im Set of die Reihenfolge erkennen

Beitrag von pluto »

Du müsstest mit ord den Wert(Index) rauß bekommen, wenn ich dich richtig verstanden habe.

edit01:
Also Praktisch so:

Code: Alles auswählen

procedure ShowInfoGrid(cTest: TSetMeinTest) overload;
 
begin
 ShowMessage(InttOStr(ORD(cTest))); 
 
{  if c1 in cTest then ShowMessage('C1');
  if c2 in cTest then ShowMessage('C2');
  if c3 in cTest then ShowMessage('C3');
  if c4 in cTest then ShowMessage('C4');
  if c5 in cTest then ShowMessage('C5');
  if c6 in cTest then ShowMessage('C6');}
end;
MFG
Michael Springwald

Ralph59
Beiträge: 145
Registriert: So 22. Mär 2009, 07:48
OS, Lazarus, FPC: WIN 11 (momentan )
CPU-Target: 64 und 32Bit
Wohnort: Hessen
Kontaktdaten:

Re: Im Set of die Reihenfolge erkennen

Beitrag von Ralph59 »

Hallo Pluto,

leider funktioniert das nicht so einfach, dabei bekomme ich folgenden Fehler:
  • Error: Ordinal expression expected,
da in cTest ja letztendlich nicht nur ein Wert steht.

So gibt z.B.

Code: Alles auswählen

ShowMessage(InttOStr(Ord(true)));  //Ausgabe 1
ShowMessage(InttOStr(Ord(1)));     //Ausgabe 1
ShowMessage(InttOStr(Ord('a')));   //Ausgabe 97
zurück.

Hast du vielleicht noch eine andere Idee?

Mit freundlichem Gruß

Ralph
Fehler sind wie Berge, man steht auf dem Gipfel seiner eigenen und redet über die der anderen.

Benutzeravatar
theo
Beiträge: 10894
Registriert: Mo 11. Sep 2006, 19:01

Re: Im Set of die Reihenfolge erkennen

Beitrag von theo »

Ein Set ist kein Array. Es hat keine Reihenfolge. Ein Element ist enthalten oder eben nicht.
Genauso wie es dem Integer i egal ist ob du:
i:=1+2+4 oder
i:=2+1+4 schreibst.
Zuletzt geändert von theo am Sa 30. Okt 2010, 17:01, insgesamt 1-mal geändert.

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: Im Set of die Reihenfolge erkennen

Beitrag von mse »

Sets sind Bitfelder, die Reihenfolge der Elemente im Procedureparameter ist irrelevant. Der Compiler verwendet immer die Nummerierungsreihenfolge zur Bestimmung der Bitposition.
Nimm ein "array of TMeinTest" falls die Reihenfolge der Werte massgebend ist.

Ralph59
Beiträge: 145
Registriert: So 22. Mär 2009, 07:48
OS, Lazarus, FPC: WIN 11 (momentan )
CPU-Target: 64 und 32Bit
Wohnort: Hessen
Kontaktdaten:

Re: Im Set of die Reihenfolge erkennen

Beitrag von Ralph59 »

Hallo,

so ähnlich habe ich mir das schon gedacht. In diesem Fall werde ich dann leider auf ein Array zurückgreifen müssen, wobei der Nachteil darin besteht,
dass das Array in der aufrufenden Prozedur bereits vorhanden sein muss, damit dieses übergeben werden kann.
Vielleicht verwende ich auch optionale Parameter über overload.

Ein Aufruf von

Code: Alles auswählen

ShowInfoGrid([c5, c3, c4]);
oder
ShowInfoGrid([2, 4, 6]);
oder 
ShowInfoGrid(['Test1','Test2','Test3']);
ist dann nicht möglich. :(

Trotzdem vielen Dank für den kleinen Kurs :wink:


Mit freundlichem Gruß

Ralph
Fehler sind wie Berge, man steht auf dem Gipfel seiner eigenen und redet über die der anderen.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Im Set of die Reihenfolge erkennen

Beitrag von pluto »

Vielleicht hilft hier die RTTI weiter:
GetEnumProp(ComboBox2.canvas.Brush,'style')

Ich glaube diese Funktion ist in "typinfo" drin. Der Erste Parameter ist eine Klasse und der Zweite ist die Eigenschaft.

edit01:
ist dann nicht möglich

Natürlich ist das Möglich:

Code: Alles auswählen

function Test(testItemst:array of Integer);
....
 
Aufruf mit test([0,0,0]);
Das ganze kannst du auch als Array of Const machen dann hast du sowas wie bei Format.
MFG
Michael Springwald

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: Im Set of die Reihenfolge erkennen

Beitrag von mse »

Ralph59 hat geschrieben:In diesem Fall werde ich dann leider auf ein Array zurückgreifen müssen, wobei der Nachteil darin besteht,
dass das Array in der aufrufenden Prozedur bereits vorhanden sein muss, damit dieses übergeben werden kann.
Nicht bei einem "offener Array Parameter".

Code: Alles auswählen

type
 TMeinTest = (c1, c2, c3, c4, c5, c6);
procedure testproc(par: array of tmeintest);
 begin
 end;
[...]
testproc([c5,c1,c2]);

Ralph59
Beiträge: 145
Registriert: So 22. Mär 2009, 07:48
OS, Lazarus, FPC: WIN 11 (momentan )
CPU-Target: 64 und 32Bit
Wohnort: Hessen
Kontaktdaten:

Re: Im Set of die Reihenfolge erkennen

Beitrag von Ralph59 »

Hallo,

noch mal vielen Dank, funktioniert alles.

Ich verstehe zwar nicht, warum das mit den Array's vorher bei mir nicht funktioniert hatte, aber es ist müßig darüber nachzudenken.

Code: Alles auswählen

procedure ShowInfoGrid(cTest: Array of TMeinTest) overload;
begin
  ShowMessage(inttostr( High(cTest)));
end;
 
procedure ShowInfoGrid(par: Array of Integer) overload;
var
  i: Integer;
begin
  for i := 0 to High(par) do ShowMessage(IntToStr(par[i]));
end;
 
procedure ShowInfoGrid(par: Array of String) overload;
var
  i: Integer;
begin
  for i := 0 to High(par) do ShowMessage(par[i]);
end;
Danke, Danke, Danke --> Ein Bier für euch beide :D

Mit freundlichem Gruß

Ralph
Fehler sind wie Berge, man steht auf dem Gipfel seiner eigenen und redet über die der anderen.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von pluto »

Du kannst auch die Funktion Length Verwenden wobei du hier dann ein -1 hinterschreiben müsstest.
MFG
Michael Springwald

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: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von mse »

pluto hat geschrieben:Du kannst auch die Funktion Length Verwenden wobei du hier dann ein -1 hinterschreiben müsstest.
Tipp: high() ist in FPC für dynamische arrays ein wenig schneller als length().

Code: Alles auswählen

function fpc_dynarray_length(p : pointer) : tdynarrayindex;[Public,Alias:'FPC_DYNARRAY_LENGTH']; compilerproc;
  begin
     if assigned(p) then
       fpc_dynarray_length:=pdynarray(p-sizeof(tdynarray))^.high+1
     else
       fpc_dynarray_length:=0;
  end;

Code: Alles auswählen

function fpc_dynarray_high(p : pointer) : tdynarrayindex;[Public,Alias:'FPC_DYNARRAY_HIGH']; compilerproc;
  begin
     if assigned(p) then
       fpc_dynarray_high:=pdynarray(p-sizeof(tdynarray))^.high
     else
       fpc_dynarray_high:=-1;
  end;
Auch bei offenen Array Parametern braucht length() einen Befehl mehr als high().
Noch ein Bier? ;-)

Martin

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von pluto »

Danke für den Hinweis. Ich Trinke kein Alkohol *G* Aber du kannst dir gerne noch eins Nehmen, nichts da gegen..... :D

Wobei mir noch nicht ganz klar ist warum es einen Zeitlichen Unterschied zwischen den beiden Funktionen gibt. Im Grunde machen die doch genau das gleiche.
MFG
Michael Springwald

Ralph59
Beiträge: 145
Registriert: So 22. Mär 2009, 07:48
OS, Lazarus, FPC: WIN 11 (momentan )
CPU-Target: 64 und 32Bit
Wohnort: Hessen
Kontaktdaten:

Re: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von Ralph59 »

Hallo ihr beiden,

ich glaube, ich werde mich dazu hinreißen lassen, sowohl eins, zwei Cola als auch ein oder zwei Bier auszugeben.

Beim nächsten Lazarus Treffen :?:

Bis dahin habe ich dann ja auch noch ein wenig Zeit etwas programmieren zu lernen und mich mit FPC tiefer zu befassen :wink:

Mit freundlichem Gruß

Ralph
Fehler sind wie Berge, man steht auf dem Gipfel seiner eigenen und redet über die der anderen.

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: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von mse »

pluto hat geschrieben: Wobei mir noch nicht ganz klar ist warum es einen Zeitlichen Unterschied zwischen den beiden Funktionen gibt. Im Grunde machen die doch genau das gleiche.
Der Unterschied ist hier:

Code: Alles auswählen

length():
       fpc_dynarray_length:=pdynarray(p-sizeof(tdynarray))^.high+1
high():
       fpc_dynarray_high:=pdynarray(p-sizeof(tdynarray))^.high
Für dynamische Arrays wird folgender Speicherblock angelegt:

Code: Alles auswählen

type
{$ifdef CPU64}
  SizeInt = Int64;
{$endif CPU64}
 
{$ifdef CPU32}
  SizeInt = Longint;
{$endif CPU32}
 
{$ifdef CPU16}
  SizeInt = Integer;
{$endif CPU16}
 
  tdynarrayindex = sizeint;
 
   tdynarray = packed record
      refcount : ptrint;
      high : tdynarrayindex;
     //danach folgen die array daten
     //wert[0] <<<<-----der pointer wert der dynamischen array variable zeigt hierhin
     //wert[1]
     //...
     //wert[<high>]
   end;
In tdynarray.high wird der Index des letzten Elements abgelegt. length() muss also zusätzlich 1 addieren was ein wenig Zeit kostet.
Zuletzt geändert von mse am So 31. Okt 2010, 16:10, insgesamt 1-mal geändert.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Im Set of die Reihenfolge erkennen (gelöst) Danke

Beitrag von pluto »

Du meinst das +1 macht so viel aus ? Meistens ist dann noch ein -1 notwendig. Also gleich die andere Funktion nehmen.
MFG
Michael Springwald

Antworten