Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Bedingte Variable (https://www.delphipraxis.net/199105-bedingte-variable.html)

markus888 24. Dez 2018 07:37

Bedingte Variable
 
Wie kann ich eine bedingte Variable erzeugen:
Abhängig von einem übergebenen Wert soll der Typ einer Variable bestimmt werden.

Code:
procedure test(const x:Integer);
var
if x=1 then
  p:Integer
else if x=2 then
  p:Byte;

begin

end;

H.Bothur 24. Dez 2018 07:50

AW: Bedingte Variable
 
Moin,

1) Ich habe keine Ahnung
2) warum willst Du das machen ? Zumindestens in deinem Beispiel könnte man doch immer Int nehmen, oder ?

Gruß
Hans

uligerhardt 24. Dez 2018 07:56

AW: Bedingte Variable
 
Genau so, wie du es willst, geht es nicht. Aber es gibt zig ähnliche Möglichkeiten:
  • Variants
  • Zeiger - etwa mit "p: Pointer" und pro Fall unterschiedlichen Aufrufen von "New".
  • Pro Fall eine eigene Unterroutine mit passend typiertem p
  • Wenn es wirklich um Integer und Byte geht, nimm einfach immer den größten Typ (Integer oder Int64).

Edit: Vielleicht lässt sich in Rio sogar was mit inline-Variablen machen? Dürfen da Namen doppelt vergeben werden?

p80286 24. Dez 2018 08:28

AW: Bedingte Variable
 
Wofür soll das gut sein?
Falls die Typen sich eigentlich ausschließen - Char und Byte z.B. - ist der Denkansatz ggf. der falsche, falls es um unterschiedliche Wertebereiche handelt - Byte und Word- läßt sich bestimmt der richtige Weg finden.

Gruß
K-H

Schokohase 24. Dez 2018 09:10

AW: Bedingte Variable
 
Es gibt die Variante Teile in Record-Typen

Ob die hier passend wären kann man ohne weitergehenden Kontext nicht beantworten.

markus888 24. Dez 2018 09:15

AW: Bedingte Variable
 
Was ich konkret machen will:

Ich greife per Pointer auf die Elemente eines SafeArray zu - die Elemente sind vom Typ Variant.
Darin enthalten sich immer Daten eines Types -> diverse Integer, Currency, Gleitkommazahlen usw.
Für den Zugriff möchte ich Pointer auf verschiedene Record Typen verwenden, die den direkten Zugriff auf die enthaltenen Daten ermöglichen.

Zwischenzeitlich kam die Antwort mit dem varianten Teil im Record.
Das könnte eine ideale Lösung sein.
LG Markus

Edit:
Ein simples Beispiel für zwei Typen:

Code:

  TVarInteger = record
    Typ:Word;
    T1:Word;
    T2:Integer;
    Data: integer;
    T3: integer;
    end;

  TVarCur = record
    Typ:Word;
    T1:Word;
    T2:Integer;
    Data: Currency;
    end;
Es sind immer nur Typ und Data von Bedeutung.
Ich brauche dann immer - abhängig vom übergebenen Wert einen Pointer auf eine von mehreren möglichen Strukturen.

Wie könnte ich das ideal anstellen?

HeZa 24. Dez 2018 09:46

AW: Bedingte Variable
 
Zitat:

Zitat von markus888 (Beitrag 1421987)
Wie kann ich eine bedingte Variable erzeugen:
Abhängig von einem übergebenen Wert soll der Typ einer Variable bestimmt werden.

Bestimme nicht den Typ der Variablen, sondern weche Methode aufzurufen ist.

Delphi-Quellcode:
procedure TuEtwasMitArray(const TypeCode: Integer);
begin
  case TypeCode of
    1: TuEtwasMitIntegerArray;
    2: TuEtwasMitByteArray;
    else raise EInvalidOperation.CreateFmt('Unknown TypeCode %d', x);
  end;
begin

procedure TuEtwasMitIntegerArray;
var
  p: Integer;
begin
  ...
end;

procedure TuEtwasMitByteArray;
var
  p: Byte;
begin
  ...
end;
Wie du auf das Array zugreifen willst hast du uns ja noch nicht gezeigt.

markus888 24. Dez 2018 09:53

AW: Bedingte Variable
 
Zitat:

Zitat von HeZa (Beitrag 1422011)
Wie du auf das Array zugreifen willst hast du uns ja noch nicht gezeigt.

Sorry, ich übermittle das erste Array-Element als Pointer an die Prozedur und bewege mich mittels inc() durch die Elemente.
Das wesentliche was die Codes unterscheidet sind Zeiger auf verschiedene Records.

HeZa 24. Dez 2018 12:01

AW: Bedingte Variable
 
Zitat:

Zitat von markus888 (Beitrag 1422013)
Zitat:

Zitat von HeZa (Beitrag 1422011)
Wie du auf das Array zugreifen willst hast du uns ja noch nicht gezeigt.

