Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi boolean ohne variable? (https://www.delphipraxis.net/36031-boolean-ohne-variable.html)

Pseudemys Nelsoni 14. Dez 2004 21:39


boolean ohne variable?
 
hi,

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fs : TFileStream;
  DataSize : Word;
  DataType : Word;
  CurEntry : record
    Header : record
      Tag : array[0..3] Of Char;
      EntryType : Word;
      Size : Word;
    end;
    case boolean of
      true:  (Value : DWORD; Junk: array[0..1023] of Char);
      false : (Str : array[0..1023] of Char);
  end;
  CurInfo : String;
  CurJunk : array[0..1023] Of Char;
begin
  //...
end;
ich habe 2 fragen hierzu, ersteinmal: wieso hat das "case" hier kein "end;" ? und zweitens wie funktioniert der boolean in dem case, er hat ja gar keine variable? O_o

Aenogym 14. Dez 2004 21:44

Re: boolean ohne variable?
 
hi,

zwei gegenfargen: woher hast du das? und kompiliert es?

Aenogym

glkgereon 14. Dez 2004 21:46

Re: boolean ohne variable?
 
ja, es kompiliert....

aber wundern tuts mich auch :gruebel:

Pseudemys Nelsoni 14. Dez 2004 21:52

Re: boolean ohne variable?
 
es ist ein stück code den ich von SCP habe, ich versuche gerade den nach und nach nachzuvollziehn und scheitere bereits wie man sieht an den records ^^

ja es lässt sich kompilieren, wenn ich ein "end;" ans case ranfügen würde, würde es nichtmehr gehen.
ich kann zwar ein b: vor dem "boolean" machen, aber das war nur als test, es lässt sich mit und ohne kompilieren, nur versteh ich nicht wie dieser bool dann funktioniert?

Aenogym 14. Dez 2004 22:00

Re: boolean ohne variable?
 
so,

delphi-hilfe bemüht:

Zitat:

A record type can have a variant part, which looks like a case statement. The variant part must follow the other fields in the record declaration.

To declare a record type with a variant part, use the following syntax.

Delphi-Quellcode:
type recordTypeName = record
   fieldList1: type1;
     ...
   fieldListn: typen;
   case tag: ordinalType of
   constantList1: (variant1);
     ...
   constantListn: (variantn);
   end;
The first part of the declaration--up to the reserved word case--is the same as that of a standard record type. The remainder of the declaration--from case to the optional final semicolon--is called the variant part. In the variant part,
  • tag is optional and can be any valid identifier. If you omit tag, omit the colon (:) after it as well.
  • ordinalType denotes an ordinal type.
  • Each constantList is a constant denoting a value of type ordinalType, or a comma-delimited list of such constants. No value can be represented more than once in the combined constantLists.
  • Each variant is a semicolon-delimited list of declarations resembling the fieldList: type constructions in the main part of the record type. That is, a variant has the form

    Code:
    fieldList1: type1;
        ...
       fieldListn: typen;
    where each fieldList is a valid identifier or comma-delimited list of identifiers, each type denotes a type, and the final semicolon is optional. The types must not be long strings, dynamic arrays, variants (that is, Variant types), or interfaces, nor can they be structured types that contain long strings, dynamic arrays, variants, or interfaces; but they can be pointers to these types.

Records with variant parts are complicated syntactically but deceptively simple semantically. The variant part of a record contains several variants which share the same space in memory. You can read or write to any field of any variant at any time; but if you write to a field in one variant and then to a field in another variant, you may be overwriting your own data. The tag, if there is one, functions as an extra field (of type ordinalType) in the non-variant part of the record.

Variant parts have two purposes. First, suppose you want to create a record type that has fields for different kinds of data, but you know that you will never need to use all of the fields in a single record instance. For example,

Delphi-Quellcode:
type
  TEmployee = record
  FirstName, LastName: string[40];
  BirthDate: TDate;
  case Salaried: Boolean of
    True: (AnnualSalary: Currency);
    False: (HourlyWage: Currency);
end;
The idea here is that every employee has either a salary or an hourly wage, but not both. So when you create an instance of TEmployee, there is no reason to allocate enough memory for both fields. In this case, the only difference between the variants is in the field names, but the fields could just as easily have been of different types. Consider some more complicated examples:

Delphi-Quellcode:
type
  TPerson = record
  FirstName, LastName: string[40];
  BirthDate: TDate;
  case Citizen: Boolean of
    True: (Birthplace: string[40]);
    False: (Country: string[20];
            EntryPort: string[20];
            EntryDate, ExitDate: TDate);
  end;
type
  TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);
  TFigure = record
    case TShapeList of
      Rectangle: (Height, Width: Real);

      Triangle: (Side1, Side2, Angle: Real);
      Circle: (Radius: Real);
      Ellipse, Other: ();
  end;
