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

本文介绍了Pascal编程中两种类型的数组:静态数组和动态数组。静态数组在声明时固定大小,其索引范围在定义中指定,超出范围访问会导致运行时错误。动态数组长度在运行时可变,使用SetLength函数进行大小调整。动态数组通过引用计数,赋值操作不会复制内容,而Copy函数用于在数组间复制数据。此外,还探讨了数组的打包和解包操作,用于节省存储空间。
摘要由CSDN通过智能技术生成

 

、静态数组 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.
             
                      
             
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值