Delphi数组

参考:http://www.cnblogs.com/huangjacky/archive/2009/12/21/1628833.html

  数组就是一堆相同特性数据的一个组合,也就是每个元素的类型必须是一样的,当然在其他一些弱语法的语言里面,数组的元素可以是千奇百怪,例子

var
    A : Array[0..2] of Integer;
begin
    A[0] := 1;
    a[1] := 1.0;    //这里是错的,因为每个元素都必须是Integer类型
end;

  

Delphi中数组的分类

1.定长和不定长

  定长数组

  定长数组也就是长度在声明的时候就确定的,后面是不能改变的,而在定长数组里,起始序号不必从0开始,可以自己定,例如

var
    A : Array[2..3] of Integer;
begin
    A[2] := 1;
    SetLength(A,3);    //这里会出错,因为定长数组不能再分配
end;

  从上面我们可以看到起始序号是2,但是步长是1,是不能改变的。为什么我们看到很多数组的起始序号是0呢?习惯而已。

  来看一个特殊用法

type
    THuangJacky = (hjA, hjB, hjC);
const
    //用法1
    B : Array[0..2] of string = (‘A‘, ‘B‘, ‘C‘);
    //用法2
    C : Array[THuangJacky] of string(‘A‘, ‘B‘, ‘C‘);
var
    H : THuangJacky;
    S :String;
begin
    S := B[Ord(H)]);
    S := C[H];
    //B[H]和C[1]都会出错
end;

  从上面的例子可以看出只要是有序数类型都可以当做数组的序号,但是我们用的时候序号就必须是声明的哪种序数类型,所以上面的代码注释中才会写出两种错误的情况

  不定长数组

  不定长数组:动态数组,也就是声明的时候没有说长度是多少,在使用之前必须声明,长度是可以再分配的,序号必须从0开始,例子

var
    A : Array of Integer;    //定长数组可能的定义是 A :Array[0..10] of Integer
begin
    SetLength(A, 3);    //数组一共有3个元素
    A[0] := 1;
    A[1] := 2;
    A[2] := 3;
    //A[3]没有,因为只有3个元素

    SetLength(A, 4);    //如果变长长度,直接增加后面的元素
    A[3] := 4;    //现在增加了第四个元素,而前三个元素还是那三个

    SetLength(A, 3);    //如果长度变短了,超出部分就会被去掉
    //现在A[3]没有了
end;

  有时候,大家这样要先设定长度,在赋值,很麻烦,现在介绍一个一气呵成的招数

type
    TA = Array of Integer;
var
    A : TA;
begin
    A := TA.Create(1, 2, 3);
    //此招请勿在Delphi 7上面使用

    //使用上面的方法之后,A[0] :=1, A[1] := 2, A[2]:=3
end;

  

2.一维和多维

  前面的所有例子,所讨论的都是一维数组,要想弄一个矩阵(多维数组)怎么办?

var
    A : Array[0..2, 0..2] of Integer;
    B : Array[0..2] of Array[0..2] of Integer;
begin
    A[0, 0] := 1;
    B[0, 0] := 1;
end;

  两种方法都是可以的,下面介绍二维数组中的不定长数组

var
    B : Array of Array of Integer
begin
    //设置一个3*3的矩阵
    SetLength(B, 3, 3);

    //如果需要实现齿状数组,必须像下面这么做
    SetLength(B, 3);
    SetLength(B[0], 1);
    SetLength(B[1], 2);
    SetLength(B[2], 3);
end;

接下来介绍几个关于数组的常用函数

  1.复制函数

var
    A, B : Array[0..1] of Integer;
begin
    A[0] := 1;
    A[1] := 2;
    B := A;
    B[0] :=2;
    ShowMessageFmt(‘A0:%D, B0:%D‘, [A[0], B[0]]);    //A0:1,B0:2
end;

  这个效果就是我们想要的,貌似没有什么好说的,但是如果是动态数组呢?

var
    A, B : Array of Integer;
begin
    SetLength(A, 2);
    SetLength(B, 2);
    A[0] := 1;
    A[1] := 2;
    B := A;
    B[0] := 2;
    ShowMessageFmt(‘A0:%D, B0:%D‘, [A[0], B[0]]);    //A0:2, B0:2
    //很显然改了B[0]的值之后,对A[0]的也造成了影响,所以B和A之间存在着某种联系
end;

  现在怎么办?A和B被关联到一个地址了,其实现在我们可以使用Copy函数,就可以解决这个问题了

var
    A, B : Array of Integer;
begin
    SetLength(A, 2);
    SetLength(B, 2);
    A[0] :=1;
    A[1] :=2;
    B := Copy(A);    //整个数组都赋值过去
    B := Copy(A, 0, 2);    //选择性复制
    B[0] := 2;
    ShowMessageFmt(‘A0:%D,B0:%D‘, [A[0], B[0]]); // A0:1,B0:2
end;

  

  2.序号相关

  函数Low()和High()值得信赖,不过我们需要注意的是,他们返回的类型是我们数组的序号的那个类型,并不都是Integer,如前面例子中的THuangJacky

var
    A : Array of array of string;
    I, J : Integer;
begin
    SetLength(A, 10);
    for I := Low(A) to High(A) do
    begin
        SetLength(A[I], I);
        for J := Low(A[I]) to High(A[I]) do
            A[I, J] := IntToStr(I) + ‘,‘ + IntToStr(J) + ‘ ‘;
        end
    end;
end.

  

  3.数组长度

  Length()函数返回的是Integer类型

var
    A : Array of Integer;
begin
    SetLength(A, 2);
    Length(A);
end.

  