For each record instance, the compiler allocates enough memory to hold all the fields in the largest variant. The optional tag and the constantLists (like Rectangle, Triangle, and so forth in the last example) play no role in the way the compiler manages the fields; they are there only for the convenience of the programmer.

The second reason for variant parts is that they let you treat the same data as belonging to different types, even in cases where the compiler would not allow a typecast. For example, if you have a 64-bit Real as the first field in one variant and a 32-bit Integer as the first field in another, you can assign a value to the Real field and then read back the first 32 bits of it as the value of the Integer field (passing it, say, to a function that requires integer parameters).
:D

Aenogym

edit: das nächste mal verwende ich die vorschau :roll:

paresy 14. Dez 2004 22:11

Re: boolean ohne variable?
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fs : TFileStream;
  DataSize : Word;
  DataType : Word;
  CurEntry : record
              Header : record
               Tag : array[0..3] Of Char;
               EntryType : Word;
               Size : Word;
              end;
              case boolean of
               true:  (Value : DWORD; Junk: array[0..1023] of Char);
               false : (Str : array[0..1023] of Char);
             end;
  CurInfo : String;
  CurJunk : array[0..1023] Of Char;
begin
  //...
end;
damit kannst du in einem record mehrere variablen im selben speicher halten -> das ganze dient der übersicht wenn du ein record für 2 sachen verwenden willst und dadurch 2 ( hier 2 durch das boolean -> true/false ) verschieden bezeichnungen brauchst.

beispiel:

Delphi-Quellcode:
 TIPSVarType = (vtBoolean, vtInteger, vtFloat, vtString);
 TIPSVarTypes = set of TIPSVarType;

 PIPSVariable = ^TIPSVariable;
 TIPSVariable = record
  VarName   : PChar;
  VarType   : TIPSVarType;
  VarInfo   : PChar;
  VarUpdated : TDateTime;
  case TIPSVarType of
   vtBoolean : (VarBoolean : Boolean);
   vtInteger : (VarInteger : Integer);
   vtFloat  : (VarFloat  : Single);
   vtString : (VarString : PChar);
 end;
hier habe ich für jeden variablentyen einen eigenen namen mit verschiedenen typen (Boolean/Integer..). da das record je immer nur eine variabe annehmen kann muss ich ja nicht alle möglichkeiten im record gleichzeitig aufnehmen sondern nehme per case nur jeweils eins rein was mich an speicher nur soviel kostet wie der größte typ ( der compiler denkt da halt mit... und mir erspart es arbeit bzw arbeitsspeicher )

werd mal bei gelegenheit das topic aus der delphi help suchen.... da gabs was...

dizzy 14. Dez 2004 22:12

Re: boolean ohne variable?
 
[ot]
"Junk" ist ein schöner Bezeichner :D. Das heisst so viel wie Müll/Schrott. "Chunk" ist mir in Verbindung mit binären Dateiformaten eher ein Begriff ;) (heisst ~Stück, im Sinne z.B. von "a chunk of meat")
[/ot]

Jö, wollt ich nur am Rande los werden :angel2:

btw: DAS nenne ich mal nen Record! Record in Record, und dann noch mit variantem Teil und (verkappten) Strings. Is ja alles drin so :lol:

Pseudemys Nelsoni 14. Dez 2004 22:21

Re: boolean ohne variable?
 
@Aenogym:

wenn ich keinen bezeichner habe für den boolean, wie spreche ich ihn dann an?

@paresy:

ich weiss schon wie variante records funktionieren, mir ist nur schleierhaft wieso da nach dem case kein "end;" kommt

paresy 14. Dez 2004 22:26

Re: boolean ohne variable?
 
Zitat:

Zitat von Pseudemys Nelsoni
@Aenogym:

wenn ich keinen bezeichner habe für den boolean, wie spreche ich ihn dann an?

