type
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
……
vtVariant: (VVariant: PVariant);
end;
end;请问其中的 “Case XX of”什么意思?怎么在记录类型中??????????????
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
……
vtVariant: (VVariant: PVariant);
end;
end;请问其中的 “Case XX of”什么意思?怎么在记录类型中??????????????
解决方案 »
- CxGrid 图片显示
- 这一条语句是什么意思?
- 怎么在控件的单击事件中取控件的Caption和name
- 来个难点的!如何得出两个日期间各个月、周的开始日期、结束日期?
- 一个关于TQuery字串长度的问题,急啊,我搞了好长时间了也查不出什么错。
- 请问怎样获得制定文件类型的图标?
- 谁用过delphi做过数字签名?
- 关于SQL SERVER的问题--多条记录更新
- 怎样动态在程序中创建SOCKET
- 请问我在编译程序的时候出现 file not found "frmaddBdsuo.dcu"是什么意思?dcu是什么文件?
- 源代码从Delphi 5移到Delphi 7出问题了:(
- Richedit的字符间距有人能搞定吗?
或许还有 xx 是
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
……
vtVariant: (VVariant: PVariant);
中的某种类型
一个记录类型能拥有变体部分,它看起来就像case 语句,在声明中,变体部分必须跟在其它字段的后面。
要声明一个变体记录,使用下面的语法:
type recordTypeName = record
fieldList1: type1;
...
fieldListn: typen;
case tag: ordinalType of
constantList1: (Variant1);
...
constantListn: (Variantn);
end;
声明的前面部分(直到关键字case)和标准记录类型一样,声明的其余部分(从case 到最后一个可选的
分号,)称为变体部分,在变体部分
tag 是可选的,它可以是任何有效标志符。如果省略了tag,也要省略它后面的冒号(:)。
ordinalType 表示一种有序类型。
每个constantList 表示一个ordinalType 类型的常量,或者用逗号隔开的常量序列。在所有的常量
中,一个值不能出现多次。
每个Variant 是一个由逗号隔开的、类似于fieldList: type 的声明列表,也就是说,Variant 有下面
的形式:
fieldList1: type1;
...
fieldListn: typen;
这里,每个fieldList 是一个有效标志符,或是由逗号隔开的标志符列表,每个type 表示一种类型,
最后一个分号是可选的。这些类型不能是长字符串、动态数组、变体类型或接口(都属于动态管
理类型),也不能是包含上述类型的结构类型,但它们可以是指向这些类型的指针。
变体记录类型语法复杂,但语义却很简单:记录的变体部分包含几个变体类型,它们共享同一个内存区
域。你能在任何时候,对任何一个变体类型的任何字段读取或写入,但是,当你改变了一个变体的一个
Data types, variables and constants
字段,又改变了另一个变体的一个字段时,你可能覆盖了自己的数据。如果使用了tag,它就像记录中
非变体部分一个额外的字段,它的类型是ordinalType。
变体部分有两个目的。首先,假设你想创建这样一个记录:它的字段有不同类型的数据,但你知道,在
一个(记录)实例中你永远不需要所有的字段,比如:
type
TEmployee = record
FirstName, LastName: string[40];
BirthDate: TDate;
case Salaried: Boolean of
True: (AnnualSalary: Currency);
False: (HourlyWage: Currency);
end;
这里的想法是,每个雇员或者是年薪,或者是小时工资,但不能两者都有。所以,当你创建一个TEmployee
的实例时,没必要为每个字段都分配内存。在上面的情形中,变体间的唯一区别在于字段名,但更简单
的情况是字段拥有不同的类型。看一下更复杂的例子:
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;
对每个记录类型的实例,编译器分配足够的内存以容纳最大变体类型的所有字段。可选的tag 和
constantLists(像上面例子中的Rectangle、Triangle 等)对于编译器管理字段没有任何作用,它们只是为
了程序员的方便。
使用变体记录的第二个原因是,你可以把同一个数据当作不同的类型进行处理,即使在编译器不允许类
型转换的场合。比如,在一个变体类型中,它的第一个字段是64 位实数,在另一个变体类型中,第一个
字段是32 位整数,你可以把一个值赋给实数(字段),然后再当作整数来读取它的前32 位值(比如,把
它传给一个需要整数参数的函数)。
part must follow the other fields in the record declaration.
To declare a record type with a variant part, use the following syntax.
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 comma-delimited list of declarations resembling the fieldList: type
constructions in the main part of the record type. That is, a variant has the form
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,
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:
S t r u c t u r e d t y p e s
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 above) 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).
请教结构定义中,出现case是什么意思?