Sorry, ich übermittle das erste Array-Element als Pointer an die Prozedur und bewege mich mittels inc() durch die Elemente.
Das wesentliche was die Codes unterscheidet sind Zeiger auf verschiedene Records.

Willst du mit den Datentypen Integer, Byte, Currency, Gleitkomma immer das gleiche machen?

Wenn ja müsstes du die ja wahrscheinlich in einen gemeinsamen Datentypen wandeln? Dann über gib deiner Prozedure ein Zugriffsobjekt (Enumerator), den du abhängig vom Datentype erzeugst. Der übernimmt das Ermitteln der Werte aus dem Array und ein evt. wandel des Array-Typen in den von Dir benötigten Typen. Dann kann die Logik deiner Prozedure die die Arbeit erledigt immer gleich bleiben und wird von dem Typen-Chaos nicht behelligt.

Wenn du unterschiedliche Sachen machen möchtest nimm unterschiedliche Prozeduren.

MichaelT 25. Dez 2018 23:38

AW: Bedingte Variable
 
In dem Record steht die Typinformation und ein Wert oder ein Pointer auf einen weiteren Verbund (record)?

Pfui. Aber ich weiß eh.

An sich wäre die Entsprechung zu dem konkreten Beispiel die Verwendung eines Variant und die Varablendeklaration der Syntactic Sugar.

In einer statisch typisierten Sprache ein Array mit Elementen unterschiedlichen Typs zu befüllen mutet eher seltsam an. Konsekutive Listen leben wie der Name schon sagt von lückenlos zusammenhängend und der Ermittlung der Position durch Erhöhung der Adresse um die Länge des beinhalteten Datentyps.

Alles andere ist eine beliebige Liste die aber seit den 90ern gerne in Arrays verpackt wird und deswegen gesellt sich an sich gerne ein Record hinzu. So einen Record braucht man selten, genommen wird dieser dauernd.

---

Damit verbleibt der untypisierte Pointer als Alternative für den 'Typ' des Elements oder eben ein Wunder Wuzi Record Typ.

---

Du verlierst jede Typinformation und musst damit alle Fälle entweder in einen Variant (Datentypen) oder ein Variantenrecord (ähnlich einer UNION in C) packen und dann je nach Typ in eine eigene Prozedur springen oder halbwegs anständig innerhalb einer verarbeiten.

Der Variantenrecord lebt davon, dass du mehrere Variablen pro Variante kannst zusammenfassen oder Bits sprechend kannst benennen. Zu einem Varianten Record gehört in der Regel eine Enumeration die den Typ beschreibt. Das wäre anstatt des x aus deinem Beispielcode.

---

Records können Methoden haben sind aber nicht vererbbar.

---

Du kannst auch einen Zeiger auf die zum Typ passende Prozedur zur Behandlung des Records selbst halten. Die Typinformation ist an sich Powidl (egal österr.). Ich habe zumeist ein dynamisches Arry mit Prozedurzeigern im Head gehalten und im Datenelement indirekt auf die 'Methode' resp. Prozedur verwiesen. Wobei eigentlich ein Record genügt und geschwind das Datenelement aus dem Array je nach Belieben und Größe der Datenmenge.


Das wäre dann sinnvoll, wenn man einen Recordtyp verstecken könnte und Prozeduren zu dessen Modifikation in ein Modul packte.

Die nächste Frage die es zu beantworten gilt ist ob du von Rekursion kannst profitieren.

---

Ich mahne etwas zur Vorsicht, da Delphi abstrakte Datentypen abseits von Klassen nicht erlaubt sauber abzubilden. Es fehlt POINTER TO RECORDTYPE ohne den RECORDTYPE außerhalb des allgemein verwendbaren Interfaces zu definieren. Du kannst den Typ nicht so einfach verstecken, sodass du sobald du Zugriff auf den Pointer selbst hast nicht die Inhalt direkt könntest modifizieren. Über 3 Units pro ADT geht es schon.

---

Borland konnte das so nie und bestenfalls über einen untypisierten Pointer, was nur die halbe Miete ist. Modula II war Turbo Pascal weit überlegen. Der reine untypisierte Pointer macht nurmehr dann Sinn, wenn man sowieso zur Laufzeit eine DLL bspw. lädt usw...

---

Delphi unterstützt IS und damit einen sicheren Typecast bei Klassen. In VB.net wurde Variant an sich auch durch Klassen abgelöst. Seit Anbeginn von Delphi ist der Fall in Klassen zu verpacken.


Zitat:

Zitat von markus888 (Beitrag 1422013)
Zitat:

Zitat von HeZa (Beitrag 1422011)
Wie du auf das Array zugreifen willst hast du uns ja noch nicht gezeigt.

Sorry, ich übermittle das erste Array-Element als Pointer an die Prozedur und bewege mich mittels inc() durch die Elemente.
Das wesentliche was die Codes unterscheidet sind Zeiger auf verschiedene Records.



Alle Zeitangaben in WEZ +1. Es ist jetzt 19:29 Uhr.
Seite 1 von 2  1 2      

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