您的位置:首页 > 移动开发 > Objective-C

数据类型及其相互关系

2008-10-28 20:04 507 查看
3.1[/b]数据类型及其相互关系[/b][/b]
本节对object pascal的数据类型做全面的介绍,并揭示各种数据类型的内存管理方法,最后讨论他们相互的兼容关系和转化方法。
目的:能对各种数据类型有比较全面的,深入的认识,并掌握他们相互关系,最终能在编程的时能合理的准确的选择使用他们

3.1.1[/b]数据类型概述[/b][/b]
Object pascal中定义啦大量的数据类型,不同数据类型具有不同的用途。虽然delphi中对数据类型比较严格,但他们之间也不是严格划清界限的,也就是说,某些数据类型之间具有兼容性和转化性。
下边给个数据类型全家福。

Simple
Ordinal有序类型
类型取值范围空间
Integer
Integer-2147483648~2147483647Signed32-bit
Cardinal0~4294967295Unsigned32-bit
Shortint-128~127Signed8-bit
Smallint-32726~32767Signed16-bit
Longint-2147483648~2147483647Signed32-bit
Int64-2^63~2^63-1Signed64-bit
Byte0~255Unsigned8-bit
Word0~65535Unsigned16-bit
Longword0~4294967295Unsigned32-bit
Character
CharAnsicharWidechar
Boolean
BooleanByteboolLongboolWordbool
Enumerated
Subrange
Real
类型精度取值范围空间
Real15-165.0*10^-324~1.7*10^3088B
*real4811-122.9*10^39~1.7*10^386B
Single7-81.5*10^45~3.4*10-384B
Double15-165.0*10^-324~1.7*10^3088B
Extended19-203.6*10^-4951~1.1*10^493210B
*comp19-20-2^63+1~2^63-18B
Currency19-208B
String`
*shortstringPcharPansicharansiString widestringPwidechar
Structured
SetArrayRecordClassclass reference interfaceFile
Pointer
无类型指针有类型指针
Procedural
普通过程类型对象过程类型
Variant
VariantOlevariant
1, ordinal(有序)类型
simple类型规定啦一个数据取值范围。而ordinal类型在此基础上,还增加啦有序的特性。

该部分演示代码:

var
B: Byte;
begin
B := 255;
{$R+} //执行越界检查。此时越界会抛出erangeerror类型的异常。
B := B + 1;
{$R-}//不执行越界检查,这是默认状态。此时不会抛出错误,但会得到错误的运算结果。
//看下例代码
ShowMessage(IntToStr(B));
end;
======================================================================var
B: Byte; //Byte类型的变量在内存中占据8个Bit。使用函数SizeOf可以取得一个变量或者一个类型在内存中占据的字节数
begin
B := 255; //此时B在内存中的状态是:11111111(8位都是1)。
B := B + 1; //期望获得:100000000(最高位是1,其他8位是0);但是Byte最多8位,所以最高位被抛弃,因而得到低8位全0,也就是最终结果0
ShowMessage(IntToStr(B)); //得到B=0而不是256
end;
======================================================================
type
TC = 'A'..'Z'; //定义字符内容的子界类型
var
C: TC;
OI: Integer;
PI, SI, H, L: Char;
S: String;
begin
C := 'B';
OI := Ord(C); //OI = 66
//ord 取得有序变量的值在取值范围中所在的顺序(即位置)
PI := Pred(C); //PI = ‘A’
//pred 取得有序变量的前序的值(即上一个位置的值)
SI := Succ(C); //SI = ‘C’
//succ 取得有序变量的后序的值(即下一个位置的值)
H := High(TC); //或者H := High(C); H = ‘Z’
//high。。末序的值(取值范围规定的最大的值)
L := Low(TC); //或者L := Low(C); L = ‘A’
//low ..始序的值。。
S :=
'顺序:' + IntToStr(OI) + #13 +
'前序:' + PI + #13 +
'后序:' + SI + #13 +
'末序:' + H + #13 +
'始序:' + L;
ShowMessage(S);
end;
Integer的基本类型是integer和cardinal,建议大多情况下使用这两中类型,因为他们呢是32位的,操作系统和cpu可以花费最少的时间处理他们。
其中取值范围大的可以兼容取值范围小的。范围大的可以赋值给范围小的,单数据会被斩断,这个规则对于实数也是适用的。

代码分析:

var
B: Byte; //B是8位的
W: Word; //W是16位的
begin
W := $1234; //将16进制常数$1234赋值给W
B := W; //B得到的值是W的低8位,即16进制的$34,也即10进制的52
ShowMessage(IntToStr(B)); //显示B的结果值52
end;
Character的基本类型是char。
Boolean的基本类型是boolean
Enumerated(枚举)类型定义拉一系列有序值的集合。Enumerated变量就从这个既定的集合中取某个值。集合中的有序值称为元素,元素一般从0开始连续索引
如下代码分析:

type

TSize = (Small, Medium, Large);
var
Size: TSize;
begin
Size := Large;
ShowMessage(IntToStr(Ord(Size))); //显示2
end;
Subrange(子界)类型也是定义一系列有序值的集合。
代码分析:

type

TColors = (Red, Blue=5, Green, Yellow, Orange, Purple=10, White, Black); //定义一个枚举类型TColors。TColors定

义了一些有序值供下面的子界类型TMyColors使用
TMyColors = Green..White;
var
MyColors: TMyColors;
begin
MyColors := Green; // MyColors只能在Green…White之间取值,取Red、Black等是不允许的
ShowMessage(IntToStr(Ord(MyColors))); //显示6,因为元素Green在TColors中被索引为6
end;
2.real(实数)类型
因为无理数的介入,使得real不再能够“有序”。
Real的基本类型是real,。
3.string(字符串)类型
分为三类:短字符串,长字符串,宽字符串。
Shortstring在内存中占0.。。255字符。就是说他被固定为256字节。其中第0字节存储字符串的实际长度。
长字符串和宽字符串的内存分配是动态的,最大可到2GB,可以认为他们是无限长的。
4.structured(构造)类型
Array(数组)有两种形式:静态数组和动态数组。
Record(记录)类型,十多个任意元素的集合,其中的元素成为记录的字段。
File(文件)类型用来读写文件。
剩下的构造类型class。。三种子类型,由于牵涉的东西比较多,在后边用到时再说他们。
5.pointer(指针)类型
一个指针占用4字节空间,该内存块用来存储另一块内存所在的地址,这另一块内存区才是存储实际数据的地方。
6.procedural(过程)类型
算是一种比较特殊的类型。这种变量可以存取一个过程或者函数!。可以实现回调函数的功能。
结合代码分析啊。(看i和j最终是否一样)

type

TOneFun = function(X: Integer): Integer; //声明一个过程类型

function SomeFunction(X: Integer): Integer; //实现一个和TOneFun兼容的过程
begin
Result := X*2;
end;

function SomeCallBack(X: Integer; OneFun: TOneFun): Integer; //SomeCallBack被调用时,回调函数OneFun,并返回OneFun的执行结


begin
Result := OneFun(X);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
F: TOneFun; //声明过程类型变量,也可以直接声明:F: function(X: Integer): Integer;
I,J: Integer;
begin
F := SomeFunction; //用过程类型变量F引用一个实际过程
I := F(4); //通过过程类型变量F直接调用函数SomeFunction
J := SomeCallBack(4, F); //通过过程类型变量F回调函数SomeFunction
if I = J then
ShowMessage('F(4)和SomeCallBack功能相同');
end;
7.variant(可变)类型
可以存储绝大部分不同的类型的数据。
某个时刻有三种可能的状态:unassiged,null,非null
记住不要对null状态的variant变量进行操作。否则抛出evariantInvalidOpError类型的错误。
比如:

以上已全面的叙述啦object pascal中的数据类型。

3.1.2[/b] [/b]变量的内存分配和释放[/b][/b]
变量的内存分配有两种形式:自动和人工。自动分配:声明变量后被分配内存;人工:声明变量后必须用代码显式的分配内存。
如果是非指针类型的全局变量或局部变量声明后会自动分配内存。
如果是指针类型的则不会自动分配内存。如果是全局的初始值是nil,表示没有指向;如果是局部的,尽管没有分配内存,但是会随机地指向一个地址,值不是nil。

变量的释放:。。。
具体分配的方法有:
1.赋值。
比如:

var

P1,P2: PChar;
begin
P1 := 'lxpbuaa'; {P1已经拥有一块内存}
P2 := P1; {将P2指向P1的内存,这样就间接完成了P2的内存分配}
end;
2.对于类,则调用构造函数。
比如:

var

Obj: TObject;
begin
Obj := TObject.Create; //调用构造函数创建对象,变量Obj指向该对象
Obj.Free; //释放内存,Free内部调用析构函数Destroy;也可以使用:
//FreeAndNil(Obj);
end;
3.分配指定大小的内存。

var

P: PChar;
Size: Cardinal;
begin
Size := MAX_COMPUTERNAME_LENGTH + 1;
GetMem(P, Size); //分配Size个字节的内存块(即缓冲区),并让P指向它
GetComputerName(P, Size); //API函数GetComputerName将取得的计算机名放在P中
ShowMessage(P);
FreeMem(P); //释放缓冲区占用内存
end;
结下,动态分配内存的函数和过程。
1.Getmem
2.Allocmem
Reallocmem
Freemem
3.New

3.1.3 数据的内存结构
分析数据类型变量在内存中的真实存放格式,目的:了解这些类型的真是运作方式。
1. boolean类型
2. enumerated类型
3. ansistring/string类型
包括四个域:

偏移/byet
内容
-8存储引用计数
-4存储字符长度
0..Length-1存储实际字符
Length零字符(null或者#0)。
引用计数域帮助管理内存的自动释放工作。
零字符域便于和pchar类型的转化。
Widestring变量是类似的,但是少啦引用计数域。
Ansistring和widestring都用4个byet(即32Bits)来存储字符长度,
代码演示:

var

S: String;
L: Integer;
begin
S := 'lxpbuaa';
L := PInteger(Integer(S) - 4)^;
//或者 L := PInteger(PInteger(@S)^ - 4)^;
//或者 L := PInteger(PInteger(Addr(S))^ - 4)^;
//最终得到L = Length(S) = 7;
end;
4. set类型
5. dynamic array类型
动态数组内存被分为几个域:

偏移/byet
内容
-8存储引用计数
-4存储元素数目
0..Length*(元素的大小)-1存储存储元素值
6. Variant类型
Variant内部存储为TVarData类型的记录。TVarData被定义在system单元。
Vtype用来存储数据的类型。
另外一个字段为8字节大小,用来存储实际数据或者指向该实际数据的指针。
根据这两个字段,一个variant可以和其他数据类型相互转化。

3.1.4强数据类型与类型转化
Object pascal十一种“强数据类型”语言。就是严格区分不同的数据类型并不总是允许不同类型数据直接赋值。
。。。
数据类型转化的方法
1. typecasting(类型强制转化)
2. pointers(指针)
3. variants(可变类型)
4. variant parts in records(变体记录):不做介绍用到时讨论
5. absolute addressing(绝对地址):同上

关于过程和函数,类等等在下节介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息