• Delphi数组详解(整理)


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

    数组的下标一般下界值都为0,不建议使用非0下标。

    静态数组:

     1 标准方法: 
       var MyArr: array[0..10] of Integer; //定义静态数组
     2 可以使用非0下标: 
       var MyArr: array[9..10] of Integer; //不能提倡,这样不容易与系统函数沟通
     3 根据预定义类型来声明数组: 
       type TMyArr = array[0..10] of Integer; //先定义一个数组类型 var MyArr: TMyArr; //再定义静态数组
     4 在非过程区可以直接赋值: 
       var MyArr: array[0..2] of Integer = (11,22,33);//过程中无法直接赋值操作
     6 多维数组: 
       var MyArr: array[0..2, 0..2] of Integer; begin //使用 MyArr[1,2] := 100; end;
     7 根据子界定义数组: 
       type TRange = 0..10; var MyArr: array[TRange] of Integer;
     8 根据枚举定义数组: 
       type TEnums = (Enum1,Enum2,Enum3); 
      var MyArr: array[TEnums] of string;
      begin MyArr[Enum1] := '万一';//Enum1,Enum2,Enum3就相当于普通数组的下标
      ShowMessage(MyArr[Enum1]); //万一 end;
    9 根据其他类型定义数组: 
      var MyArr: array[Byte] of Char; begin MyArr[255] := #65; ShowMessage(MyArr[255]); //A end;
    应尽量不使用内建类型,可以新建类型: type TNewByte = Byte; var MyArr: array[TNewByte] of Char; begin MyArr[255] := #65; ShowMessage(MyArr[255]); //A end;

    也可以使用类型别名: type TChar = type Char; var MyArr: array[TChar] of Byte; begin MyArr['C'] := 255; ShowMessage(IntToStr(MyArr['C'])); //255 end;

    同时定义类型: type MyRec = record s: string; r: Real; b: Byte; end; var Arr1: array[0..100] of MyRec; Arr2: array[0..100] of record s: string; r: Real; b: Byte; end; 可以直接这样定义: Arr3: packed array[0..100] of MyRec; //压缩数组定义, 好像没有区别?
     

    动态数组:

    动态数组是指其大小在声明时不能确定的数组,动态数组的大小在使用时确定。分配空间后可以使用 nil 进行释放空间。一般离开数组作用域系统会自动释放。

    由于动态数组不用提前声明数组长度,所以一般动态数组下标由 0 开始。

    1 常规定义: 
    var StrArr: array of String; //动态数组定义时不与维数 begin SetLength(StrArr,6); //分配6个元素位置: 0-5 StrArr[0] := '万一';
    2 指针复制操作与Copy函数:
     var
       Arr1,Arr2: array of Integer;
     begin
       SetLength(Arr1,6);
       Arr1[5] := 100;
       Arr2 := Arr1;//指针赋值操作
       ShowMessage(IntToStr(Length(arr2)));//arr2引用了arr1,所以arr2长度也为6.
       ShowMessage(IntToStr(arr2[5]));//arr2引用了arr1,结果100
         Arr2[5]:= 99;                  //动态数组也是一个指针,改变其中一个数组元素值,另外一个也会改变
         ShowMessage(IntToStr(arr1[5]));//结果99
         arr2 := nil;
         ShowMessage(IntToStr(arr1[5]));//释放其中一个数组,另外一个没有影响
         Arr2  := Copy(arr1);//Copy函数是将两个相同类型的数组进行赋值,此时复制的是所有数组元素
         ShowMessage(IntToStr(arr2[5]));//结果99,这种操作与指针不同,两个数组之间没有联系。
    3 动态多维数组:
      var Arr: array of array of Integer; begin SetLength(Arr,5,5); //分配空间 Arr[0,3] := 100; //赋值 ShowMessage(IntToStr(Arr[0,3])); //取值
    4 变体数组:
     var
        Arr: array[0..3] of Variant;// Variant为变体类型关键字
      begin
        Arr[0] := 123;
        Arr[1] := 'wy';
        Arr[2] := True;
        Arr[3] := VarArrayOf([1,'wanyi',1.5]); //变体数组的元素也可以是变体数组
        ShowMessage(Arr[0]); //123,不需要转换
        ShowMessage(Arr[1]); //wy
        ShowMessage(Arr[2]); //True
        ShowMessage(Arr[3][1]); //wanyi
      end;
     
     5 枚举数组:
       procedure TForm1.Button1Click(Sender: TObject);
       type
         TMyEnum = (Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday); //定义枚举}
       var
         weekArr: array[TMyEnum] of string; //定义数组 数组元素是String类型
         myEnum: TMyEnum; //定义枚举变量}
       begin //数组赋值}
         weekArr[Monday] := '星期一';
         weekArr[Tuesday] := '星期二';
         weekArr[Wednesday] := '星期三';
         weekArr[Thursday] := '星期四';
         weekArr[Friday] := '星期五';
         weekArr[Saturday] := '星期六';
         weekArr[Sunday] := '星期天'; 
         ShowMessage(weekArr[Sunday]); //星期天}
         //遍历数组 必须定义myEnum: TMyEnum枚举变量,因为TmyEnum是数组维数,也就是下标 
         for myEnum := Low(weekArr) to High(weekArr) do
         begin
           ShowMessage(weekArr[myEnum]); //将分别显示: 星期一 ... 星期天}
         end;
       end;

    数组定义时,如果唯数是以枚举开始的话,编译指令是从Low()..High() 
    所以带有负数值的枚举用来定义数组常量会出错. 
    Type 
    TErrorCode = (ecNOERROR = 0, 
    ecDisConnect = -1, 
    ecOtherError = -2); 
    Const 
    ErrorLabels : array [TErrorCode] of String =( 
    '无错误' , '断开连接' , '其他错误'); 
    procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    Caption := ErrorLabels[ecOtherError]; 
    end; 
    Caption得到的是:无错误,那是因为Low(TErrorCode)=ecOtherError 
    High(TErrorCode)就是ecNOERROR 

     6 子界数组: 

    procedure TForm1.Button1Click(Sender: TObject); type TABC = 'A'..'G'; //定义子界} var abcArr: array[TABC] of Integer; //定义数组 数组元素是 Integer类型 abc: TABC; //定义子界变量} begin //数组赋值} abcArr['A'] := 11; abcArr['B'] := 22; abcArr['C'] := 33; abcArr['D'] := 44; abcArr['E'] := 55; abcArr['F'] := 66; abcArr['G'] := 77; ShowMessage(IntToStr(abcArr['G'])); //77 //遍历数组 必须定义子界变量abc: TABC 因为 TABC 是数组维数,也就是下标 for abc := Low(abcArr) to High(abcArr) do begin ShowMessage(IntToStr(abcArr[abc])); //11 22 33 44 55 66 77 end; end; end.
    常规:
    procedure TForm1.Button1Click(Sender: TObject);
    const
      //因为过程中var无法直接赋值,所以需要const
      arr: array[0..1] of Char = ('A','B');
    begin
      ShowMessage(arr); //AB
      ShowMessage(IntToStr(Length(arr))); //2
    end;
    数组的其他定义方式: procedure TForm1.Button1Click(Sender: TObject);
    const arr: array[Boolean] of Char = ('A','B'); begin ShowMessage(arr); //AB ShowMessage(IntToStr(Length(arr))); //2 //访问元素 ShowMessage(arr[False]); //A ShowMessage(arr[True]); //B //也可以这样访问 ShowMessage(arr[Low(arr)]); {A} ShowMessage(arr[High(arr)]); {B} //但不能这样访问} // ShowMessage(arr[0]); // ShowMessage(arr[1]); //但可以变通一下} ShowMessage(arr[Boolean(0)]); //A ShowMessage(arr[Boolean(1)]); //B end; procedure TForm1.Button1Click(Sender: TObject); const arr: array[Byte] of Integer = ( 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72, 73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138, 139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158, 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178, 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198, 199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218, 219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, 239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256); begin ShowMessage(IntToStr(arr[Low(arr)])); //1 ShowMessage(IntToStr(arr[High(arr)])); //256 ShowMessage(IntToStr(Length(arr))); //256 end; end. procedure TForm1.Button1Click(Sender: TObject); const BoolStr: array[Boolean] of string = ('False', 'True');//过程区直接赋值,所以需要Const 关键字 var b: Boolean; begin b := True; ShowMessage(BoolStr[b]); {True} b := not b; ShowMessage(BoolStr[b]); {False} end; end.
     动态数组一般是不需要手动释放的, 如果需要.:
      var arr: array of Integer; begin {设置动态数组维数}     
      SetLength(arr,10); 
      arr := nil;//释放方法一 
      SetLength(arr, 0);//释放方法二
      Finalize(arr); //释放方法三 
      end;

    注:整理于https://www.cnblogs.com/ahroot/archive/2011/10/28/2227585.html

    也可学习https://www.cnblogs.com/huangjacky/archive/2009/12/21/1628833.html

  • 相关阅读:
    C语言memmove()函数:复制内存内容(可以处理重叠的内存块)
    boot简介
    MT6753/MT6755 呼吸灯功能添加
    MT6753 使用nt35596s 由于液晶极化出现的闪屏问题解决思路
    MTK平台释疑android M 配置中断相关问题
    MT6755 平台手机皮套驱动实现
    MTK平台 GPU 相关知识
    MTK平台如何定位显示花屏和界面错乱等绘制异常的问题?
    【Python】注释
    【Linux】.gz文件 压缩与解压缩命令
  • 原文地址:https://www.cnblogs.com/fansizhe/p/12639586.html
Copyright © 2020-2023  润新知