【5.高级数据类型】8.动态使用指针变量

本文详细介绍了ObjectPascal中的动态指针变量使用,包括New与Dispose、GetMem和FreeMem的过程,以及如何通过链表实例展示其在动态存储结构中的应用。通过链表生成随机数并计算统计信息的示例代码加深理解。
摘要由CSDN通过智能技术生成

8.动态使用指针变量

8.1New与Disponse过程

当指针变量声明后没有使用@运算符赋值时,此时的指针变量称为动态指针变量,动态指针变量在访问之前必须首先分配内存单元。Object Pascal 提供了标准过程来处理:

New,用来为动态指针变量分配内存单元,并把该单元的地址赋值给指针变量,所分配的单元大小由指针所指向的类型决定。如果应用程序的堆栈已没有足够的空间,则触发EoutOfMemory异常。调用格式:

New(<指针变量名>)

如:

var
    p: ^integer;
begin
    New(p);
end;

此时就可以使用“p^”来访问这个整型的动态指针变量。

当程序不再使用动态指针变量时,可以调用标准过程 Dispose 删除 New 所创建的动态指针变量,并释放所分配的内存单元,调用格式:

Dispose(<指针变量名>)

如:

var
    p: ^integer;
begin
    New(p);
    p^ := 7;
    Dispose(p);
end;

8.2GetMem和FreeMem过程

标准过程 GetMem 用于为动态指针变量申请一块指定大小的内存区域,并把该区域的起始地址赋值给指针变量。如果应用程序的堆栈已没有足够的空间,则触发EoutOfMemory异常。调用格式:

GetMem(<指针变量名>, <区域大小>)

当程序不再使用动态指针变量时,可以调用标准过程 FreeMem删除动态指针变量,并释放所分配的内存单元,调用格式:

FreeMem(<指针变量名>)

8.3动态指针变量的应用

动态指针类型,常用来描述动态存储结构的实现。如:链表、堆栈、队列等。本节简单介绍链表结构。

链表是一组元素的序列,在这个序列中,每个元素总是与前面的元素相链接,这种链接就可以使用指针来实现。如下图:

 

链表中的元素称为节点,第一个节点称为表头,最后一个节点称为表尾。

指向表头的指针称为头指针,存放表头的地址。表尾不指向任何节点,其指针的值为Nil。

节点一般使用记录类型来描述,描述节点的记录至少包含两个域:值域,存放数据的域,其类型由存储的数据类型决定;指针域,存放下一个节点的地址。

如:

type
    Node = record
        data: integer;
        next: ^Node;
    end;
var
    head: ^Node;

或者:

type
    Link = ^Node;
    Node = record
        data: integer;
        next: ^Node;
    end;
var
    Head: Link;

注意:在上面的代码中,Link = ^Node; 语句在定义时,Node还没有被定义,在Object Pascal中,这种情况只对指针类型的定义适用,也就是说:指针所指的对象可以被后定义

8.4动态指针的使用

示例:用链表实现随机产生10个整数,计算和、平均值、最大值、最小值。界面如下图:

 

示例代码:

type
  Pointer = ^Node;
  Node = record
    value: Integer;
    next: Pointer;
  end;
​
var
  Head: Pointer;
​
procedure TForm1.FormCreate(Sender: TObject);
var
  p: Pointer;
  i: integer;
begin
  // 窗体创建时对链表进行初始化
  New(Head);
  p := Head;
​
  for i := 1 to 10 do
  begin
    New(p^.next);
    p := p^.next;
  end;
  p^.next := nil;
end;
​
procedure TForm1.FormDestroy(Sender: TObject);
begin
  // 窗体销毁时对链表进行释放
  Dispose(Head);
end;
​
procedure TForm1.Button1Click(Sender: TObject);
var
  p: Pointer;
begin
  // 链表中存放数据
  Memo1.Lines.Clear;
  Edit1.Text := '';
  Edit2.Text := '';
  Edit3.Text := '';
  Edit4.Text := '';
​
  randomize();
  p := Head;
  while p^.next <> nil do
  begin
    p^.value := random(100);
    p := p^.next;
  end;
​
  p := Head;
  while p^.next <> nil do
  begin
    Memo1.Lines.Add(inttostr(p^.value));
    p := p^.next;
  end;
end;
​
procedure TForm1.Button2Click(Sender: TObject);
var
  p: Pointer;
  sum, max, min: Integer;
  mean: Real;
begin
  // 计算
  p := Head;
​
  sum := 0;
  max := p^.value;
  min := p^.value;
​
  while p^.next <> nil do
  begin
    sum := sum + p^.value;
​
    if p^.value > max then max := p^.value;
    if p^.value < min then min := p^.value;
​
    p := p^.next;
  end;
​
  mean := sum / 10;
​
  Edit1.Text := inttostr(sum);
  Edit2.Text := floattostr(mean);
  Edit3.Text := inttostr(max);
  Edit4.Text := inttostr(min);
end;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Janeb1018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值