case in Pascal Unions

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
markusk
Norton Commander
Beiträge: 132
Registriert: Fr 19. Apr 2013, 11:12

case in Pascal Unions

Beitrag von markusk »

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
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: case in Pascal Unions

Beitrag von DOSferatu »

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.
Antworten