




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
9.1 指针类型的声明指针类型在任何语言中都是比较难以理解也是比较灵活的一种数据类型 指针常是它所指的变量的内存地址。声明指针类型的语法如下: Type 指针类型标志符=基类型; 其中,指针类型标志符即是指针类型名,基类型可以是简单类型,如整型,实型,字符型等,也可以是结构类型,如数组,记录,集合等。指针类型声明示例:Type Tr = Integer; PI = real; Word = Record Name: String10; Age: Integer; Scores: Real; End;BytePtr = Byte;WordPtr = Word; 上例中,声明了4个指针类型。其中,BytePtr是一个指向字节类型的数据;而WordPtr是一个指向记录类型Word的数据 Object Pascal不要求基类型一定是要在前面已声明的,也可以是一个标志符,然后在同一个模块内声明基类型。声明了指针类型后,就可以声明指针类型的变量,如: Var BP: BytePtr; WP: WordPtr;或: Var BP: Bytel;指针所指的基类型可以是简单类型,也可以是构造类型,如: Type Student = Record Name: String; Age: Integer; Sex: (Man, Woman); End; Var StuPtr: Student; 上例中,声明了一个指向记录类型的Student指针变量StuPtr,以后程序中就可以使用StuPtr来表示记录类型Student的动态变量。要访问其中的Name字段,可以写成StuPtr.Name。这里介绍动态变量的概念,动态变量的构成是用指针类型的变量标志符后加一个“”符号,就构成指针所指向的基类型的动态变量,如上例中的StuPtr就是Student的动态变量。 与通常的变量一样,一旦声明了指针变量,编译器将给指针分配存储单元,但存储单元中的值尚未确定。要想让指针指向确定的地址,必须通过赋值语句或New标准过程来实现。如:Label 1,2,3,4,5;Var M: Integer; X1, X2: Integer;Begin 1: M:= 20; 2: X1:= M; 3: New(X2); 4: X2:= 150; 5: Dispose(X2);End;执行上述语句段时,若编译器给变量M分配的内存地址为$011001,那么,执行标号为3的语句后,指针变量X1和变量M的关系如下:X1 $011001 $01100120 即指针变量X1的值为变量M的内存地址。 执行语句3时,编译器首先在内存中分配适宜存放指针X2所指向的数据(这里为正数)的一组存储单元(假设为$01100A),然后将这组单元的首地址写入指针X2。这里X2称为动态存储变量。使用New建立了动态存储变量后,它的值是不确定的,以后可以将某个整数值存储在该单元中。X2 $01100A $01100A?X2 $01100A $01100A150 执行语句5后,标准过程Dispose将释放由New分配的内存单元。在程序段中,标号过程New和Dispose应配对使用。当用New分配的动态存储空间不再使用时,应及时地释放所分配的存储空间,避免发生错误。如果分配存储空间时内存不够,将触发一个异常错误(EoutOfMemory),程序随即终止。上例中的运算符“”和“”专用于指针类型,分别称为取址和应用运算符。9.2 指针的运算Delphi提供了专门的过程和函数来操作指针,这些过程和函数是:New过程,操作符,PTR函数,GetMem过程1) New过程 New是Object Pascal中的标准例程(在System单元中声明),用于在应用程序中为动态变量分配一块区域,并把该区域的地址赋给指针变量。所分配区域的大小由指针所指的类型决定。如果分配存储空间时内存不够,将触发一个异常错误(EoutOfMemory)New过程的声明如下: Procedure New(Var P: Pointer); 其中P是一个指针变量,调用了New过程后,程序就可以用P作为指针所指类型的动态变量。相应地,当程序不再需要使用动态变量时,就应当调用标准例程Dispose删除New创建的动态变量,并释放所分配的空间。程序示例如下:Type PlisEntry = TlistEntry; TlistEntry = Record Next : PlistEntry; Text : String; Count: Integer; End;Var List, P: PlistEntry;Begin New(P); P.Next := List; P.Text := Hellow world; P.Count := 1; List:= P; Dispose(P); End;2) 操作符 操作符是一个一元操作符,用于获得操作数的的地址,后面的操作数可以是变量,过程,函数或类型中的方法,程序示例如下:Procedure ChangeValue(X: Integer);Var IntPtr: Integer;Begin Intptr:= X; Writeln(IntPtr); IntPtr:= 20;End;如果主程序如下:Var Param: Integer;Begin Param:= 10; ChangeValue(Param); Writeln(Param);10End; 上例中,ChangeValue过程首先声明了一个指向整数类型数的指针IntPtr,然后用操作符取出X的地址赋予IntPtr指针,并显示IntPtr指针指向的数,最后改变这个数。3) PTR函数 PTR 函数是Pascal中的标准例程,用于把一个指定的地址转换为指针,语法为: Function Ptr(Address: Integer): pointer;其中,Address是一个整数,用于表示一个32位地址,函数执行的结果是把32为地址转化为指针。4) GetMem过程 GetMem 过程也是Pascal中的标准例程,类似于New,用于在应用程序中堆栈中为动态变量申请一块指定大小的区域,并把该区域的地址赋予指针变量。 语法为: Procedure GetMem(var P:Pointer;Size:Integer); 其中P是一个指针变量,Size指定区域的字节数。所分配区域的大小由指针变量P的基类型决定。如果在应用程序堆栈中没有足够的内存空间供分配,将触发EOutOfMemory异常。如果程序不再需要该动态变量时,可以调用标准例程FreeMem释放该变量分配的内存空间。程序如下:Var F: file; Size: Integer; Buffer: Pchar;Begin AssignFile(F, test.txt); Reset(F,1); Try Size:= FileSize(F); GetMem(Buffer, Size); Try BlockRead(F, Buffer,Size); ProcessFile(Buffer, Size); Finally FreeMem(Buffer); End; Finally CloseFile(F); End;End; 上例打开一个名字Test.txt为的文件,并把文件读入动态分配的缓冲区,缓冲区大小为文件的大小,然后对文件进行处理,最后释放动态分配的缓冲区,并关闭文件。Pascal中有一个特殊的保留字nil,这是一个空指针常量,当指针的值为nil时,表示指针当前没有指向任何动态变量。值为nil的指针变量不能访问动态变量。指针变量除了能被赋值外,还能进行相等或不相等的比较,比较只限于类型兼容的指针变量之间。当两个指针指向同一个对象时,指针才相等。9.3 无类型指针无类型指针是指指针变量在声明时没有指明基类型。无类型指针在声明中只使用Pointer。如:Var PAnyPOint: Pointer; 指针PAnyPOint可以指向任何变量类型。无类型的指针的作用是它可以指向任何类型,但是,不能用指针变量符后加“”的形式引用它的动态变量。要引用Pointer类型指针指向的变量,应先将其转换为确定的类型,如:Type Tpinte: Integer;Var M, N: Integer; P: Pointer; Pt: Tpinte;Begin M:= 150; P:= M; Pt:= Tpinte(P) N:= Pt;End;9.4 字符指针类型字符指针类型即PChar 数据类型,是一个指向以NULL(不是零)字符结尾的字符串的指针。这种类型主要用于与外部函数中如在Windows API 中所用的函数兼容。与Pascal字符串不同,Windows和C字符串没有一个长度字节。取而代之的是它们0字节索引开始,以一个NULL结束。Pascal RTL字符函数根据长度决定存储在字符串变量中的字符数目。在Pascal中使用这些函数就需要PChar类型变量。内存将分配给变量并被所需函数使用。 除了PChar外,Delphi还包含PAnsiChar和PWideChar数据类型。 PAnsiChar数据类型是一个指向以NULL字符结尾的AnsiChar字符串的指针,在Delphi中,PCHAR等同于PAnsiChar。 PWideChar数据类型是一个指向以NULL字符结尾的WideChar字符串的指针,用于UniCode字符集。 实际上,PAnsiChar和PWideChar数据类型的定义为:Type PansiChar = AnsiChar; PwideChar = WideChar; Pchar = PansiChar;字符串类型与PChar类型赋值兼容,即一个字符串可以直接赋给一个PChar类型的变量,如:var P: Pchar; Begin P:= Hello World;End;9.5 动态存储结构的实现指针常用于描述动态存储结构的实现。动态存储结构中常用的有链表,堆栈,队列等存储结构。可以把堆栈和队列看成特殊的链表 本节只是简单介绍一下如何利用指针和记录来实现链表结构。 链表是一组元素的序列,在这个序列中每个元素总是与他前面的元素相链接(第一个元素除外)。这种关系可以通过指针来实现。链表中的元素称为节点,第一个节点称为表头,最后一个称为表尾。指向表头的指针称为头指针,在这个头指针里存放着表头的地址。节点一般用记录来描述,描述节点的记录至少含有两个域,一个用来存放数据,该域的类型根据要存放的数据而定,称为值域;另一个用来存放下一个节点的地址,称为指针域。表尾不指向任何节点,其指针的值为NIL。如图:应用Object LPascal的指针和记录类型,图示的链表可以声明如下:Type Node:= Record; Data: Char; Next: Node; End;Var Head: Node; 或者:Type Link = Node; Node:= Record Data: Char; Next: Node; End;Var Head: Link; 链表中相邻节点的地址是不连续的。当表头指针失去了指向表头的地址后,就无法找到整个链表,从而不能再对链表进行操作。同样,当任一节点中的指针失去了下一个节点后,链表就会断开,后边的节点就会全部消失。 若让表尾节点原有的空指针指向表头节点,就成为循环链表。如果链表的各节点既有指向前一个节点的指针又有指向后一个节点指针,这时的链表就称为双向链表。 链表可以描述许多实际问题,区别只是链表的值域有所不同。 对链表的操作有查找,插入,删除等。对于插入和删除操作来说,链表是很实用的数据结构。不论在链表的什么位置插入或删除节点,只需修改相应的指针。不必像顺序存储的数组那样需要移动数组中的每个元素。但对于链表来说,只有指针对用户来说是可见的。因此,要访问链表中某个节点的数据,必须从头指针开始依次搜索要访问的元素。 队列和堆栈是特殊的链表。所谓队列就是一个先入先出表。在该表中只允许在表头插入节点,在表尾删除节点。向队列中插入节点称作入队,新节点入队后就成为队列的新表尾;从队列的表头删除节点称为出队,出队后,其后继节点成为表头。由于队列的插入和删除操作分别在两端进行,所以要删除的节点将是队列中最先进入的节点。堆栈则允许在链表的表头进行插入和删除操作。这里表头称为栈顶,另一端为栈底。向一个堆栈中插入新节点成为入栈或压栈,新节点插入后成为新的栈顶节点;从堆栈中删除节点称为出栈或退栈,它是把栈顶节点删除掉,是其相邻的节点成为新的栈顶。由于插入和删除仅在栈顶一端进行,后进栈的节点必然会先被删除,所以堆栈又称为先进后出表。【例9-1】 下列是一个关于在链表中利用指针处理字符串的程序。 分析:该程序的功能是通过一个文本编辑框输入一个字符串,输入后将该字符串存入一个链表中。每输入一次,在链表中新添一个节点。输入一些字符串后,单击“显示”按钮将输入的所有字符串显示在一个列表框中。通过文本编辑框输入的所有字符串显示在一个列表框中。通过文本框输入要查找的字符串,然后单击“删除”,将该字符串从链表中删除。此时再按下“显示”按钮,显示新的链表中的数据。 设计时添加一个组件Edit, 名为Edit1,添加一个组件Memo,名为Memo1, 三个Button组件:“删除”名为btnDel,“显示”名为btnList,“退出”名为btnQuit。 为了实现程序的功能,先声明一个全程的链表结构类型并命名一个该类型变量。这些在窗体单元的实现部分的开始处进行实现:implementation$R *.dfmtype pLink = Node; Node = record Data: string30; Next: pLink; end;var Head: pLink;当程序创建窗体时进行变量Head的初始化:procedure TForm1.FormCreate(Sender: TObject);begin Head:= Nil;end; 当在文本编辑框中输入字符串并按下回车键后,在链表上添加一个新节点,并将输入的数据保存在该节点的数据域中,这个功能通过Edit1的OnKeyPress处理过程实现:procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);var tempP, P: pLink;begin if Key = #13 then /如果按下回车键 begin New(tempP); /创建一个节点 tempP.Data:= Edit1.Text; tempP.Next:= Nil; if Head = Nil then /如果链表为空表 begin New(Head); /创建链表 Head:= tempP; end else begin /如果链表不为空表 P:= Head; while P.Next Nil do /找表尾 P:= P.Next; P.Next:= tempP; /将新节点添加到表尾 end; Edit1.Clear; /清空编辑框 Edit1.SetFocus; /置编辑框为活动焦点 end;end;当按下“显示”时,在列表框ListBox1中显示链表中所有节点数据域中的数据:procedure TForm1.btnListClick(Sender: TObject);var P: pLink;begin Memo1.Clear; P:= Head; While P Nil do begin Memo1.Lines.Add(P.Data); P:= P.Next; end;end; 在E
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中国田七花香烟市场调查研究报告
- 2025年中国多制式电视监视器市场调查研究报告
- 2025-2030育林产业市场发展分析及前景趋势与投资战略研究报告
- 2025-2030羽绒服行业市场深度分析及发展策略研究报告
- 2025-2030纳米二氧化钛行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030笔记本电脑产业政府战略管理与区域发展战略研究咨询报告
- 2025-2030电压探针行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030涡轮式粉碎机行业市场发展分析及发展趋势与投资管理策略研究报告
- 2025-2030海绵和擦洗垫行业市场现状供需分析及重点企业投资评估规划分析研究报告
- 2025-2030流行性感冒行业市场现状供需分析及投资评估规划分析研究报告
- 给小学生讲医疗知识
- 热力管道吊装专项方案
- 女性经期管理
- 财务管理有趣的知识普及
- 云肩完整版本
- 2024年10月自考04741计算机网络原理试题及答案含评分参考
- 数字化技术在中国会计师事务所中应用的研究报告 2024
- 人民医院手术室装修及安装方案
- 《兰亭集序》公开课一等奖省公开课获奖课件说课比赛一等奖课件
- 2025届高考专题复习:课内外古诗词对比阅读
- 企业创业孵化与创新基地管理制度
评论
0/150
提交评论