数组

EGL 支持下列类型的数组:

在任一情况下,最多支持 7 个维。

动态数组

在声明记录、固定记录或基本变量数组时,该数组的标识与数组中的元素无关:
  • 有一组特定于该数组的函数,它们允许您在运行时增加或减少元素数目。
  • 特定于数组的属性 maxSize 指示数组中的有效元素数目。缺省值是没有限制;元素数目仅受到目标环境的要求限制。

您不必在声明中指定元素数目,但如果指定了元素数目,则该数目指示元素的初始数目。还可以通过在声明中列示一系列数组常量来指定元素的初始数目,只能对基本变量这样做,不能对记录这样做。

以下示例显示声明动态数组的语法:

  // An array of 5 elements or less
  myDataItem01 CHAR(30)[] { maxSize=5 };

  // An array of 6 elements or less, 
  // with 4 elements initially
  myDataItem02 myDataItemPart[4] { maxSize=6 };

  // An array that has no elements 
  // but whose maximum size is the largest possible
  myRecord myRecordPart[];

  // A 3-element array whose elements 
  // are assigned the values 1, 3, and 5
  position int[] = [1,3,5]; 

可使用文字整数来初始化元素数目,但变量和常量都无效。

在声明数组的数组时,元素的初始数目在从最左边指定的维中和每个后续维中有效,直到某个维缺少初始编号为止。下列声明有效:
  // Valid, with maxsize giving the maximum 
  // for the first dimension
  myInt01 INT[3][];
  myInt02 INT[4][2][] {maxsize = 12};
  myInt03 INT[7][3][1];

  // In the next example, array constants indicate 
  // that the outer array initially has 3 elements.
  // The first element of the outer array is 
  // an array of two elements (with values 1 and 2).
  // The second element of the outer array is
  // an array of three elements (with values 3, 4,5).
  // The third element of the outer array is 
  // an array of two elements (with values 6 and 7).
  myInt04 INT[][] = [[1,2],[3,4,5],[6,7]];
例如,以下示例中的语法无效,原因是数组 myInt04 被声明为没有元素的数组,但其中每个元素被指定了 3 个元素:
  // NOT valid
  myInt04 INT[][3];
  myInt05 INT[5][][2];

被指定为程序或函数参数的数组不能指定元素数目。

当代码引用数组或数组元素时,下列规则适用:
  • 元素下标可以是解析为整数的任何数字表达式,但该表达式不能包括函数调用。
  • 如果代码引用动态数组但未指定下标,则引用的是整个数组。

内存不足状态被视为灾难性错误,并将导致程序结束。

动态数组函数

对每个动态数组都提供了一组函数和只读变量。在以下示例中,数组被称为 series
  series.reSize(100);
数组的名称可能包括一组方括号,每个方括号中包含一个整数。下面是一个示例:
  series INT[][];

  // resizes the second element 
  // of series, which is an array of arrays 
  series[2].reSize(100);

在下面几节中,用数组名替换 arrayName,并请注意,可以通过包名和/或库名来对名称进行限定。

appendAll()

  arrayName.appendAll(appendArray  Array in)
此函数执行下列操作:
  • 通过添加由 appendArray 引用的数组副本,对 arrayName 引用的数组进行追加
  • 根据添加的元素数目增大数组大小
  • 对每个追加的元素指定适当的下标值

appendArray 的元素必须与 arrayName 的元素具有相同的类型。

appendElement()

  arrayName.appendElement(content ArrayElement in)

此函数将一个元素放在指定数组的末尾并将大小增大 1。对于 content,可以替换为具有适当类型的变量;另外,可以指定一个文字,该文字将被赋予在操作期间创建的元素。此过程复制数据;如果指定变量,则该变量仍可用于比较或其它用途。

赋值指定了文字赋值规则。

getMaxSize()

  arrayName.getMaxSize ( ) returns (INT)

此函数返回一个整数,它指示数组中允许的最大元素数目。

getSize()

  arrayName.getSize ( ) returns (INT)