从上面的那个复制的例子我们可以看出来:定长数组变量就是一个变量,所以可以直接用 := 来赋值,而动态数组变量就是一个指针,如果用了 :=来赋值,两个变量就关联在一起了

var
    A :Array[0..2] of Integer;
    B :Array of Integer;
begin
    ShowMessageFmt(‘A:%8x, A[0]:%8p‘, [Integer(@A), @A[0]]);    //一样,从地址来看这个数组控件在栈上面
    SetLength(B, 3);
    ShowMessageFmt(‘B:%8p, B[0]:%8p‘, [B, @B[0]]);    //一样,这个数据空间在堆上面
end

  我们看到A要取地址才和A[0]取地址一样,那么也就是说A就是A[0];

  而B直接就和B[0]取地址一样了,也就是说B就是B[0]的地址

  数组在内存中的分布:连续分布的,间隔就是每个元素的大小

var
    A: Array[0..2] of Integer;
    B: Array of Integer;
begin
    A[1] := 123;
    //从A也就是A[0]的地址上面往下走4个直接就是A[1]
    ShowMessageFmt(‘A[1]:%D,直接取值:%D‘,[A[1], PInteger(Integer(@A)+4)^]);
    //一样,都是123
    SetLength(B, 3);
    B[2] := 88;
    //从B往下走8个字节就是B[2]
    ShowMessageFmt(‘B[2]:%D,直接取值:%D‘,[B[2],PInteger(Integer(B)+8)^]);
end;

  但是动态数组的结构和字符的结构就很像了

偏移 -8 -4 0~Length*元素
内容 32位引用次数 元素个数 实际内容
时间: 2024-10-13 22:43:45

Delphi数组的相关文章

关于DELPHI数组,指针,字符串转换的例子!(转)

var   aa:   array [0..5] of Char;   bb:Pointer;   cc:string;   dd:PChar; procedure TForm1.Button1Click(Sender: TObject);begin dd:='abcdef'; //以下是pchar内容转数组FillChar(aa,length(dd),#0);Move(dd^,aa,SizeOf(aa)); //以下是数组传递到指针bb:=GetMemory(SizeOf(aa));Move(

delphi 数组类型

数组类型 数组类型定义了一组指定类型的元素序列,在方括号中填入下标值就可访问数组中的元素.定义数组时,方括号也用来指定可能的下标值.例如,下面的代码中定义了一个有 24 个整数的数组: type    DayTemperatures = array [1..24] of Integer; 在数组定义时,你需要在方括号中填入一个子界类型的值,或者用两个有序类型的常量定义一个新的子界类型,子界类型指定了数组的有效索引.由于子界类型指定了数组下标值的上界和下界,那么下标就不必象 C.C++.JAVA

delphi数组如何初始化

https://wenda.so.com/q/1535561587217078delphi数组如何初始化rosegirl09112级分类:其他被浏览44次2018.07.01检举满意答案 csx3308362采纳率:42%9级 2018.07.02vari : integer;arr1 : array[0..9] of integer;arr2 : array[0..9] of char;begin//如果是初始化是给每个元素相同的初值,可以用Fillchar这个函数来fillchar(arr1

delphi 数组作为参数传递

在函数中如果数组的个数不定,可以使用开放数组参数 实参可以接受静态数组和动态数组 procedure p1(a:array of Byte); begin ShowMessage( IntToHex( Integer(@a),2)); ShowMessage(IntToStr(a[0])); end; procedure TForm1.btn1Click(Sender: TObject); var a:array[0..5] of Byte; begin ShowMessage(IntToHex

Delphi - 数组和结构体

技术交流,DH讲解. 记得很早之前我就说过,数组和结构体在内存中其实一样的,他们都是连续分布的.例如: ? 1 2 3 4 TMyStruct = record   A,B,C:Integer; end; T3IntArray = array[0..2]of Integer; 这两个都占12字节,而且TMyStruct.A就是T3IntArray[0].而我们知道在访问数组中某个元素的时候,只是在第一个元素的地址 + 序号 * 元素大小.那么访问结构体应该也是这样的,只是结构体中每个元素的大小不

DELPHI数组,指针,字符串转换的例子

关于数组,指针,字符串转换的例子 var   aa:   array [0..5] of Char;   bb:Pointer;   cc:string;   dd:PChar; procedure TForm1.Button1Click(Sender: TObject);begindd:='abcdef'; //以下是pchar内容转数组FillChar(aa,length(dd),#0);Move(dd^,aa,SizeOf(aa)); //以下是数组传递到指针bb:=GetMemory(S

delphi 数组复制利用CopyMemory 最为完美

在各网站的文章里面,见复制数据的方法中,有move的,有system.copy的,而要实际应用中,这两种方法,并不是很完美,会遇到一些问题,比如copy在记录里面的复制时,编译都过不去,而CopyMemory的功能,就相当强大. 要注意如果不是byte时,长度可能需要使用sizeof来参与计算 Buff,BuffCmdCrc16:array of Byte SetLength(BuffCmdCrc16, 10); 一.复制10个byte CopyMemory(@BuffCmdCrc16[0],@

[转]Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换、变体类型常用的函数)

Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换.变体类型常用的函数) 一.变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型: 也可以告诉目前存储的数据是什么类型(通过使用VarType函数): 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法: variant数组只不过是variant型的数组,不必包含同类型的数据: 1.  VarArrayOf函数:更快捷的创建一维变体数组,可以创建全异的数值数组: funct

Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换、变体类型常用的函数)

来源:http://blog.csdn.net/xiongmao000738/article/details/6863988 一.变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型: 也可以告诉目前存储的数据是什么类型(通过使用VarType函数): 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法: variant数组只不过是variant型的数组,不必包含同类型的数据: 1.  VarArrayOf函数:更快捷的创建一维变体数组,可以