garnicht.... der compiler bietet dir alle möglichkeiten an. das boolean bringt nur dass du im case 2 möglichkeiten hast.

dizzy 14. Dez 2004 22:28

Re: boolean ohne variable?
 
Ich darf?

Zitat:

Zitat von Pseudemys Nelsoni
@Aenogym:
wenn ich keinen bezeichner habe für den boolean, wie spreche ich ihn dann an?

Garnicht. Du wählst die passende Variante allein durch das Schreiben des Elementbezeichners. Das "case" hier ist bloß ein sprachliches Konstrukt, und funktioniert nicht wie "case" im eigentlichen Code.

Zitat:

Zitat von Pseudemys Nelsoni
@paresy:
ich weiss schon wie variante records funktionieren, mir ist nur schleierhaft wieso da nach dem case kein "end;" kommt

Weil der variante Teil ohnehin immer der letzte im Record sein muss. Somit ist der variante Teil genau dann zu ende, wenn der Record zu ende ist ;)

Pseudemys Nelsoni 14. Dez 2004 22:37

Re: boolean ohne variable?
 
@paresy, das verstehe ich nicht, irgendwie muss doch entschieden werden welcher variante teil benutzt wird, in den beispiel, siehe ersten post, wann ist da true und wann false?

@dizzy, danke das erklärt das fehlende end;

paresy 14. Dez 2004 22:47

Re: boolean ohne variable?
 
benutz mal das auto completion feature von delphi... dann zeigt er dir folgende möglichkeiten an:

Header : record

//true teil
Value : DWORD;
Junk: array[0..1023] of Char;
//false teil
Str : array[0..1023] of Char;

d.h. -> du hast die wahl für welchen teil du dich entscheidest. du kannst auch beiden teilen was zuweisen, jedoch überschneiden sich die sachen dann im speicher was wahrscheinlich nicht sinn und zweck erfüllt... vllt jedoch auch mal nützlich sein kann ( hab nur grad keine idee )

Chewie 14. Dez 2004 23:55

Re: boolean ohne variable?
 
Angewandt wird das ganze z.B. bei Ip-Adressen: Dort gibt es die Möglichkeit, eine 32Bit-Zahl zu setzen oder aber 4 8Bit-Zahlen. Da die 4x8 Bit den gleichen Speicherbereich adressieren wie die 1x32 Bit, spielt das keine Rolle.

Christian Seehase 15. Dez 2004 00:09

Re: boolean ohne variable?
 
Moin Mario,

Zitat:

Zitat von Pseudemys Nelsoni
irgendwie muss doch entschieden werden welcher variante teil benutzt wird

jein ;-)

Das entscheidest Du, indem Du das entsprechende Feld angibst.
Vielleicht wird es mit einem Beispiel deutlicher:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

type
  TcsMyVariant1 = record
    case boolean of
      true : (dwDWORD : DWORD);
      false : (bByte0  : Byte;
               bByte1  : Byte;
               bByte2  : Byte;
               bByte3  : Byte;)
  end;

  TcsMyVariant2 = record
    case byte of
      8  : (dwDWORD : DWORD);
      37 : (bByte0  : Byte;
            bByte1  : Byte;
            bByte2  : Byte;
            bByte3  : Byte;)
  end;

var
  mvWork1 : TcsMyVariant1;
  mvWork2 : TcsMyVariant2;

begin
  mvWork1.dwDWORD := $FFEEDDCC;

  ShowMessage(IntToHex(mvWork1.bByte3,2)+#13#10+
              IntToHex(mvWork1.bByte2,2)+#13#10+
              IntToHex(mvWork1.bByte1,2)+#13#10+
              IntToHex(mvWork1.bByte0,2));

  mvWork2.bByte0 := $CC;
  mvWork2.bByte1 := $DD;
  mvWork2.bByte2 := $EE;
  mvWork2.bByte3 := $FF;

  ShowMessage(IntToHex(mvWork2.dwDWORD,8));
end;

Pseudemys Nelsoni 15. Dez 2004 00:39

Re: boolean ohne variable?
 
moin christian,

danke für dein beispiel :]

was ich aber nun nicht verstehe ist "8" bzw "37" bei deinem 2ten rekord, irgendwie seh ich im code nirgends wo das eine bedeutung haette

Christian Seehase 15. Dez 2004 00:52

Re: boolean ohne variable?
 