此函数返回一个整数,它指示数组中允许的元素数目。建议在处理动态数组时使用此函数而不是 SysLib.size

另一函数提供的功能等同于 arrayName.getSize 的功能:
SysLib.size( ) returns (INT)

但是,建议您在处理动态数组时使用 arrayName.getSize ( )。

insertElement()

  arrayName.insertElement (content ArrayElement in, index INT in)
此函数执行下列操作:
  • 将一个元素放在目前位于数组中指定位置的元素之前
  • 将数组大小增大 1
  • 将位于所插入元素之后的每个元素的下标增大 1

content 是新内容(常量或变量,并具有适合于数组的类型),index 是指示新元素位置的整数文字或数字变量。

如果 index 比数组中的元素数目大 1,则此函数在数组末尾创建一个新元素并将数组大小增大 1。

removeAll()

  arrayName.removeAll( )

此函数从内存中除去数组元素。该数组可以被使用,但它的大小为零。

removeElement()

  arrayName.removeElement(index INT in)

此函数除去位于指定位置的元素,将数组大小减 1,并将位于所除去的元素后的每个元素的下标都减 1。

index 是一个整数文字或数字变量,它指示要除去的元素的位置。

resize()

  arrayName.resize(size INT in)

此函数将数组的当前大小增加或缩小至 size 中指定的大小,该大小是一个整数文字、常量或变量。如果 size 的值大小数组允许的最大大小,运行单元将终止。

reSizeAll()

  arrayName.reSizeAll(sizes INT[
] in)

此函数增加或缩小多维数组的每个维。参数 sizes 是整数数组,每个连续元素指定连续维的大小。如果重新调整大小的维的数目大于 arrayName 中的维数,或者如果 sizes 中的元素的值大于 arrayName 的等同维中允许的最大大小,运行单元将终止。

setMaxSize()

  arrayName.setMaxSize (size INT in)

该函数设置数组中允许的最大元素数目。如果将最大大小设置为小于数组当前大小的值,运行单元将终止。

setMaxSizes()

  arrayName.setMaxSizes(sizes INT[
] in)

此函数设置多维数组的每个维。参数 sizes 是整数数组,每个连续元素指定连续维的最大大小。如果指定的维的数目大于 arrayName 中的维数,或者如果 sizes 中的元素的值小于 arrayName 的等同维中的当前元素数目,运行单元将终止。

将动态数组用作自变量和参数

可以将动态数组作为自变量传递给 EGL 函数。必须将相关参数定义为与自变量具有相同类型的动态数组;对于数据项,类型必须包含相同的长度和小数位数(如果有的话)。

不能将动态数组作为自变量传递给另一个程序。

下面是将动态数组用作参数的函数的示例:
  Function getAll (employees Employee[])
   ;
  end
    

在运行时,参数的最大大小是对相应自变量声明的最大大小。函数或被调用程序可以更改数组的大小,此更改在调用代码中会生效。

SQL 处理和动态数组

EGL 允许使用动态数组来访问关系数据库的行。有关读取多行的详细信息,请参阅 get。有关添加多行的详细信息,请参阅 add

结构字段数组

当您指定固定结构中的字段具有大于 1 的 occurs 值时,您就声明了结构字段数组,如以下示例所示:
  Record myFixedRecordPart
    10 mySi CHAR(1)[3];
  end
    

如果名为 myRecord 的固定记录基于该部件,则符号 myRecord.mySi 指的是包含三个元素的一维数组,其中每个元素都是一个字符。

结构字段数组的使用

在下列上下文中,可以引用结构字段的整个数组(例如 myRecord.mySi):
  • 作为 in 运算符使用的第二个操作数。此运算符测试数组是否包含给定的值。
  • 作为函数 sysLib.size 中的参数。该函数返回结构字段的 occurs 值。

本身不是数组的数组元素是与任何其它项类似的字段,可以通过各种方式引用该字段;例如,在赋值语句中引用它,或者在函数调用中作为自变量来引用它。

