delphi_动态数组
delphi packedrecord使用示例

delphi packedrecord使用示例在Delphi 中,`packed record` 是一种特殊的记录类型,它可以用于在固定大小的数据结构中存储可变大小的数据。
`packed record` 类型的字段会自动进行压缩,以适应其父数据结构的固定大小。
下面是一个使用`packed record` 的示例:```delphitypeTMyPackedRecord = packed recordName: array[0..255] of AnsiChar;Age: Integer;end;varMyPackedRecord: TMyPackedRecord;MyOtherPackedRecord: packed recordID: Integer;OtherData: array[0..10] of Byte;end;begin// 填充TMyPackedRecord 类型的实例 := 'John Doe';MyPackedRecord.Age := 30;// 填充TMyOtherPackedRecord 类型的实例MyOtherPackedRecord.ID := 123;MyOtherPackedRecord.OtherData := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];end.```在这个示例中,我们定义了两个`packed record` 类型:`TMyPackedRecord` 和`TMyOtherPackedRecord`。
`TMyPackedRecord` 包含一个变长字符串和一个整数,而`TMyOtherPackedRecord` 包含一个整数和一个长度为11 的字节数组。
注意,由于使用了`packed` 关键字,每个字段都会根据父数据结构的长度进行压缩。
因此,实际分配的内存空间将根据字段的大小和顺序进行调整。
在使用`packed record` 时,需要注意以下几点:1. `packed record` 的字段不会进行内存对齐,而是紧密相邻排列。
delphi中Socket程序发送PChar类型结构体的问题