Moin Mario,

Zitat:

Zitat von Pseudemys Nelsoni
irgendwie seh ich im code nirgends wo das eine bedeutung haette

das war auch Sinn und Zweck der Zahlenwahl.
Sie haben keine Bedeutung. Solange Du für jede Variante einen Wert angibst, der zum Wertebereich des Ordinaltyps im Case angibst, kannst Du Werte nehmen, wie Du gerade willst.
Unter Umständen können die Werte auch der Dokumentation dienen, z.B.

Delphi-Quellcode:
type
  TcsMyType = record
    bRecordType : Byte;
    case Byte of
      $AA : (.....); // Aufteilung, wenn bRecordType = $AA ist
      $BB : (.....); // Aufteilung, wenn bRecordType = $BB ist
      // ...
  end;
Wenn Du nur zwei Varianten unterscheiden musst reicht boolean, bis zu 256 dann Byte usw.
Grösser schadet nicht.

Pseudemys Nelsoni 15. Dez 2004 01:23

Re: boolean ohne variable?
 
danke christian, dann ist mir das nun klar =)

glkgereon 15. Dez 2004 07:03

Re: boolean ohne variable?
 
nochmal ne frage...also so:

Delphi-Quellcode:
type
  TTest = record
    Variable:Typ;
    case Typ of //bezieht sich auf die zuletzt genannte Variable des Typs 'Typ'
      Wert1: (a:Typa, b:Typb);//Fall 1
      Wert2: (x:Typx, y:Typy);//Fall 2
  end;
ist das so korrekt?
mit kommentaren, ends und allem?

Hansa 15. Dez 2004 07:22

Re: boolean ohne variable?
 
Ich empfehle, dieses Thema nicht zu vertiefen. :mrgreen:

Warum ?

1. wie man sieht, führen Varianten für ziemliche Verwirrung. :shock:

2. sie bringen keinen Vorteil.

3. Aus Sicht einer Datenbank ist es völliger Unsinn, es geht nämlich auch, einen Typ anzulegen, der in Abhängigkeit eines Wertes 1 Byte oder 10000 belegt. In diesem Falle müßten dann 10000 Byte belegt werden bei jedem Datensatz.

Deshalb : Finger weg ! :warn:

Oxmyx 15. Dez 2004 15:13

Re: boolean ohne variable?
 
Natürlich hat es einen Vorteil. Stell dir mal einen mathematischen Vektor vor. In manchen Fällen willst du, dass die Komponenten x, y und z sind. In anderen Fällen willst du x1, x2 und x3. In anderen vielleicht dann u, v, w. So kannst du alle Varianten in einem Vektortyp unterbringen.

Sharky 15. Dez 2004 15:44

Re: boolean ohne variable?
 
Es gibt schon Fälle wo es nett ist:
Delphi-Quellcode:
type
  TmyColor = record
      case boolean of
      true : (Color : TColor);
      false : (ColorR : Byte;
               ColorG : Byte;
               ColorB : Byte;)
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  myColor : TmyColor;
begin
  myColor.Color := clLime;
  Label1.Caption := 'Rotanteil : ' + IntToStr(mycolor.ColorR);
  Label2.Caption := 'Grünanteil : ' + IntToStr(mycolor.ColorG);
  Label3.Caption := 'Blauanteil : ' + IntToStr(mycolor.ColorB);
end;
Und schon kann ich ganz elegant auf die einzelnene Anteile einer Farbe zuweisen :stupid:

maximov 15. Dez 2004 16:11

Re: boolean ohne variable?
 
Oder eine matrix, die man über feldnamen oder array-adressierung ansprechen will:
Delphi-Quellcode:
TD3DMatrix = packed record
    case Integer of
      0 : (_00, _01, _02, _03,
           _10, _11, _12, _13,
           _20, _21, _22, _23,
           _30, _31, _32, _33 : Single);
      1 : (m : array [0..3, 0..3] of Single);
  end;
Also, nix da 'finger weg' ...wenn man weiß was man tut.

Hansa 15. Dez 2004 20:39

Re: boolean ohne variable?
 
Zitat:

Zitat von maximov
...wenn man weiß was man tut.

Eben drum. :mrgreen:

NicoDE 15. Dez 2004 20:52

Re: boolean ohne variable?
 
Zitat:

Zitat von glkgereon
nochmal ne frage...also so:

