case in Pascal Unions

case in Pascal Unions

Beitragvon markusk » Di 8. Nov 2016, 22:01

Hallo!

In Turbo Pascal werden die von C bekannten Unions ja beispielsweise so definiert:

type VEL = record
case boolean of
true : (Zeichen, Attribut : byte);
false : (Inhalt : word);
end;

Kann mir jemand erklären was es mit diesem case auf sich hat? Zumal dieses boolean beim Zuweisen ja gar nicht vorkommt, denn eine Zuweisung erfolgt ja dann so:

var velptr : ^VEL;

velptr^.Zeichen:=65;
velptr^.Attribut:=2;

oder eben

velptr^.inhalt:=$0241;

lg, Markus
markusk
HELP.COM-Benutzer
 
Beiträge: 25
Registriert: Fr 19. Apr 2013, 10:12

Re: case in Pascal Unions

Beitragvon DOSferatu » Mi 9. Nov 2016, 07:07

Ich habe es so noch nie benutzt. Aber es dient wohl eher genau dieser Möglichkeit - damit bei der Übergabe geprüft werden kann (wenn Prüfung angeschaltet), ob der übergebene Typ der richtige ist. Und eben, um an dieselbe Stelle sowohl die einzelnen Werte als auch die komplette Variable übergeben zu können.
Ich selbst arbeite in solchen Fällen übrigens eher mit "absolute". D.h. Ich deklariere Variablen und dann nochmal andere Variablen an die gleiche Stelle. Das mache ich z.B. gern bei Strings:
Code: Alles auswählen
var h:string; lh:byte absolute h; hx:boolean absolute h;

So kann ich, statt die Funktion length(h) zu benutzen einfach die Byte-Variable lh abfragen, um die Stringlänge zu ermitteln - oder sogar zu ändern. Und hx ist FALSE, wenn der String leer ist, ansonsten TRUE.
(Das geht, weil im Gegensatz zu C, das nullterminierte Strings benutzt, bei Pascal die Stringlänge im ersten Byte gespeichert wird.)
Leerzeichen am Stringende löschen?
Code: Alles auswählen
while h[lh]=#32 do dec(lh);

(Das geht für alle Zeichen außer #0. Hier muß man dann den "Unterlauf" berücksichtigen, z.B. mit
Code: Alles auswählen
while hx and (h[lh]=#0) do dec(lh);

Ich verwende das auch ganz gern, um "Festkomma-Variablen" zu simulieren:
Code: Alles auswählen
var XX:longint; XF:record XL:word;XH:integer;end absolute XX;

Solche Dinge benutze ich dann gern in grafischen Dingen - z.B. Linienzeichnen. Da habe ich dann 2 Routinen, je nachdem, ob der Anstieg der Linie flacher oder steiler ist und dementsprechend ist der Adder für eine Koordinate 65536 und für die andere entsprechend dem Anstieg eben 0 bis 65535. (Wobei ich natürlich in Wirklichkeit dann nur für die 65536-Variante einfach 1 zur jeweils "oberen" word/integer der Koordinate addiere, weil es ja sowieso 2 Subroutinen sind.)
Zum Setzen der Pixel braucht man dann nur die ganzzahligen Werte. (Ich bin ja nicht so verrückt und benutze da Fließkomma und setze dann jedesmal Pixel mit pixel(round(X),round(Y)) oder so.)
Ähnlich gehe ich auch vor (wenn auch in Assembler) für die gedrehten/gespiegelten Sprites, die ich in meiner einen Unit benutze.

Also ich denke mal, o.g. Möglichkeit und auch die von mir genannten Möglichkeiten sind wohl hauptsächlich nützlich, um Werte direkt (als "Block") zuweisen zu können/abzufragen, ohne irgendwelche "Typecasting"-Funktionen benutzen zu müssen. Ja, das ist vielleicht nicht so "sauber", da es nicht 100% kompatibel/portierbar wäre. Im Falle von Strings muß man sich darauf verlassen, daß sie im "Pascal-Stringformat" vorliegen (s.o.). Bei Variablen, so wie oben verwendet, muß klar sein, daß die Bytereihenfolge des Zielsystem PC-artig ist.
Andererseits sind Dinge wie die obengenannten aber schneller als Funktionen (die zusätzliche Aufrufe benötigen und intern ggf. auch Prüfungen durchführen).

Auch das von Dir genannte Beispiel wäre dann davon abhängig. daß die Bytereihenfolge des Zielsystems nicht vertauscht wäre. Allerdings gibt es Turbo-Pascal ja soweit ich weiß nur für x86-PC.
DOSferatu
DOS-Übermensch
 
Beiträge: 1095
Registriert: Di 25. Sep 2007, 11:05


Zurück zu Programmierung

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste