当前位置: 首页 > 工具软件 > FreePascal > 使用案例 >

FreePascal 学习笔记 第六章 数组 (数组的下标很有意思,仔细看)

贾烨
2023-12-01

 

、静态数组 Static Arrays

数组的范围包含在数组定义中时,它称为静态数组。

尝试访问索引超出声明范围的元素将生成运行时错误(如果启用了范围检查)。

函数High和Low返回数组最左边的索引类型的上限和下限

示例:

Type 

 	RealArray = Array [1..100] of Real; //有效索引1到100

  	TA = Array[0..9,0..9] of Integer;  //有效索引0到9 
以下两种声明等同
Type  

   APoints = array[1..100] of Array[1..3] of Real;
Type 

 APoints = array[1..100,1..3] of Real;

当静态数组类型变量彼此分配时,将复制整个数组的内容。对于多维数组也是如此。
program testarray1;
type
  TA = array[0..9, 0..9] of integer;
var
  A, B: TA;
  I, J: integer;
begin
  for I := 0 to 9 do
    for J := 0 to 9 do
      A[I, J] := I * J;
  writeln('Array of A') ;
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(A[I, J]: 2,' ');
    Writeln;
  end;

  B := A;

  Writeln('Array of A');
  for I := 0 to 9 do
    for J := 0 to 9 do
      A[9 - I, 9 - J] := I * J;
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(A[I, J]: 2,' ');
    Writeln;
  end;

  writeln('Array of B');
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(B[I, J]:3);
    Writeln;
  end;
  readln;
end.                   有效索引1到100

  	TA = Array[0..9,0..9] of Integer;  //有效索引0到9 
以下两种声明等同
Type  

   APoints = array[1..100] of Array[1..3] of Real;
Type 

 APoints = array[1..100,1..3] of Real;

当静态数组类型变量彼此分配时,将复制整个数组的内容。对于多维数组也是如此。
program testarray1;
type
  TA = array[0..9, 0..9] of integer;
var
  A, B: TA;
  I, J: integer;
begin
  for I := 0 to 9 do
    for J := 0 to 9 do
      A[I, J] := I * J;
  writeln('Array of A') ;
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(A[I, J]: 2,' ');
    Writeln;
  end;

  B := A;

  Writeln('Array of A');
  for I := 0 to 9 do
    for J := 0 to 9 do
      A[9 - I, 9 - J] := I * J;
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(A[I, J]: 2,' ');
    Writeln;
  end;

  writeln('Array of B');
  for I := 0 to 9 do
  begin
    for J := 0 to 9 do
      Write(B[I, J]:3);
    Writeln;
  end;
  readln;
end.

、动态数组 Dynamic arrays

1.声明动态数组类型的变量时,数组的初始长度为零。

2.数组的实际长度使用标准SetLength函数设置 。

4.调用SetLength之后,有效的数组索引从0到开始。

program testDynamicArray;


 

type

TByteArray = array of byte;


 

Var

I,J: integer;

m,n: integer;

A : TByteArray;

B : Array of TByteArray;

C : Array of Array of TbyteArray;

begin

WriteLn('A-High=',High(A));//未设置时显示-1

SetLength(A,10); //设置一维数组

WriteLn('A-High=',High(A)); //设置r后显示W9

Writeln;


 

SetLength(B,100,10);//设置多维数组

WriteLn('B-High=',high(b));

WriteLn('B-High=',high(b[0]));

Writeln;


 

SetLength(C,7,8,9);

WriteLn('C-High=',High(c)); //=6

WriteLn('C-High=',High(C[0])); //=7

WriteLn('C-High=',High(C[0,0])); //=8

WriteLn('C-High=',High(C[0,0,0])); //=255 Why?

 

m := high(A);

n := high(b[99]);

writeln(n);


 

for i:=0 to 9 do

begin

A[i]:=i;

for j:=0 to 9 do

B[i,j] := i*j;

end;


 

writeln('Array of A');

for i :=0 to 9 do

write(A[i]:2,' ' );

writeln;


 

writeln('Array of B');

for I := 0 to 9 do

begin

for J := 0 to 9 do

Write(B[I, J]:3);

Writeln;

end;

readln;

end.

5.动态数组是按引用计数的:将一个动态数组类型的变量分配给另一个数组将使两个变量都指向同一数组。与ansistrings相反,对一个数组元素的赋值将反映在另一个数组中没有写时复制。

program TestReferenceCounted;    
type
  TByteArray = array of byte;
var
  A,B :TByteArray;
begin
  SetLength(A,10);
  A[0] := 33;
  WriteLn(A[0]);//33
  B := A;
  WriteLn(B[0]);/33
  A[0] := 31;
  WriteLn(A[0]);//31
  WriteLn(B[0]);//31

  //SetLength会使引用计数归一,使得2个数组的值不会同步更新
  SetLength(B,10);
  B[0] := 11;
  WriteLn(A[0]); //31
  WriteLn(B[0]); //11
  SetLength(A,20);
  A[0] := 22;
  WriteLn(A[0]); //22
  WriteLn(B[0]); //11     
	
  readln
end.
type
  TByteArray = array of byte;
var
  A,B :TByteArray;