Delphi-Quellcode:
type
  TTest = record
    Variable:Typ;
    case Typ of //bezieht sich auf die zuletzt genannte Variable des Typs 'Typ'
      Wert1: (a:Typa, b:Typb);//Fall 1
      Wert2: (x:Typx, y:Typy);//Fall 2
  end;
ist das so korrekt?
mit kommentaren, ends und allem?

Fast, Semikolon statt Kommata:
Delphi-Quellcode:
type
  TTest = record
    case Variable: Typ of // Gleich hier, statt davor (verdeutlicht besser die Bedeutung von 'Variable')
      Wert1: (
        a: Typa; // Semilkolon
        b: Typb);
      Wert2: (
        x: Typx;
        y: Typy);
  { end; }  // unnötig, da variante Member ohnehin nur am Ende erlaubt
  end;

StefanDP 15. Dez 2004 21:02

Re: boolean ohne variable?
 
man könnte es auch einsetzen, um geziehlt bitmanipulation zu betrieben:
Delphi-Quellcode:
type
  TFlags = record
    case boolean of
    TRUE: (Flags: Byte);
    FALSE: (F1, F2, F3, F4, F5, F6, F7: Boolean;)
  end;
:mrgreen:
damit kann man beliebigs bits im byte ändern, aber auch das ganze byte mit einem wisch aus/einlesen

stefan

NicoDE 15. Dez 2004 21:07

Re: boolean ohne variable?
 
Zitat:

Zitat von StefanDP
man könnte es auch einsetzen, um geziehlt bitmanipulation zu betrieben

Nope (Boolean = ByteBool), dafür würde man eher Sets verwenden.
(Bitte erst Testen, bevor man wilde Behauptungen aufstellt...)

Chewie 15. Dez 2004 21:16

Re: boolean ohne variable?
 
Na ja, bei FreePascal könnte es so gehen (wenn ich mich richtig erinnere).

Da gibts sowas wie
Delphi-Quellcode:
type TPackedBool = packed Array[0..7] of Boolean;
Hab aber leider den FPC grad nicht zur Hand, kanns also nicht testen,
Ist außerdem eh ein andres Thema ;)

NicoDE 15. Dez 2004 21:41

Re: boolean ohne variable?
 
Zitat:

Zitat von Chewie
bei FreePascal könnte es so gehen

Nope.

Pseudemys Nelsoni 15. Dez 2004 21:53

Re: boolean ohne variable?
 
Zitat:

Zitat von Hansa
2. sie bringen keinen Vorteil.

Zitat:

Zitat von maximov
...wenn man weiß was man tut.

Zitat:

Zitat von Hansa
Eben drum. :mrgreen:





da hast dich aber schnell rausgeredet :P :mrgreen:

Hansa 15. Dez 2004 22:01

Re: boolean ohne variable?
 
Zitat:

Zitat von Pseudemys Nelsoni
...da hast dich aber schnell rausgeredet :P :mrgreen:

nix rausreden. :mrgreen: Keine Angst, ich habe die Varianten schon getestet und sehe nur keinen Vorteil darin, eine Variable 2mal zu deklarieren und dann noch verschieden. Was soll das für ein Programm werden ?

Bzw., wer soll das verstehen ? Sagen wir mal nach 1 Jahr ? :shock:

Christian Seehase 16. Dez 2004 00:00

Re: boolean ohne variable?
 
Moin Hansa,

wenn Du, beispielsweise, einen Recordtypen zum Auslesen von Dateien mit Varianten Teilen versiehst, erhältst Du eine übersichtlichere Lese-/Schreibroutine für verschiedene Datensatztypen.

Ausserdem schau Dir mal die Deklaration von TRect in der Hilfe an.

Hansa 16. Dez 2004 00:07

Re: boolean ohne variable?
 
Nun denn, ich sage ja nicht, daß eine Variante absoluter Unfug ist. :mrgreen: Ich bezweifle nur den Nutzen für "normale" Programme. 8) Und die TRect-Hilfe ist die Bestätigung dafür, daß Delphi besser ist als C und Konsorten.

tilman 20. Nov 2007 12:43

Re: boolean ohne variable?
 
Sry wenn ich einen alten Thread aufwärme :spin:
Hab grad das erste mal von dieser case-option gehört, ist dass dann sowas ähnliches für typen wie overload für methoden?


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