Delphi的类型包括Simple type、String type、structured type、Pointer type、procedure type、variant type。
1.simple type
simple type 包括ordinal type(有序类型)和real type(真实类型)。ordinal type包括integer、character、boolean、enumerate、subrange。
1.1 integer类型分为通用Integer类型(Integer和Cardinal);基本Integer类型(shortint、SmallInt、LongInt、Int64、Byte、word、LongWord);
1.2 Character类型分为AnsiChar类型(8位Ansi编码)和WideChar类型(16位Unic编码)。通用类型为Char(AnsiChar)使用SizeOf,Chr(65):='A';
1.3 Boolean类型分为Boolean、ByteBool、WordBool、LongBool四种基本布尔类型。其中ByteBool、WordBool、LongBool的值为0,则被认为是true;
1.4 Enum类型。例子:type Suit = (Club, Diamond, Heart, Spade);。如有需要定义两个Enum变量,1.var Card1, Card2: (Club, Diamond, Heart, Spade);或者
type Suit = (Club, Diamond, Heart, Spade);
var
Card1: Suit;
Card2: Suit;
在默认情况下,Enum类型中的元素都是从0开始的。
1.5 subrange类型:代表一个值类型的子集。例如:type TColors = (Red, Blue, Green, Yellow, Orange, Purple, White, Black);相当于type TMyColors = Green..White;
2. real type
real type包括Real48、Single、Double、Extended、Comp、Currency。
2.1字符串类型
2.1.1 ShortString:256个字符长度,向后兼容;其中第一个字节存储串的长度,剩下的255个字节存储字符。利用Ord(S[0])返回S的长度;用High和Low分别返回最大长度(255)与最小长度(0)。例如:
- var MyString: string[100];
等同于
- type CString = string[100];
- var MyString : CString;
当给一个short-string变量赋值时,多于它最大长度的部分将被截取掉。
2.1.2 AnsiString:8位ANSI字符(在多数情况下为首选类型);长串变量是一个指针,占据4个字节的内存,其内存在堆中分配,并对其内存进行自动管理。(当变量为空或长度为0时,指针为nil)。
reference-counting:一个长串变量被销毁或赋给一个新值,原来的串(变量的前一个值)引用计数减1,而新的值引用计数加1.若引用计数为0,它的内存被释放。
copy-on-write:当使用字符串索引改变其中的一个字符时,若字符串的引用计数大于1,将生成串的一个拷贝。
2.1.3 WideString:Unicode字符(多用户服务器和多语言应用程序);在Win32下,没有reference-counting和copy-on-write机制,但支持内存动态分配;
在赋值语句和表达式中,字符串类型可以混合使用,编译器自动进行所需的转换。在默认的{$H+}状态下,string解释为AnsiString;使用{$H-}指示字,把它解释为ShortString
2.1.4 零结尾字符串(Null-terminated strings):以0下标开始的字符数组,并且最后一个是NULL(#0)。存储零结尾字符串:
- type
- TIdentifier = array[0..15] of Char;
- TFileName = array[0,,259] of Char;
- TMemoText = array[0..1023] of WideChar;
可以把一个字符串常量,赋给一个0下标开始的静态字符数组。该数组与PChar和PWideChar指针相兼容。所以PChar和PWideChar可以像数组一样使用索引。
2.2 结构类型
结构类型包括set、array、record、class、class-reference、interface-type。
2.2.1 sets
sets是同一种有序类型的值的聚集(不能包含相同的值)。定义集合:
- type
- TSomeInts =1..250;
- TIntSet = set of TSomeInts;
也等同于
- type
- TIntSet = set of 1..250;
2.2.2 Arrays
arrays是由相同类型的、经过索引的元素组成的聚集。(可以包含相同的值)
2.2.2.1 static arrays
定义一维数组
- var MyArray: array[1..100] of Char;
定义多维数组
- type TMatrix = array[1..10] of array [1..50] of Real;
等价于
- type TMatrix = array[1..10,1..50] of Real;
2.2.2.2 dynamic arrays
动态数组的定义
- var myFlexibleArray : array of Real;
分配内存地址
- SetLength(myFlexibleArray,20);
动态数组的变量实际上是一个指针,如没有其他方法引用该变量,释放所占用的内存,则可以通过给变量赋nil值或传递Finalize。动态数组的比较相当于其引用的比较(比较地址)
2.2.2.3 多维动态数组
多维动态数组定义
- type TMessageGrid = array of array of string;
- var Msgs : TMessageGrid;
分配内存地址
- SetLength(Msgs,I,J);
2.2.2.4 数组类型
数组类型的定义和赋值
- type IntArray = array[1..10] of Integer;
- var Int1 : IntArray;Int2 : IntArray;
2.3 record
record表示不同种类的元素的集合,其中元素被称为field。
record类型的定义:
- type
- TDateRec = record
- Year : Integer;
- Month : (jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
- Day : 1..31;
- end;
实例化record类型
- var record1,record2 : TDateRec;
访问字段
- record1.Year := 1904;
- record1.Day := 16;
也可以用with
- with record1 do
- begin
- Year := 1904;
- Day := 16;
- end;
2.3.1 变体记录
定义变体记录
- 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;
2.4 文件类型
文件类型的定义
- type
- PhoneEntry = record
- Firstname,LastName : string[20];
- PhoneNumber : string[15];
- Listed: Boolean;
- end;
- PhoneList = file of PhoneEntry;
数组和记录类型中不能包含文件类型。
2.5 指针类型
指针是表示内存地址的变量。
@运算符:取得一个变量的地址。
^typeName:指向typeName类型的变量的指针;pointer^:返回指针所指向地址保存的值。
字符类型包括PAnsiChar和PWideChar。
2.6 过程类型
过程类型允许你把过程和函数作为“值”看待,并可以将其赋给变量或传给其它过程和函数。例如
- type
- TIntegerFunction = function: Integer;
- TProcedure = procedure;
- TStrProc = procedure(const S : string);
- TMathFunc = function(X: Double):Double;
- var
- F: TIntegerFunction;
- Proc : TProcedure;
- SP : TStrProc;
- M: TMathFunc;
上面的变量是过程指针,也就是指向过程或函数地址的指针。
- type
- TMethod = procedure of object;
- TNotifyEvent = procedure(Sender: TObject) of object;
这些类型叫做方法指针。下面来看一下过程类型在语句和表达式中的使用:
- var
- F: function(X: Integer): Integer;
- I: Integer;
- function SomeFunction(X: Integer): Integer;
- ...
- F := SomeFunction;
- I := F(4);
@F:将F转换为无类型的指针,其存储的是地址;@@F:表示F所对应的地址。判断一个过程类型是否赋予值:
- if Assigned(Onclick) then OnClick(X);
2.7 变体类型
变体类型在运行时可以改变变量类型。能存储除了结构类型和指针外的所有类型。包含字符串的变体类型不能使用索引(即不能采用数组的访问形式)。例如:
- var
- V1,V2 : Variant;
- I : Integer;
- D: Double;
- begin
- V1 := 1;
- V2 := 'hello world';
- end;
除了^、is、in,所有运算符都可以使用Variant作为运算符。Variant的操作返回Variant值;有一个运算数是Null则结果为Null;例如:
- V := Null + 3; //V为null
Variant数组不能把一个普通的静态数组赋给Variant。需要通过调用VarArrayCreate或VarArrayOf来实现:
- V: Variant;
- ...
- V := VarArrayCreate([0,9],varInteger);
2.8 类型一致性
不同类型或变量的定义:
- Type
- TS1 = set of Char;
- TS2 = set of Char;
- var
- S1 : string[10];
- S2 : string[10];
相同类型或变量的定义:
- type MyString = string[10];
- var
- S1 : MyString;
- S2 : MyString;
2.9 变量
全局变量的声明:
- var I : Integer = 7;
变量绝对地址:一个新变量和另一个变量共有一个内存地址。这样,这个新变量的声明后面跟关键字absolute。例如:
- var
- Str: string[32];
- StrLen: Byte absolute Str;
动态变量的创建需要用GetMem或New过程来创建。需要手工释放内存,使用FreeMem来释放由GetMem创建的变量,使用Dispose释放由New创建的变量。
线程局部变量,使用threadvar,例如:
- threadvar X : Integer;
long string、wide string、dynamic arrays、variants、interface能够被定义为threadvar,其变量的内存需要手动释放。
3.0 资源字符串
Resource strings当做资源链接到可执行文件或库中,所以不需要重新编译。例如:
- resourcestring
- CreateError = 'Cannot create file %s';