元素下标可以是解析为整数的任何数字表达式,但该表达式不能包括函数调用。

一维结构字段数组

通过先指定数组名称并接着指定用方括号括起来的下标,可以引用一维数组(如 myRecord.mySi)的元素。下标是一个整数或解析为整数的字段;例如,可以使用 myStruct.mySi[2] 来引用示例数组中的第二个元素。下标的变化范围可以是从 1 到结构字段的 occurs 值,如果下标超出该范围,则会发生运行时错误。

如果在需要字段的上下文中使用结构字段数组的名称,但未指定用方括号括起来的下标,则 EGL 假定您正在引用数组的第一个元素,但仅当处于 VisualAge® Generator 兼容性方式时才如此。建议您显式地标识每个元素。如果未处于 VisualAge Generator 兼容性方式,则需要显式地标识每个元素。

下面的示例显示如何引用一维数组中的元素。在那些示例中,valueOne 解析为 1,valueTwo 解析为 2:
  // these refer to the first of three elements:
  myRecord.mySi[valueOne]

  // not recommended; and valid 
  // only if VisualAge Generator
  // compatibility is in effect:
  myRecord.mySi                                    

  // this refers to the second element:
  myRecord.mySi[valueTwo]
一维数组可以带有子结构,如以下示例所示:
  record myRecord01Part
    10 name[3];
      20 firstOne CHAR(20);
      20 midOne CHAR(20);
      20 lastOne CHAR(20);
  end
    

如果名为 myRecord01 的记录基于上一个部件,则符号 myRecord01.name 指的是包含三个元素的一维数组,其中每个元素都带有 60 个字符,myRecord01 的长度是 180。

可以在不引用子结构的情况下引用 myRecord01.name 中的每个元素;例如,myRecord01.name[2] 引用第二个元素。也可以引用元素中的子结构。例如,如果满足唯一性规则,则可以按照下列任何方式来引用第二个元素的后 20 个字符:

  myRecord01.name.lastOne[2]
  myRecord01.lastOne[2]	
  lastOne[2]

仅当可生成部件属性 allowUnqualifiedItemReferences 设置为 yes 时,最后两种方法才有效。

有关不同类型的引用的详细信息,请参阅对变量和常量的引用

多维结构字段数组

如果 occurs 值大于 1 的结构项带有子结构,并且如果下级结构项也具有大于 1 的 occurs 值,则下级结构项声明带有附加维的数组。

让我们考虑另一个记录部件:
  record myRecord02Part
    10 siTop[3];
      20 siNext CHAR(20)[2];
  end
    
如果名为 myRecord02 的记录基于该部件,则一维数组 myRecord02.siTop 的每个元素本身也是一维数组。例如,可以使用 myRecord02.siTop[2] 来引用三个下级一维数组中的第二个一维数组。结构项 siNext 声明二维数组,您可以使用下列任一语法来引用该数组中的元素:
  // row 1, column 2.
  // the next syntax is strongly recommended
  // because it works with dynamic arrays as well
  myRecord02.siTop[1].siNext[2]

  // the next syntax is supported for compatibility
  // with VisualAge Generator
  myRecord02.siTop.siNext[1,2]

要阐明引用了哪个内存区,应了解多维数组中的数据是如何存储的。在当前示例中,myRecord02 包含 120 个字节。引用的区域被划分为具有三个元素的一维数组,每个元素 40 个字节:

  siTop[1]     siTop[2]     siTop[3]

一维数组的每个元素都进一步细分为一个包含两个元素的数组,其每个元素均为 20 个字节,并且位于同一个内存区中:

  siNext[1,1] siNext[1,2] siNext[2,1] siNext[2,2] siNext[3,1] siNext[3,2]