delphi中Socket程序发送PChar类型结构体的问题delphi中Socket程序发送PChar类型结构体的有趣问题10-25 [:(] 我想通过Socket在局域网传输数据,而且这个数据可能是命令可能是字符串或者其他类型数据,所以我定义了一个如下记录类型:TSocketMessage = recordMsg: string[255];end;(其他数据域暂时忽略不谈,反正我觉得数据和命令同时传输时用记录类型方便一些)然后在客户端把要传输的字符串装到这个记录里面,用ClientSocket1.Socket.SendBuf方法发出去,然后在服务器端用ServerSocket1.Socket.ReceiveBuf方法接收这个记录,并将记录里的字符串显示出来一切正常,以下程序能正确传输信息。
问题来了,因为我传输的数据量可能很大,所以记录域Msg string[255]太小了,所以我改类型为string或者PChar类型,结果出现什么都发不过来或者是乱码的问题,请问为什么?以下是程序源码,unit1是服务器端,unit2是客户端,unit3是公共单元大家需要将'192.168.100.148'这个改成自己机器的IP地址。
unit1程序窗口上放了ServerSocket1,Button1,memo1unit2程序窗口上放了ClientSocket1,edit1,button1,button2,button3--------------------------------unit Unit3;interfacetypeTSocketMessage = recordMsg: string[255]; //我想把此行改成Msg: PChar;结果什么消息都不能发送了end;implementationend.--------------------------unit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ScktComp, StdCtrls;TForm1 = class(TForm)ServerSocket1: TServerSocket;Memo1: TMemo;Button1: TButton;procedure ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementationuses Unit3;{$R *.DFM}procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);varpack: TSocketMessage;beginSocket.ReceiveBuf(Pack, SizeOf(Pack));memo1.lines.add( Pack.Msg );end;procedure TForm1.Button1Click(Sender: TObject);beginServerSocket1.Port:= 8090;ServerSocket1.Open;end;end.------------------------------unit Unit2;interfaceWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ScktComp;typeTForm2 = class(TForm)ClientSocket1: TClientSocket;Button1: TButton;Edit1: TEdit;Button2: TButton;Button3: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button3Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm2: TForm2;implementationuses Unit3;{$R *.DFM}procedure TForm2.Button1Click(Sender: TObject);beginClientSocket1.Port:= 8090;ClientSocket1.Address:= '192.168.100.148';ClientSocket1.Active:= true;end;procedure TForm2.Button2Click(Sender: TObject);varpack: TSocketMessage;beginpack.Msg := Edit1.Text; //此行改成pack.Msg := PChar(Edit1.Text); ClientSocket1.Socket.SendBuf(Pack, SizeOf(Pack));end;procedure TForm2.Button3Click(Sender: TObject);beginif ClientSocket1.Active thenShowMessage('true')elseShowMessage('False');end;end.1:用string或pchar的话,是不是SizeOf(Pack)会有问题随便说说,主要是听课!2:procedure TForm1.ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);varS: string;beginSocket.ReceiveText(S);memo1.lines.add(S);end;procedure TForm2.Button2Click(Sender: TObject);varpack: TSocketMessage;beginpack.Msg := PChar(Edit1.Text);ClientSocket1.Socket.SendBuf(Pack.Msg^, StrLen(Pack.Msg));end;string[0..Len]已经是静态分配内存了,而string or PChar,则无,所以sizeof(s) // s[0..len]是求出长度sizeof(s) // s: string or PChar,则永远=43:像Char, Byte, Word, Integer, DWORD以及静态分配的数组,为堆分配的内存,也就是一定义,就已经确定了它的内存范围,而string, PChar, Pointer, array of TDataType则不是,是需要在运行时刻,通过函数取得。
delphi指针大全

目录1 DELPHI的指针-引用.................................................................................- 1 -2 delphi的“引用/值”模型..............................................................................- 5 -3 谈谈Delphi 的类型与指针....................................................................- 13 -4 Delphi 7 指针数据类型............................................................................- 17 -5 delphi中的Pchar指针.............................................................................- 19 -1 DELPHI的指针-引用大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。
因此,说指针是C语言的灵魂,一点都不为过。
同时,这种说法也让很多人产生误解,似乎只有C语言的指针才能算指针。
Basic不支持指针,在此不论。
其实,Pascal语言本身也是支持指针的。
从最初的Pascal发展至今的Object Pascal,可以说在指针运用上,丝毫不会逊色于C语言的指针。
以下内容分为八个部分,分别是一、类型指针的定义二、无类型指针的定义三、指针的解除引用四、取地址(指针赋值)五、指针运算六、动态内存分配七、字符数组的运算八、函数指针一、类型指针的定义。
对于指向特定类型的指针,在C中是这样定义的:int *ptr;char *ptr;与之等价的Object Pascal是如何定义的呢?varptr : ^Integer;ptr : ^char;其实也就是符号的差别而已。
Dephi常用函数查询

一、数据类型转换函数在我们编写程序当中,根据不同情况,会使用到多种数据类型。
当要对不同的类型进行操作时,必须要将不同的类型转换成同样的类型。
因此熟练地掌握数据类型的转换是非常重要的。
1.FloatToStr功能说明:该函数用于将“浮点型”转换成“字符型”。
参考实例:Edit1.Text := FloatToStr(1.981);2.IntToStr功能说明:该函数用于将“整数型”转换成“字符型”。
参考实例:S := IntToStr(10);(注:S为String类型变量。
)3.IntToHex功能说明:该函数用于将“十进制”转换成“十进制”。
该函数有二个参数。
第一个参数为要转换的十进制数据,第二个参数是指定使用多少位来显示十六进制数据。
参考实例:Edit1.Text := IntToHex('100', 2);执行结果,Edit1.Text等于64。
注意:Delphi没有提供专门的“十六进制”转换为“十进制”的函数。
使用StrToInt函数可以实现这个功能。
具体代码是:I := StrToInt('S' + '64'); 这时I等于100。
加上一个'S'即可将“十六进制”转换为“十进制”。
4.StrToInt功能说明:该函数用于将“字符型”转换成“整数型”。
参考实例:I := StrToInt('100');注意:不能转换如StrToInt('ab')或StrToInt('好')这样的类型,因为他们并不存在数字型。
5.StrToFloat功能说明:该函数用于将“字符型”转换成“浮点型”。
参考实例:N := StrToFloat(Edit1.Text);注意:Edit1.Text中的内容为1.981(凡在Edit控件中显示的文本均为字符串)。
N为Do uble类型,用于保存转换后的浮点型数据。
delphi遍历循环

在Delphi 2009 中, for in 循环都能用在什么地方?一、遍历TStringsvarList: TStrings;s: string;beginList := TStringList.Create;maText := 'aaa,bbb,ccc';for s in List doShowMessage(s);List.Free;end;二、遍历数组varArr: array[0..2] of Byte;i: Integer;b: Byte;beginfor i := Low(Arr) to High(Arr) doArr[i] := Random(MAXBYTE);for b in Arr doShowMessage(IntToStr(b));end;三、遍历子界{例1}varsub: 0..9;str: string;beginstr := '';for sub in [Low(sub)..High(sub)] dostr := str + IntToStr(sub);ShowMessage(str); {0123456789}end;{例2}typeTSub = 'A'..'G';varsub: TSub;str: string;beginstr := '';for sub in [Low(sub)..High(sub)] dostr := str + sub;ShowMessage(str); {ABCDEFG}end;{例3}varsub: Byte; {Byte 应该算是个 0..255 的子界}num: Cardinal;beginnum := 0;for sub in [Low(sub)..High(sub)] doInc(num, sub);ShowMessage(IntToStr(num)); {32640} end;四、遍历枚举typeTEnum = (Red,Green,Blue);varenum: TEnum;count: Integer;begincount := 0;for enum in [Low(enum)..High(enum)] do Inc(count);ShowMessage(IntToStr(count)); {3} end;五、遍历集合typeTEnum = (Red,Green,Blue,Yellow);TSet = set of TEnum;varset1: set of TEnum;set2: TSet;elem: Tenum;count: Integer;beginset1 := [Red, Yellow];count := 0;for elem in set1 do Inc(count); ShowMessage(IntToStr(count)); {2}set2 := [Red..Yellow];count := 0;for elem in set2 do Inc(count); ShowMessage(IntToStr(count)); {4} end;六、遍历字符串varstr: string;c: Char;beginstr := 'ABCD';for c in str doShowMessage(c);end;。
delphi

第6章常用控件和基础编程
6.1标准类控件及应用编程 1.标准类控件standard类:进行所有的引 用系统如工程计算系统,数据库系统都要 用到的一类控件 6.1.1主菜单控件mainmenu 生成主菜单的工具是标准页面(standard) 中的主菜单控件
ห้องสมุดไป่ตู้
数据表的安全设置
密码可以是针对整个数据表结构,也可以 针对某一字段 主密码:控制对整个数据表的访问 辅助密码:用户组中不同访问级的用户的 密码 在系统中创建一个专用的权限认证窗口,可 以对系统主管和其他人进行权限认证,及 对权限进行维护和修改
2.2数据表的操作
1.数据表的数据编辑:数据库桌面管理-Fileopen-table-选择表-单击打开-桌面主菜单tableedit data-可以进行修改 2.显示数据表结构信息:table-info structure 2. table-info 3.修改数据表结构:table-restructure-… 4.数据导航工具与数据编辑工具:
窗体的基本作用: 1是替他对象的载体 2系统功能模块的表现和系统功能的载体 3窗体对系统有极大的修饰作用,窗体制作 很大程度上决定系统质量
5.1窗体的设计方法 5.1.1父子窗体简介
1.父窗体:fsMDIForm系统设计时,第一次 创建的窗体 功能:1用作启动画面2作系统权限认 证窗体。3用于系统的主控界面 改变主窗体:project|options|forms 2.从窗体或子窗体fsMDIChild
一个工程可能有一个或多个窗体或单元, 但仅有一个工程名称
3.3.2工程创建与其他应用举例
1左对齐:edit|align|选择left side|单击ok 垂直宽度相等:space equally 2.扩充标签和编辑控件:edit|copyedit|paste 3.控件排序:edit|tab order 4.锁定控件:edit|lock controls 5利用视图菜单对控件布局: view|Alidnment palette
基于Delphi的位置随机显示技术
第2 3卷 第 1期
20 0 2年 3月
淮
北
煤
师
院
学
报
C l g ol e e
Vo . 3 Nn 1 12 M丑 2 0 L 0 2
Ju n l f Hu i e a Id sr l c ∞ o r a o ab i Co l n u t 1 y 朗 h
淡 出式 、 随机 式 显示 , 则较 为复杂 , 因为此类 图形 显示 无 明确 的规律 . 文 以位 图的随机 显示 本 为பைடு நூலகம் , 解决 了此类 图形 显示 中涉及 的两个 主要问题 : 一是 避免显示 重复像 素; 二是 确定所 有像 素均 已显 示 完 毕 的条 件
2 实 现 环 境 及 算 法 思 想
及 到的关 键 问题 及 其解 决方法 . 关 键词 : ep i位 图 ; 素; D lh; 像 随机 显示
分 类 号: P 1 T32 文 献 标识码 : A 文章 编号: 0 0— 2 7(0 2 0 10 2 2 2 0 ) 1—0 2 0 7—0 3
l 问题 的 提 出
be i gn
I : / 初 始 化 计 数 器 =O /
Rad mi no
// 始化 随机数 发生 器 初
Btm : T i p ce t; / 动态 创 建一 个位 圈对象 , l 口 n bt ra e / 接收 一 幅位 图的 所有像 累
I p n it rd ao e ̄ ue te fe e p cu e ilg x t h n
本程 序在 Wi o s8 作系统下面 的快速编程 工具 D lh n w9 操 d e i p 5中得 到实现 , e h Dl i p 5是一个 面 向对象 的可视化 编程工具 , 其提 供了大量 的可视 化控件模板供 用户 使用 , 大方便 了用户 开 极 发 Wi o s n w 应用程 序 . D lh5中, 一组专 门的对 象 和控件 用来 绘制 图形, d 在 e i p 有 完成一 些简单 的 图像 处 理功 能 . 如 在设计 阶段 用 Th p 对 象绘 基本 图形 , 运行 阶段 用 Tm g 对 象装 例 sae 在 i ae 入 图像 文件 .本程 序 用到其 中的 T a vsT i a 对 象, 法 思想 是创 建一 个位 图对 象、 cn a 、bt p m 算 从外 存装 人 一幅位 图 然后 随机 地从位 图对象 中取像 素画到窗体 上, 直到所 有像素 有且 只有一 次被 取出并 画到窗体 上为止, 而实现 了位 图在窗体 上的随机显示 . 从
delphi数据类型指针
delphi数据类型指针序数类型序数类型包括整数、字符、布尔、枚举、子界等类型。
序数类型定义了一个有序的值的集合,集合中的每个值(除第一个)都有一个唯一的前驱值,每个值(除最后一个)都有一个唯一的后继值。
此外,每个值都有一个序号,类型中的序号决定值在类型中的顺序。
大多数情况下,如果一个值的序号为n,那么它的前驱值的序号为n - 1,后继值的序号为n + 1。
·对于整数类型,值的序号就是其自身整数值。
·子界类型保留了其基类型的序号。
·对于其他序数类型,默认情况下,第一个值的序号为0,下一个为1,等等。
枚举类型可以明确地忽略这一默认情况。
一些预定义函数作用于序数类型和序数类型标识符,下面是最重要的几个:函数参数返回值备注Ord序数表达式表达式的值的序号不要使用Int64类型参数(见编者注中的Ord函数中不要使用Int64类型参数)Pred序数表达式表达式的值的前驱值不要用于具有write过程的的属性Succ序数表达式表达式的值的后继值不要用于具有write过程的的属性High序数类型标识符或序数类型变量类型中的最大值也可以作用于短串和数组Low序数类型标识符或序数类型变量类型中的最小值也可以作用于短串和数组例如,High(Byte)返回255,因为Byte类型的最大值是255;Succ(2)返回3,因为3是2的后继。
标准过程Inc和Dec分别对序数变量递增和递减。
例如对于序数变量 I,Inc(I)等价于I := Succ(I),如果 I 是一个整数变量,还等价于I := I + 1。
使用指针、数组和串常量处理空结束串通常必需使用指针(见指针和指针类型)。
串常量对PChar和PWideChar类型是赋值兼容的,这两种类型也表示指向Char和WideChar类型空结束数组的指针的值。
例如,var P: PChar;...P := 'Hello world!';赋值语句将P指向包含空结束串’Hell world!’副本的内存区域。
Delphi中的泛型基础及简单应用
2010已发布很长时间了,口碑还不错,准备用它开发下一项目,但对泛型等新东西的认识还不够,就搜了一下,发现下面这篇文章,还不错,大家一起补补课吧!C++中的模板、C#等语言中泛型技术,给许多操作不同类型数据的软件人员提供了一个很好的方法。
其类型的“可变”性,让许多用过的软件人员所心喜。
但是在Delphi 2009以前的版本中,是从来没有的。
让许多不会用Delphi中TList的人员,大大的抱怨。
如果用好Delphi 中TList,其可用性,我个人认为,比其它语言中的泛型好用很多(当然对指针的应用和内存的分配、释放不了解的人除外)。
自从Delphi 2009的发布,给许多喜欢用泛型技术的软件人员,提供了方便。
由于Delphi 2009不太稳定,也没有过多的去用其泛型技术。
Delphi 2010发布以来,出现许多“Delphi 2010初体验,是时候抛弃Delphi 7了”的话语的满天飞,让我想一看其究竟。
闲话少说,Delphi 2010的泛型单元Generics.Defaults、Generics.Collections;重点还是Generics.Collections单元,其中有TArray泛型类、TList(列表的泛型)、TQueue(队列的泛型)、TStack(栈的泛型)、TDictionary (Hash Table哈希表的泛型)及其上述泛型所对应的TObject的泛型,非常广泛。
简单的泛型类应用:(转) -----------------------------------------------------------------------------------------------unit Unit1; interface uses Windows, Messages, SysUtils, V ariants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Edit1: TEdit; Edit2: TEdit; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); end; var Form1: TForm1; implementation{$R *.dfm}uses Generics.Collections; {Delphi 泛型容器单元}var Dictionary: TDictionary; {定义一个泛型TDictionary 类, 指定有Cardinal、string 构成}{建立}procedure TForm1.FormCreate(Sender: TObject); begin Dictionary := TDictionary.Create; Memo1.Clear; Button1.Caption := Button1.Caption + ' 添加'; Button2.Caption := Button2.Caption + ' 删除'; Button3.Caption := Button3.Caption + ' 尝试取值'; Button4.Caption := Button4.Caption + ' 清空'; Edit1.Clear; Edit2.Clear; Edit1.NumbersOnly := True; end; {释放}procedure TForm1.FormDestroy(Sender: TObject); begin Dictionary.Free; end; {添加}procedure TForm1.Button1Click(Sender: TObject); var key: Cardinal; value: string; str: string; k,v: Boolean; begin key := StrToIntDef(Edit1.Text, 0); value := Edit2.Text; if value = '' then value := 'Null'; k := Dictionary.Contains Key(key); {Key 是否存在}v := Dictionary.ContainsV alue(value); {V alue 是否存在}if not k then begin Dictionary.Add(key, value); Memo1.Lines.Add(Format('%d=%s', [key, value])); {同步显示}end; if k and not v then begin str := Format('key 已存在: %d=%s; 是否修改其值?', [key, Dictionary[key]]); if MessageBox(0, PChar(str), '提示', MB_OKCANCEL or MB_ICONQUESTION) = mrOk then begin//Dictionary[key] := value; {Dictionary[key] = Dictionary.Item[key]} Dictionary.AddOrSetV alue(key, value); {也可使用上一句} Memo1.Lines.V alues[IntToStr(key)] := value; {同步显示}end; end; if k and v then begin str := Format('%d=%s 已存在, 不能重复添加', [key, value]); MessageBox(0, PChar(str), '错误', MB_OK + MB_ICONHAND); end; Text := IntToStr(Dictionary.Count); end; {删除: Remove} procedure TForm1.Button2Click(Sender: TObject); var key: Integer; i: Integer; begin key :=StrToIntDef(Edit1.Text, 0); if not Dictionary.ContainsKey(key) then begin ShowMessageFmt('key: %d 不存在', [key]); Exit; end; Dictionary.Remove(key); Text := IntToStr(Dictionary.Count); {同步显示} i := Memo1.Lines.IndexOfName(IntToStr(key)); if i > -1 then Memo1.Lines.Delete(i); end; {尝试取值: TryGetV alue}procedure TForm1.Button3Click(Sender: TObject); var key: Integer; value: string; begin key := StrToIntDef(Edit1.Text, 0); if Dictionary.TryGetV alue(key, value) then ShowMessageFmt('key: %d 已存在, 其值是: %s', [key, value]) else ShowMessageFmt('key: %d 不存在', [key]) end; {清空: Clear}procedure TForm1.Button4Click(Sender: TObject); begin Dictionary.Clear; Text := IntToStr(Dictionary.Count); Memo1.Clear; {同步显示}end; end. -------------------------------------------------------------------------------- 自定义泛型应用:(转) -------------------------------------------------------------------------------- unit Unit1; interface uses Windows, Messages, SysUtils, V ariants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); end; var Form1: TForm1; implementation{$R *.dfm}type TArr= array[0..9] of T; {定义一个泛型数组} {虽然大家习惯用T 来泛指其他类型, 但使用其他合法的标识符也是可以的}{用作Integer} procedure TForm1.Button1Click(Sender: TObject); var Arr: TArr; i: Integer; begin for i := Low(Arr) to High(Arr) do Arr[i] := i * i; Memo1.Clear; for i := Low(Arr) to High(Arr) do Memo1.Lines.Add(Format('Arr[%d] = %d', [i, Arr[i]])); end; {用作string}procedure TForm1.Button2Click(Sender: TObject); var Arr: TArr; i: Integer; begin for i := Low(Arr) to High(Arr) do Arr[i] := StringOfChar(Char(i+97), 3); Memo1.Clear; for i := Low(Arr) to High(Arr) do Memo1.Lines.Add(Format('Arr[%d] = %s', [i, Arr[i]])); end; {用作Single}procedure TForm1.Button3Click(Sender: TObject); var Arr: TArr; i: Integer; begin for i := Low(Arr) to High(Arr) do Arr[i] := 100/ (i+1); Memo1.Clear; for i := Low(Arr) to High(Arr) do Memo1.Lines.Add(Format('Arr[%d] = %f', [i, Arr[i]])); end; {用作记录TPoint}procedure TForm1.Button4Click(Sender: TObject); var Arr: TArr; i: Integer; begin for i := Low(Arr) to High(Arr) do Arr[i] := Point(i, i*2); Memo1.Clear; for i:= Low(Arr) to High(Arr) do Memo1.Lines.Add(Format('Arr[%d] = (%d,%d)', [i, Arr[i].X, Arr[i].Y])); end; {用作类TButton} procedure TForm1.Button5Click(Sender: TObject); var Arr: TArr; i: Integer; begin for i := Low(Arr) to High(Arr) do begin Arr[i] := TButton.Create(Self); Arr[i].Name := Concat('Btn', IntToStr(i+1)); end; Memo1.Clear; for i := Low(Arr) to High(Arr) do Memo1.Lines.Add(Format('Arr[%d] is %s', [i, Arr[i].Name])); end; end.一、概述等了几百年,Delphi终于原生的支持泛型了。
Delphi试题含答案
Delphi试题含答案《可视化程序设计》试卷适⽤专业及层次(由出卷教研室填写):信息管理与信息系统、医学信息⼯程本科姓名:班级:学号:(此试卷共8页,答案请填写在答题纸上,答案填写在试卷上者答题⽆效)⼀、单项选择题(15分,每⼩题1分)1.⼀个Delphi应⽤程序必有⼀个⽂件和⾄少⼀个单元⽂件。
A.程序B.⼯程C.数据D.图形2.在窗体中完成多个控件整齐排列,应使⽤的操作是。
A.AlignB.Bring to frontC.ScaleD.Send to back3.下列不能⽤来定义⼦界类型是。
A.实型数据(Real)B.⽤户定义的任何顺序类型C.字符型(Char)D.整型(Integer)4.在事件处理程序中编写代码,可以处理edit编辑框中输⼊的字符,。
A.OnClickB.OnEnterC.OnMouseUpD.OnKeyPress5.关于变量,全局变量与局部变量名相同时,下列说法错误的是。
A.在过程之外是全局变量作⽤B.过程内部是局部变量作⽤C.在过程之外全局变量⽆作⽤D.在过程之外是全局变量作⽤⽽在内部是局部变量作⽤6.procedure和function的结构和功能相似,。
A.前者可以取代后者B.后者可以取代前者C.但前者有返回值,后者没有D.⼆者都可以返回⼀个值7.动态数组与静态数组的区别是。
A.是否是⼀维数组B.元素类型是否是整型C.定义时是否明确了数组元素的个数D.元素类型是否⼀致8.⽤于建⽴菜单项的加速键的字符是。
A.^B.#C.&D.@9.绘制封闭图形时,要指定填充⾊的颜⾊时,可以设置画布对象的属性。
A. pen.colorB. brush.colorC. pen.styleD. bursh.style10.BDE的中⽂含义是,它是数据库应⽤中的⼀种连接⽅法。
A.数据库连接B.数据库引擎C.数据库⽂件D.开放式数据库11.下列语句中,⽴即中断当前循环继续执⾏下⼀次循环的语句是。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态数组介绍----Delphi
自从有了动态数组,链表除了在教科书里出现外,已经很少在实际编程中被
使用了,事实也是如此,数组的确比传统链表快得多,而且也方便的多。
从 Delphi4起,开始了内建各种类型的动态数组支持。但是,对我们来说动态
数组支持似乎做的不够彻底,因为Delphi竟然连删除、插入、移动连续元素的
函数都没有提供,让人使用起来总觉得不够爽!!! 。作为一名程序员,我
们当然要有自己解决问题的能力,下面就让我们简单介绍一下Delphi 下的动态
数组。
在Delphi中,数组类型有静态数组(a : array[0..1024] of integer)、
动态数组(var a : array of integer)、指针数组(即指向静态数组的指针)
和开放数组(仅用于参数传递)。静态数组、指针数组有速度快的好处,动态数
组有大小可变的优势,权衡之下就有了折衷的办法,那就是定义的动态数组在必
要时转换为指针。
动态数组声明之后,只有下面几个函数可供操作:
1.设置数组大小,可以任意缩减或增加数组大小
Procedure SetLength(var S ; NewLength : integer);
2.取出连续元素,复制给另一个数组变量
Function Copy(s;Index,Count : integer) : array ;
3.取得数组大小及上下限
Function Length(s):integer;
Function High(x):integer;
Function Low(x):integer;
值得注意的是,不加const或var修饰的动态数组会被作为形参传递,而动
态数组用const修饰并不意味着你不能修改数组里的元素(不信你可以字自己在
程序中试试。还有一点是High函数调用了Length 函数,所以我们在获取数组
上限时最好直接用 Length(s) 函数。
动态数组在内存空间中占用4个字节. 动态数组在内存中的分配表如下:
偏移量 内容
-8 32-bit 引用计数
-4 32-bit 数组长度
0..数组长度 * (元素尺寸) - 1 数组元素 元素尺寸=Sizeof(元素类
型)
根据上面的分配情况,可以得到如下结果:
如果我们想要清空一个动态数组只需要把“数组长度”和“引用计数”清空即可。”
引用上面的一句话就是:“权衡之下就有了折衷的办法,那就是定义的动态数组
在必要时转换为指针。”下面是清空动态数组的函数:
procedure DynArraySetZero(var A);
var
P: PLongint; //占用4个字节,正好符合 32 位内存排列
begin
P := PLongint(A); // 指向 A 的地址
Dec(P); //P 地址偏移量是 sizeof(A),指向了数组长度
P^ := 0; // 长度清空
Dec(P); // 指向引用计数
P^ := 0; //计数清空。
end;
上面的函数就这么简单,而且效率也非常高。
下面让我们再来看看怎样删除动态数组中的元素,函数体如下:
{************************************
A 变量类型 , elSize = SizeOf(A)
index 开始删除的位置索引 ,Count 删除的数量
****************************************}
procedure DynArrayDelete(var A; elSize: Longint; index, Count:
Integer);
var
len, MaxDelete: Integer;
P : PLongint; //4 个字节的长整形指针
begin
P := PLongint(A);// 取的 A 的地址
if P = nil then
Exit;
{
下面这句完全等同于 Dec(P) ; len := P^ 因为 Dec(P) = Pchar(P) C 4 同样
是移动4 字节的偏移量,只不过后者按字节来移动 }
len := PLongint(PChar(P) - 4)^; // 变量的长度 ,偏移量 -4
if index >= len then //要删除的位置超出范围,退出
Exit;
MaxDelete := len - index; // 最多删除的数量
Count := Min(Count, MaxDelete); // 取得一个较小值
if Count = 0 then // 不要求删除
Exit;
Dec(len, Count);// 移动到要删除的位置
MoveMemory(PChar(P)+index*elSize , PChar(P)+(index + Count)*elSize ,
(len-index)*elSize); //移动内存
Dec(P); //移出 “数组长度”位置
Dec(P); //移出“引用计数” 位置
//重新再分配调整内存,len 新的长度. Sizeof(Longint) * 2 = 2*Dec(P)
ReallocMem(P, len * elSize + Sizeof(Longint) * 2);
Inc(P); // 指向数组长度
P^ := len; // new length
Inc(P); // 指向数组元素,开始的位置
PLongint(A) := P;
end;
对上面的例子,我们需要注意的是 elSize 参数 ,它必须是
SizeOf(DyArray_Name),表示元素所占用的字节数。
相信看了上面的例子后,对于动态数组的拷贝,移动想必也可以自己实现了
吧
后续:
其实,Delphi 对许多类型的内存分配都很相似,比如 string 类型,其实它
和动态数组是很相似的,我们完全可以把它拿来当成动态数组。实质上 string
是 Pchar 的简易版本。不管怎么说,了解一些内存的分配对我们这些开发人员
来说还是有一些好处的。