数组可以使Object Pascal所拥有的任何数据类型,数组是一些数值的简单集合。
var
MyArray: array[0..4] of Integer; { 声明一个数组包括5个整数数值}
begin
MyArray[0] := -200; { 通过操作符[]就可以访问每个数组元素}
MyArray[1] := -100;
MyArray[2] := 0;
MyArray[3] := 100;
MyArray[4] := 200;
MyArray[0] := MyArray[1] + MyArray[4]; { MyArray[0]为-100}
end;
其MyArray在内存空间的分布,每个整数需要4个字节,因此整个数组将占20个字节的内存,如下:
1、多维数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const
CArray:
array
[
0..4
]
of
Integer
= (-
20
, -
100
,
0
,
100
,
200
);
{ 数组常量的在声明的同时也要进行赋初值}
var
MyArray:
array
[
0..2
,
0..4
]
of
Integer
;
{ 两维数组的声明}
UArray:
array
[
10..20
]
of
Integer
;
{ 声明了一个下界10到上界20的11个元素的数组}
X:
Integer
;
begin
{ 两种方法可以访问两维数组}
X := MyArray[
1
][
1
] + MyArray[
2
][
1
];
{ 1、[X][Y]访问}
X := MyArray[
1
,
1
] + MyArray[
2
,
1
];
{ 2、[X, Y]访问}
{ 下面的访问超出了数组范围,
将会提示“Constant expression violates subrange bounds”错误}
X := MyArray[
3
,
1
] + MyArray[
0
,
5
];
{注意这两个元素超出数组声明的范围}
end
;
|
其中MyArray被声明为一个二维数组,其在内存中的分布如下:
2、上界与下界
处理数组会经常用到上界(Low)和下界(High)函数。如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
X, I, Lower, Upper:
Integer
;
MyArray:
array
[
10..20
]
of
Integer
;
begin
{ 这里假使已经将MyArray数组进行了赋初值}
Lower := Low(MyArray);
{ Lower的值为 10}
Upper := High(MyArray);
{ Upper的值为 20}
X :=
0
;
for
I := Lower
to
Upper
do
begin
X := X + MyArray[I];
{ X将累加数组元素值的和}
end
;
end
;
|
使用上下界函数可以保证存取数组时不越界。
对了,如果换成二维数组,上下界函数如何用呢???
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var
Lower1, Upper1:
Integer
;
{ 用来存储一维的上下界}
Lower2, Upper2:
Integer
;
{ 用来存储二维的上下界}
MyArray:
array
[
10..20
,
1..2
]
of
Integer
;
begin
{ 这里假使已经将MyArray数组进行了赋初值}
Lower1 := Low(MyArray);
{ Lower的值为 10}
Upper1 := High(MyArray);
{ Upper的值为 20}
ShowMessage(
'第一维的下界为 '
+ IntToStr(Lower1) +
',上界为 '
+ IntToStr(Upper1));
Lower2 := Low(MyArray[Lower1]);
{获取MyArray[10]下界}
Upper2 := High(MyArray[Lower1]);
{获取MyArray[10]上界}
ShowMessage(
'第二维的下界为 '
+ IntToStr(Lower2) +
',上界为 '
+ IntToStr(Upper2));
end
;
|
两次消息框显示界面如下:
3、动态数组(dynamic array)
动态数组是一种在运行时分配内存的数组,一个动态数组可以变大,也可以变小。
声明一个动态数组,只要在声明时不要制定维数,就像这样:
1
2
3
4
5
6
7
8
9
10
|
var
SA:
array
of
string
;
{ 一维动态数组}
begin
{ 使用SetLength进行动态数组的空间分配,已有元素可以得到保留}
SetLength(SA,
3
);
SA[
0
] :=
'Hello World'
;
{ 重新分配了动态数组大小为2个元素}
SetLength(SA,
2
);
ShowMessage(SA[
0
]);
{显示为'Hello World',说明已有元素得到保留}
end
;
|
用同样的方法也可以建立二维动态数组,如下:
1
2
3
4
5
6
7
8
9
10
|
var
SA:
array
of
array
of
string
;
{ 二维动态数组}
begin
{ 使用SetLength进行动态数组的空间分配,已有元素可以得到保留}
SetLength(SA,
20
,
20
);
SA[
0
][
0
] :=
'Hello World'
;
{ 重新分配了动态数组大小为2个元素}
SetLength(SA,
10
,
10
);
ShowMessage(SA[
0
][
0
]);
{显示为'Hello World',说明已有元素得到保留}
end
;
|
动态数组建立后就可以像普通数组一样使用。
动态数组通常都是以0为基准的。
动态数组是生存期自管理的,使用完它们后没有必要释放,离开作用域后它们会被自动释放。当然,如果你想在离开作用域前就删除动态数组(比如它占用太多的内存了,需要释放掉),那就用下面的语句就可以了。
1
2
3
4
5
6
7
|
var
SA:
array
of
string
;
begin
SetLength(SA,
20
);
SA[
0
] :=
'Hello World'
;
SA :=
nil
;
{ 直接把nil赋值给SA就可以了}
end
;
|
动态数组的复制问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var
A1, A2:
array
of
Integer
;
begin
SetLength(A1,
4
);
A2 := A1;
A1[
0
] :=
1
;
A2[
0
] :=
26
;
ShowMessage(IntToStr(A1[
0
]));
{ 显示结果为 26}
{
为什么显示26呢?因为A2 := A1这条赋值语句,并没有创建新的数组,仅仅只是将
A1数组的引用赋值给了A2,也就是说A2只是A1的一个别名而已,指向的都是相同东西,
因此对A2所做的任何操作都会影响到A1,如果想要完全复制创建一个新的A2数组需要
用到Copy函数,如下:
}
A2 := Copy(A1);
{ A1, A2现在为两个独立的数组}
A2[
0
] :=
10
;
A1[
0
] :=
26
;
ShowMessage(IntToStr(A2[
0
]));
{ 现在A2的值为10,说明完全的独立了}
A2 :=
nil
;
{释放掉A2}
A2 := Copy(A1,
1
,
2
);
{ 从元素1开始,复制2个元素到A2}
end
;
|