begin
  SetLength(A,10);
  A[0] := 33;
  WriteLn(A[0]);//33
  B := A;
  WriteLn(B[0]);/33
  A[0] := 31;
  WriteLn(A[0]);//31
  WriteLn(B[0]);//31

  //SetLength会使引用计数归一,使得2个数组的值不会同步更新
  SetLength(B,10);
  B[0] := 11;
  WriteLn(A[0]); //31
  WriteLn(B[0]); //11
  SetLength(A,20);
  A[0] := 22;
  WriteLn(A[0]); //22
  WriteLn(B[0]); //11     
	
  readln
end.

6.用Copy从其它数组中复制数据

program TestArrayCopy;

Type

Ta = array of integer;

var

A,B : TA;

I : integer;


 

begin

SetLength(A,10);

for I:=0 to 9 do

a[i]:= i;

writeln('Value of A');

for I:= 0 to 9 do

write(A[i]:3);

writeln;


 

//Copy返回一个与原始数组类型相同的新动态数组,

//Index中的位置开始,

//从旧数组中复制Count个元素。

B:= Copy(A,3,6);

Writeln('Value of B');

for i:=0 to 5 do

write(B[i]:3);

writeln;


 

//省略Count,则复制到旧数组的末尾

B:= Copy(A,3);

Writeln('Value of B');

for i:=0 to 5 do

write(B[i]:3);

writeln;


 

//复制旧数组中的所有元素

B:= Copy(A);

Writeln('Value of B');

for i:=0 to 9 do

write(B[i]:3);

writeln;


 

readln;

end.

7.动态数组构造函数

program TestDynamicArrayConstructor;

Type
  TIntegerArray = array of integer;
  TIntegerArrayArray = array of TIntegerArray;
Var
  A : TintegerArray;
  B : TIntegerArrayArray;

  I : Integer;
begin
  A := TIntegerArray.Create(1,2,3);
  Writeln('Length of A = ',Length(A));  //3
  WriteLn('High of A = ' ,High(A));     //2

  B := TintegerArrayArray.create(TIntegerArray.Create(1,2,3),
                                 TIntegerArray.Create(4,5,6),
                                 TIntegerArray.Create(7,8,9));
  WriteLn('Length of B = ',length(b));
  For I:=0 to 2 do
  begin
    write(B[i,i]:2);
  end;


  readln;
end.

Type
  TIntegerArray = array of integer;
  TIntegerArrayArray = array of TIntegerArray;
Var
  A : TintegerArray;
  B : TIntegerArrayArray;

  I : Integer;
begin
  A := TIntegerArray.Create(1,2,3);
  Writeln('Length of A = ',Length(A));  //3
  WriteLn('High of A = ' ,High(A));     //2

  B := TintegerArrayArray.create(TIntegerArray.Create(1,2,3),
                                 TIntegerArray.Create(4,5,6),
                                 TIntegerArray.Create(7,8,9));
  WriteLn('Length of B = ',length(b));
  For I:=0 to 2 do
  begin
    write(B[i,i]:2);
  end;


  readln;
end.

8.数组压缩各解压(打包和拆包 Packing and unpacking an array)

打包:普通打包、位打包

8.1数组压缩

procedure Pack(

const A: UnpackedArrayType;

StartIndex: TindexType;

out Z: PackedArrayType

);

Pack会将未打包数组(A)的元素复制到打包数组(Z)。从StartIndex指示的索引处开始复制。索引变量StartIndex的类型必须与A的索引类型匹配。元素总是转移到打包数组Z的开头。(即,从Low(Z)开始)。

数组A和Z的元素类型必须匹配。

8.2数组解压缩

procedure UnPack(

const Z: PackedArrayType;

out A: UnpackedArrayType;

StartIndex: TindexType

);

UnPack会将打包数组(Z)的元素复制到未打包数组(A)。Z中的所有元素被复制到A,从StartIndex索引开始。StartIndex的类型必须与A的索引类型匹配。

数组A和Z的元素类型必须匹配。

8.3示例

program TestArrayPack;

var
  foo : array['a'..'f'] of boolean
    =(false,false,true,false,false,false);
  Bar : bitpacked array[42..47] of Boolean;
  Baz : array['0'..'5'] of boolean;

  C : char;
  I : integer;
begin
  writeln('Array of foo');
  for c :='a' to 'f' do
    write(c,':' , foo[c],' ');//哇,可以用字符做数组索引
  writeln;

  pack(foo,'a',bar);
  writeln('Array of bar');
  for i :=42 to 47 do
    write(i,':' , bar[i],' ');
  writeln;


  unpack(bar,baz,'0');
  writeln('Array of baz');
  for c :='0' to '5' do
    write(c,':' , baz[c],' ');
  writeln;

  readln;
end.
             
                      
             

var
  foo : array['a'..'f'] of boolean
    =(false,false,true,false,false,false);
  Bar : bitpacked array[42..47] of Boolean;
  Baz : array['0'..'5'] of boolean;

  C : char;
  I : integer;
begin
  writeln('Array of foo');
  for c :='a' to 'f' do
    write(c,':' , foo[c],' ');//哇,可以用字符做数组索引
  writeln;

  pack(foo,'a',bar);
  writeln('Array of bar');
  for i :=42 to 47 do
    write(i,':' , bar[i],' ');
  writeln;


  unpack(bar,baz,'0');
  writeln('Array of baz');
  for c :='0' to '5' do
    write(c,':' , baz[c],' ');
  writeln;

  readln;
end.
 类似资料: