地址和指针

来源:互联网 发布:windows 搭建http代理 编辑:程序博客网 时间:2024/05/22 13:57
 地址和指针
在学习Delphi程序设计时,地址的概念非常重要,它是理解指针变量的基础。所谓地址就是内存某个存储单元在内存中的位置,而这个位置是相对于内存中第一个存储单元而言的。如果将内存中第一个单元的地址记为0,第二个单元的地址记为1,则第1000个单元的地址就可以记为999。当然,这是一种最简单的记法,在执行应用程序时,实际的地址记法比较复杂,但它们的基本概念完全相同。另外,需要注意的是,只有在程序被加载到内存中开始执行时,程序中的所有变量才在内存中有了实际的对应存储单元,而此时的内存地址才具有实际意义,但编写程序的语言已经将这些底层的复杂问题都隐藏起来了,程序只要使用指针变量来表示指针就可以,不需要关心实际内存的地址。
指针就是用来表示内存地址的变量类型。实际上,绝大多数变量的地址是由程序语言自己来维护的,程序员不需要为这些变量的地址维护变量。指针是程序员为了管理某些与内存密切相关的变量而引入的一种变量类型,它专门用来记录内存中某段存储空间的起始地址的地址值,从而可以方便地找到这段存储空间,进而访问它的内容。
动态数组变量就是一种指针类型变量。数组在内存中是存放在一起的,即数组的多个成员是按照一定的顺序在内存中放在一起的,而动态数组变量就是一个指向这块内存起始地址的指针变量,通过调用这个指针变量,就可以访问数组的内容,前面已经给出了动态数组变量的用法。为了更加深入的说明这种情况,下面给出一个更为明显的例子:
var
  I: Integer;
  StutCount: Integer;
  ScoreList, MyScoreList: array of Integer;
begin
  StutCount := 50;
  SetLength(ScoreList, StutCount);
  // set the score list
  for I := 0 to StutCount - 1 do
  begin
    ScoreList[I] := Random(100);
  end;
  // print the score list
  MyScoreList := ScoreList;
  for I := 0 to StutCount - 1 do
  begin
    ShowMessage('Stut Index: ' + IntToStr(I + 1) +
      #13#10 + 'Socre Value: ' + IntToStr(ScoreList[I]) +
      #13#10 + 'My Socre Value: ' + IntToStr(MyScoreList[I])
      );
  end;
  // to finalize the score list
  SetLength(ScoreList, 0);
end;
正是因为动态数组变量只是一个用来保存内存地址的指针变量,因此上面以黑体显示的语句将使数组MyScoreList与ScoreList指向相同的内存地址,从而就变成实际意义上相同的数组,所以这段代码执行的效果将有力地说明动态数组变量就是指针这个事实。
  注意:但指针本身也是一个变量,它也必须存放在内存中,因此也有指向这个变量的内存的地址,而这个内存的地址是由程序语言自己维护的,不需要由程序员管理。实际上,前面已经说明,在程序运行时,所有变量都必须存放在内存中,都存在实际的地址,而这些地址并不需要程序员去管理的原因就是程序语言已经帮助程序员完成了管理变量地址的任务。

所有简单数据类型(整型、实型、布尔类型等)和大量复杂数据类型都存在相应的指针类型,如果程序需要使用这些变量的指针类型,则可以使用下面的示例代码:

var
  A: Integer;
  PA: PInteger;
begin
  A := 1;
  PA := @A;
  ShowMessage(IntToStr(PA^));
end;
只要将这段代码输入程序中,很容易就可以得到运行结果——即弹出对话框的内容是1。实际上,指针的用法还相当复杂,下面的代码也是正确的:
var
  A: Integer;
  PA: PInteger;
begin
  A := 1;
  PA := @A;
  PA^ := 2;
  ShowMessage(IntToStr(A));
end;
在程序中,根据实际需要,程序员还可以为自己定义的普通或复杂数据类型定义指针数据类型,下面就是定义指针数据类型的示例代码:
type
  PMyRec = ^TMyRec;
  TMyRec = record
    P1: Integer;
    P2: Integer;
    Name: String;
  end;
可以看出,这里定义了一个结构体类型,并定义它的指针类型PMyRec。在后续代码中,程序就可以使用这里定义的数据类型和指针数据类型,下面就是一段使用这种数据类型的示例代码:
var
  rec: TMyRec;
  mrec: PMyRec;
begin
  mrec := @rec;
  mrec^.P1 := 12;
  mrec^.P2 := 2029;
  mrec^.Name := 'mywork';
  ShowMessage(rec.Name + #13#10 + 'ID: ' +
IntToStr(rec.P1) + ', ' + IntToStr(rec.P2));
end;

  说明:这里使用了一个结构体数据类型,并已经给出使用结构体数据类型的方法

原创粉丝点击