二维数组是按行优先顺序来进行存储的。其含义是如果您以两个 while 循环来初始化数组,则可通过先处理一行中的列,再处理另一行中的列来提高性能:
  // i, j, myTopOccurs, and myNextOccurs are data items; 
  // myRecord02 is a record; and
  // sysLib.size() returns the occurs value of a structure item.
  i = 1;
  j = 1;
  myTopOccurs = sysLib.size(myRecord02.siTop);
  myNextOccurs = sysLib.size(myRecord02.siTop.siNext);
  while (i <= myTopOccurs)
    while (j <= myNextOccurs)
      myRecord02.siTop.siNext[i,j] = "abc";
      j = j + 1;
    end
        i = i + 1;
  end
    

必须为多维数组的每个维指定值。例如,对于二维数组,引用 myRecord02.siTop.siNext[1] 是无效的。

以下是一个三维数组的声明示例:
  record myRecord03Part
    10 siTop[3];
      20 siNext[2];
        30 siLast CHAR(20)[5];
  end
    
如果名为 myRecord03 的记录基于该部件,并且如果满足唯一性规则,则可以按照下列任何方式来引用该数组中的最后一个元素:
  // each level is shown, and a subscript 
  // is on each level, as is recommended.
  myRecord03.siTop[3].siNext[2].siLast[5]

  // each level shown, and subscripts are on lower levels
  myRecord03.siTop.siNext[3,2].siLast[5]
  myRecord03.siTop.siNext[3][2].siLast[5]

  // each level is shown, and subscripts are on the lowest level
  myRecord03.siTop.siNext.siLast[3,2,5]
  myRecord03.siTop.siNext.siLast[3,2][5]
  myRecord03.siTop.siNext.siLast[3][2,5]
  myRecord03.siTop.siNext.siLast[3][2][5]

  // the container and the last level is shown, with subscripts
  myRecord03.siLast[3,2,5]
  myRecord03.siLast[3,2][5]
  myRecord03.siLast[3][2,5]
  myRecord03.siLast[3][2][5]

  // only the last level is shown, with subscripts
  siLast[3,2,5]
  siLast[3,2][5]
  siLast[3][2,5]
  siLast[3][2][5]

如上一示例中所示,可通过添加用括号括起来的一组下标以任意方式引用多维数组的元素。在所有情况下,第一个下标表示第一个维,第二个下标表示第二个维,依此类推。每个下标的变化范围可以是从 1 到相关结构项的 occurs 值,如果某个下标解析为该范围外的数字,则会发生运行时错误。

首先,考虑未涉及下标的情况:
  • 可指定一个列表,该列表以变量名称开头,接着是一级一级的下级结构项的名称,并通过句点将各个名称隔开,如以下示例所示:
      myRecord03.siTop.siNext.siLast
  • 可指定变量的名称,后跟句点,然后是期望的最低级项的名称,如以下示例所示:
      myRecord03.siLast
  • 如果期望的最低级项在给定名称空间中是唯一的,则只能指定该项,如以下示例所示:
      siLast
然后,考虑用于放置数组下标的规则:
  • 可在其中一个元素有效的每一个级别指定下标,如以下示例所示:
      myRecord03.siTop[3].siNext[2].siLast[5]
  • 可在其中一个元素有效的任意级别指定一系列下标,如以下示例所示:
      myRecord03.siTop.siNext[3,2].siLast[5]
  • 可在任意级别指定一系列下标,这一级别位于其中一个元素有效的某个级别或是该级别的下级,如以下示例所示:
      myRecord03.siTop.siNext.siLast[3,2,5]
  • 如果在给定级别指定的下标过多,将发生错误,如以下示例所示:
      // NOT valid
      myRecord03.siTop[3,2,5].siNext.siLast
  • 可用括号隔离下标,也可显示一系列下列,每个下标用逗号隔开;还可以同时使用这两种用法。下列示例有效:
      myRecord03.siTop.siNext.siLast[3,2,5]
      myRecord03.siTop.siNext.siLast[3,2][5]
      myRecord03.siTop.siNext.siLast[3][2,5]
      myRecord03.siTop.siNext.siLast[3][2][5]
使用条款 | 反馈
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.