zoukankan      html  css  js  c++  java
  • delphi数组之菜鸟篇

    数组是可以通过索引来引用的同类型数据的列表。按照存储空间的获取方式,Delphi支持的数组类型有两种,即静态数组和动态数组。所谓静态数组就是在声明时就已经确定大小的数组类型,而动态数组是指其大小在声明时不能确定的数组,动态数组的大小在使用时确定。

    声明静态数组的方式非常简单,只要指明数组长度和数据类型即可,下面就是声明了一个用来存放字符的数组:

    var Hello: array[0..5] of char;

    容易看出,数组的声明明显包含3个部分,关键词array表明这是一个数组变量,而[x..y]表明数组的索引是从x到y,而of char表明数组的成员是字符类型。按照类似的方法还可以声明其他类型的数组,下面就是这样的示例代码:

    var ScoreList: array[1..25] of Integer;

    var NameList: array[1..35] of String;

    声明了数组后,可以通过索引引用数组的元素(成员)。而使用数组成员的方法与使用这种类型的普通变量类似,下面就是一段使用字符数组的示例代码:

    var Hello: array[0..5] of char;

    begin
     Hello[0] := ‘H’;
     Hello[1] := ‘e’;
     Hello[2] := ‘l’;
     Hello[3] := ‘l’;
     Hello[4] := ‘o’;
     Hello[5] := Chr(0);
     ShowMessage(Hello);
    end;
    这里声明了几个数组,它们都是只包含一个索引参数的数组,即一维数组。Delphi支持具有更多索引参数的数组,即多维数组。下面给出一段声明二维数组的示例代码:
    var Hello: array[0..5][1..10] of char;
    访问二维数组成员的方式与访问一维数组的方式相似,只要按照类似的方式指定两个索引就可以访问二维数组的成员,下面就是使用二维数组的示例代码:
    var Hello: array[0..5] of array[0..10] of char;
    begin
     Hello[0][0] := ‘H’;
     Hello[0][1] := ‘e’;
     Hello[0][2] := ‘l’;
     Hello[0][3] := ‘l’;
     Hello[0][4] := ‘o’;
     Hello[0][5] := Chr(0);
     ShowMessage(Hello[0]);
    end;
    按照类似的方法还可以声明具有更高维数的数组,这里不再给出实例。另外,Delphi还支持访问二维数组成员的另外一种方法,下面就是示例代码:
    var Hello: array[0..5] of array[0..10] of char;
    begin
     Hello[0,0] := ‘H’;
     Hello[0,1] := ‘e’;
     Hello[0,2] := ‘l’;
     Hello[0,3] := ‘l’;
     Hello[0,4] := ‘o’;
     Hello[0,5] := Chr(0);
     ShowMessage(Hello[0]);
    end;
    前面只是用了静态数组,Delphi还支持动态数组,动态数组在声明时不需指定数组的大小,而在使用时直接指定,下面就是定义动态数组的方法:
    var ScoreList: array of Integer;
    由于在声明时没有指定动态数组的大小,因此在使用前必须指定动态指定数组的大小,这是通过调用过程SetLength来实现的,下面就是指定动态数组大小的示例:
    var
      I: Integer;
      StutCount: Integer;
      ScoreList: 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
      for I := 0 to StutCount - 1 do
      begin
        ShowMessage('Stut Index: ' + IntToStr(I + 1) +
          #13#10 + 'Socre Value: ' + IntToStr(ScoreList[I]));
      end;
      // to finalize the score list
      SetLength(ScoreList, 0);
    end;
    这段代码首先使用StutCount变量来初始化数组的大小,然后为所有数组成员随机分配一个在0到100之间的整数,再利用对话框输出这些整数,最后再次使用SetLength将数组的长度设置为0,从而释放数组所占用的空间。另外,后面章节将说明,动态数组实际上就是一个指针。
    4. 地址和指针
    在学习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;

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

    原文:http://www.delphitop.com/html/jichu/1895.html

  • 相关阅读:
    【tyvj1864】[Poetize I]守卫者的挑战
    【tyvj1863】 [Poetize I]黑魔法师之门
    codevs2800送外卖(状压dp)
    noip2013day1t3货车运输(瓶颈路,树上倍增)
    noip2015day2t3运输计划(二分+树上前缀和)
    nginx.spec
    salt-syndic使用
    salt-call报错OSError: [Errno 13] Permission denied: '/root/.gvfs'
    SOCKET客户端编程
    nginx配置salt-api转发,iptables限制ip连接salt-api
  • 原文地址:https://www.cnblogs.com/semth/p/9036485.html
Copyright © 2011-2022 走看看