3-2.结构类型之数组类型
3-2.数组类型(array)
转自delphii2010语法基础
数组是一种数据类型数据的有序集合,是代表一定数量具有相同类型变量的一种数据类型。Object Pascal数组可与任何简单数据类型或字符串类型等一起使用。数组可用于声明一个简单变量或作为一个记录类型定义的组成部分。
(1)数组的定义
声明一个数组变量,要求你提供一个标识符,使用array[əˈreɪ]保留词,在方括号中指定数组的界限,并指定编译器数组将用于存储什么类型,例如:
Var Check:array[1..100] of Integer;
范围标点‘..’用于表示Check是一个有100个整数的数组,这些整数从1到100编号。范围编号是一个子界类型,可以是0,也可以是正数或负数,或者字符,或其它有序类型。
下面是声明数组类型及数组类型变量的举例:
Type
TCheck = array [1..100] of Integer;
Var
CheckingAccount:TCheck;
上面是先定义数组类型,然后定义数组变量。其实上,也可以同时定义类型、变量,例如:
var
Kelvin:array[0..1000] of Temperatures;
TwentiethCentury: array[1901..2000] of Events;
LessThanzeroo: array[-999..-400] of Shortint;
DigiTValues:array ['0'..'9'] of Byte;
SecretCode:array['A'..'Z'] of char;
访问数组中的元素很简单,只要在标识符后面的方括号中给出指定的元素的索引号即可。例如:
Check[5]:=12; J:=9; Check[J]:=24;
要访问数组中的所有元素,可以使用循环语句。例如 :
For J:=1 to 10 do
Check[J]:=0;
(2)多维数组
上面介绍的是一维数组。实际上,数组可以是多维的。例如,如果你想编写一个数组来容纳一张电子表格中的值,那么就可以使用2维数组。下面的例子说明如何使用2维数组定义一个有20行和20列的表格:
Type Ttable = array[1..20,1..20] of Double; Var BigTable:Ttable;
要将2维数组中的所有数据初始化,可以使用如下语句:
var Col,Row:Intger; for Col:=1 to 20 do for Row:=1 to 20 do BigTable[Col,Row]:=0.0;
使用多维数组时,要记住的一件事是数组为每维所占据的RAM数都呈幂级数增加。例如:
Aline:Array[1..10] of byte;占用10个字节 AnArea:Array[1..10,1..10] of byte;占用10*10=100个字节 Avloume:Array[1..10,1..10,1..10] of byte;占用10*10*10=1000个字节
(3)字符数组
前面介绍的字符串,实际上就是一个1维字符数组,只不过Pascal对字符串类型作了特殊的准许,你可以把它看作一个整体。字符串类型本质上等同于下列类型:
type StringType:array[0..255] of char;
虽然你可以当一个字符串看待,但它仍然保持其数组的特性。例如在定义一个字符串类型变量时,你可以说明字符串的大小,就像你定义字符数组的大小一样。下面是几个字符串类型定义:
type MyString:string[15]; BigString:string; LittleString:string[1];
上面语句定义MyString类型包含15个字符,LittleString包含1个字符,BigString没有说明大小,就取字符串包含字符的最大个数255。然后你可以定义这些类型的变量,就像使用其它类型一样:
Var MyName:MyString; Letter,Digit:LittleString;
你可以对字符串变量进行赋值:
MyName:='Frank P.BorLand';
因为MyName长度为15,因此只能容纳15个字符。如果执行下面语句:
MyName:='Frank P.Borland and ...';
则MyName变量中只存有FranK.P.Borlan其余部分被舍弃。
为了取得字符串中的一个字符,可以按如下方法进行:
AChar:=MyName[2];
但是,如果索引大于字符串变量的长度,则结果不可知。例如:
AChar:=MyName[16];
则AChar将被设置为某个不确定的字符,换句话说,就是废字符。
在字符串类型的数组中,字符串的第一个位置[0]包含有字符串的长度,因此数组的实际长度比该字符串长度大1个字节。你可以使用Length函数或下面的代码来得到一个字符串的长度:
L:=Ord(String[0]);
(4)数组类型常量
数组类型常量的每个字段都是类型常量,一个数组类型常量由括号括起来的类型常量组成,不同类型常量用逗号隔开。像简单类型常量一样,数组类型常量用来定义一个数组常量,下面是一个例子。
type TStatus = (Active, Passive, Waiting); TStatusMap = array[TStatus] of string; const StatStr: TStatusMap = ('Active', 'Passive', 'Waiting');
上面的例子首先定义一个数组TStatusMAp,然后定义一个数组常量StatStr。该数组常量的目的是把TStatus类型的值转化为对应的字符串。下面是数组常量StatStr元素的值:
StatStr[Active] = 'Active' StatStr[Passive] = 'Passive' StatStr[Waiting] = 'Waiting'
数组常量的元素类型可以是除文件类型以外的任何类型。字符数组类型常量既可以是字符也可以是字符串,例如:
const Digits: array[0..9] of Char = ('0', '1', '2', '3', '4', '5','6', '7', '8', '9');
该数组常量也可以表示为:
const Digits: array[0..9] of Char = '0123456789';
初始化字符数组类型常量的字符串长度可以小于数组类型的定义长度,例如:
var FileName: array[0..79] of Char = 'TEST.PAS';
这时数组余下的字符空间自定置NULL(#0),因此数组也变成了一个以NULL结尾的字符串。
多维数组类型常量的定义采用括号的形式,每一维用括号括起,不同维及不同元素常量之间用逗号隔开。最里面的常量对应最右面的维数。例如:
type TCube = array[0..1, 0..1, 0..1] of Integer; const Maze: TCube = (((0, 1), (2, 3)), ((4, 5), (6, 7)));
Maze常量数组各元素的值为:
1
2
3
4
5
6
7
8
|
Maze[ 0 , 0 , 0 ] = 0 Maze[ 0 , 0 , 1 ] = 1 Maze[ 0 , 1 , 0 ] = 2 Maze[ 0 , 1 , 1 ] = 3 Maze[ 1 , 0 , 0 ] = 4 Maze[ 1 , 0 , 1 ] = 5 Maze[ 1 , 1 , 0 ] = 6 Maze[ 1 , 1 , 1 ] = 7 |
(5)开放式数组
所谓开放式数组,是指数组作为形参传递给过程或函数时其长度是可变的,这样在调用过程或函数时,可以传递不同长度的数组作为实际参数。开放式数组在过程或函数中作为形参可以定义为:
array of T
这里T是数组的元素类型标识符,实际参数必须是T类型的变量或元素类型为T的数组变量。在过程或函数内形参的作用可看作为下面的数组:
array[0..N - 1] of T
这里N是实参中元素的个数。实际上实参的上下界被映射到0到 N-1。如果实参是类型T的简单变量,则它被看成为只有类型T元素的数组。
开放数组只能以开放数组参数或一个未定义变量参数的形式传递到过程或函数。开放数组可以作为数值参数、常数参数或变量参数,并与这些参数具有同样的语法规则。作为形式参数的开放数组不允许整体赋值,只能访问它的元素。并且对元素的赋值不影响实参。当开放式数组作为数值参数时,编译器将在内存中开辟一块区域存放实参的拷贝,等过程或函数退出后再释放这块区域,这样当实参是个很大的数组时,可能会发生栈溢出的问题。在使用开放数组参数时,可以使用Low函数获得当前最小下标(不过总是为0),使用High函数获得当前最大下标,使用SizeOF函数获得当前数组大小。下面是一个例子,演示了开放式数组的使用。
Var X1:array[1..10] of Double; X2:array[1..30] of Double; {Clear过程对一个Double数组的各元素清0,SUM过程计算一个Double数组的各元素之和。两个过程的参数都是开放式数组。} procedure Clear(var A: array of Double); var I: Integer; begin for I := 0 to High(A) do A[I] := 0; end; function Sum(const A: array of Double): Double; var
I: Integer;
S: Double; begin S := 0; for I := 0 to High(A) do
S := S + A[I]; Sum := S; end; begin Clear(X1); Clear(X2); Sum(X1); Sum(X2); end.
当开放式数组的元素类型为Char时,实参可以是一个字符串常数。例如:
procedure PrintStr(const S: array of Char); var I: Integer; begin for I := 0 to High(S) do if S[I] <> #0 then
Write(S[I]) else
Break; end.
下面是合法的过程调用语句:
PrintStr('Hello world'); PrintStr('A');
(6)动态数组
在Delphi中,除了定义静态数组外,还可以定义动态数组。动态数组只需说明数组的类型信息(包括数组的维数和数组元数的类型),但不需要定义元素的个数。例如:
A: array[1..100] of string;//静态数组 B: array of integer//动态数组 C: array of array of string;//动态数组
这里A是静态数组,B是一维的整数动态数组,C是二维的字符串动态数组。动态数组没有固定的长度。相反,当为动态数组赋值或使用SetLength过程时,动态数组的内存空间将重新分配。动态数组的定义形式是:
array of baseType
例如:
var MyFlexibleArray: array of Real;
定义了一个类型为实数型的一维动态数组。注意,声明语句并没有为MyFlexibleArray分配内存。要为动态数组分配内存,需要调用SetLength过程。例如:
SetLength(MyFlexibleArray, 20);
上面语句分配20个实数,标号从0到19。
动态数组的标号是整数类型,标号总是从0开始。使用Length,High和Low函数可以取得有关动态数组的特性。Length函数返回数组中元素的个数。High函数返回数组的最大标号,Low返回0。