배열

EGL 배열에 대한 규칙은 배열의 유형에 따라 다릅니다.

EGL은 다음과 같은 유형의 배열을 지원합니다.

모든 경우에 지원되는 최대 차원 수는 7입니다.

EGL에서는 배열의 첫 번째 요소의 색인이 1입니다. 다수의 언어에서 첫 번째 요소의 색인은 0입니다.

배열 리터럴

배열 리터럴은 리터럴(기타 배열 리터럴 포함) 또는 표현식(배열 변수 포함)의 쉼표로 구분된 목록이 포함된 대괄호 쌍으로 구성됩니다. 각각의 배열 리터럴은 유형을 가지고 있으며 지정된 유형의 배열이 허용되는 모든 위치에서 사용할 수 있습니다(예: 배열 변수에 대한 초기자(initializer)로). 다음 표에는 배열 리터럴의 예제가 제공됩니다.

표 1. 배열 리터럴
배열 리터럴 유형
[ 1, 2, 3 ] SMALLINT[]
[ "hi", "Mom" ] STRING[]
[ new myRecord, new myRecord ] myRecord[]
[ (myPay < 0), (myPay > 0) ] BOOLEAN[]
[ [ 1, 2 ], [ 3, 4 ] ] SMALLINT[][]
[ 3, "cow", [ 4.5, 6.7 ] ] ANY[]

배열 리터럴의 요소 유형이 다른 경우 배열의 추론된 유형은 ANY입니다. 배열의 요소는 서로 호환되는 지정이 아니어도 됩니다.

동적 배열

DataTable을 제외한 데이터 파트를 기반으로 변수의 동적 배열을 선언할 수 있습니다.
  • 기본요소
  • DataItem
  • 레코드(임의의 유형)
  • 위임
배열 자체는 해당 요소와 독립적인 ID를 가지고 있습니다.
  • 런타임 시 요소 수를 늘리거나 줄이기 위해 arrayName.functionName() 구문과 함께 배열 이름을 사용하여 함수 세트를 호출할 수 있습니다. "동적 배열 함수"를 참조하십시오.
  • maxSize 배열 특정 특성은 배열에서 유효한 최대 요소 수를 표시합니다. 기본값은 제한이 없습니다. 요소 수는 대상 환경의 요구사항에 의해서만 제한됩니다. 다차원 배열에서 이는 첫 번째 차원만 참조합니다.
선언에서 요소 수를 지정하지 않아도 되지만 지정하는 경우 해당 숫자는 초기 요소 수를 표시합니다. 다차원 배열의 경우에는 별도의 대괄호로 각각의 색인을 묶으십시오.
multiDimensionArray INT[2][3];

동적 배열을 선언하기 위한 구문이 다음 예제에 표시됩니다.

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

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

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

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

리터럴 정수를 사용하여 요소 수를 초기화할 수 있지만 변수와 상수 모두 올바르지 않습니다.

기타 참조 변수("참조 변수" 참조)와 마찬가지로 초기화할 때까지 배열 변수를 사용할 수 없습니다.
myIntArray INT[];
myIntArray[2] = 13; // causes NullValueException

myIntArray2 INT[3]
myIntArray2[2] = 13; // this is legal
배열의 배열을 선언하는 경우 초기 요소 수는 차원에 초기 수가 부족할 때까지 가장 왼쪽에서 지정된 차원과 각각의 후속 차원에서 유효합니다. 다음과 같은 선언은 유효합니다.
  // Valid, with maxsize giving the maximum 
  // for the first dimension
  myIntArray01 INT[3][];
  myIntArray02 INT[4][2][] {maxsize = 12};
  myIntArray03 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).
  myIntArray04 INT[][] = [[1,2],[3,4,5],[6,7]];
다음 예제에서는 예를 들어, myInt04 배열이 요소의 배열로 선언되지 않았기 때문에 구문이 올바르지 않지만 해당 요소 각각에 3개의 요소가 지정됩니다.
  // NOT valid
  myInt04 INT[][3];
  myInt05 INT[5][][2];
코드가 배열 또는 배열 요소를 참조하는 경우 다음과 같은 규칙이 적용됩니다.
  • 색인은 정수로 해석되는 숫자 표현식일 수 있으며 함수 호출을 포함할 수 있습니다.
  • 코드가 동적 배열을 참조하지만 색인을 지정하지 않는 경우에는 배열 전체를 참조합니다.

메모리 부족 상황은 치명적 오류로 처리되며 프로그램을 종료합니다.

다음 예제와 같이 설정된 값 블록을 사용하여 배열을 초기화할 수 있습니다.
myArray1 int[3] {1,2,3};  // array of 3 elements; values are 1, 2, and 3

이는 새 배열을 [1,2,3] 배열 리터럴에 일치시키는 것보다 효율적입니다. 배열 리터럴의 경우 EGL은 값을 myArray1에 지정하기 전에 리터럴 배열을 작성합니다. 설정된 값 블록을 사용하는 경우에는 myArray1만 작성됩니다.

하지만 배열의 초기 크기가 0(영)이므로 다음의 선언이 실패합니다.
myArray2 int[] {1,2,3}; // throws IndexOutOfBoundsException
어떤 이유로 초기 요소 수를 지정하지 않고 배열을 작성해야 하지만 배열은 널일 수 없는 경우(나중에 요소를 추가하려고 함)에는 다음 구문을 사용할 수 있습니다.
myArray3 int[] {};  // zero-length, non-null array

동적 배열을 매개변수 및 인수로 사용

동적 배열은 인수로 EGL 함수에 전달될 수 있습니다. 관련 매개변수는 인수와 동일한 유형의 동적 배열로 정의되어야 하며 요소는 인수와 매개변수 모두에서 동일한 길이 및 소수 자리(있는 경우)를 가져야 합니다.

프로그램 또는 함수에 전달된 배열은 요소 수를 지정할 수 없습니다.

다음 예제에서는 동적 배열을 매개변수로 사용하는 함수를 보여줍니다.
  Function getAll (CustomerRecord myCustomers[])
   ;
  end

런타임 시 매개변수의 최대 크기는 해당 인수에 대해 선언된 최대 크기입니다. 호출된 함수는 배열의 크기를 변경할 수 있으며 변경사항은 코드 호출 시 적용됩니다.

구조 필드 배열

다음 예제와 같이 구조화된 레코드의 필드가 여러 발생을 가지도록 지정하는 경우 구조 필드 배열을 선언합니다.
  Record ExampleStructuredRecord
    10 mySi CHAR(1)[3];
  end

myRecord라는 구조화된 레코드 변수가 해당 정의를 기반으로 하는 경우 myRecord.mySi라는 이름은 각각 하나의 문자인 세 요소의 1차원 배열을 참조합니다.

구조 필드 배열의 사용법

다음의 컨텍스트에서 구조 필드의 전체 배열(예: myRecord.mySi)을 참조할 수 있습니다.
  • in 연산자가 사용하는 두 번째 피연산자로. 해당 연산자는 지정된 값이 배열에 포함되는지 여부를 테스트합니다.
  • sysLib.size() 함수에서 매개변수로. 해당 함수는 배열의 요소 수를 리턴합니다.

자체가 배열이 아닌 배열 요소는 다른 모든 필드와 같은 필드이므로 다양한 방식으로 해당 필드를 참조할 수 있습니다(예: assignment문에서 또는 함수 호출 시 인수로).

요소 색인은 정수로 해석되는 숫자 표현식일 수 있지만 해당 표현식은 함수 호출을 포함할 수 없습니다.

1차원 구조 필드 배열

대괄호로 묶인 색인 번호가 뒤따라오는 배열의 이름을 사용하여 myRecord.mySi와 같은 1차원 배열의 요소를 참조할 수 있습니다. 예를 들어, 예제 배열의 두 번째 요소를 myStruct.mySi[2]로 참조할 수 있습니다. 색인은 1부터 배열의 요소 수까지 다양할 수 있으며 색인이 해당 범위를 벗어나면 런타임 오류가 발생합니다.

색인을 지정하는 경우가 아니면 단일 값이 필요한 컨텍스트에서는 구조 필드 배열의 이름을 사용할 수 없습니다(가능한 예외에 대해서는 이 주제에 있는 "호환성" 참조).

다음 예제와 같이 1차원 배열을 하위 구조화할 수 있습니다.
  Record Record01
    10 name[3];
      20 firstOne CHAR(20);
      20 midOne CHAR(20);
      20 lastOne CHAR(20);
  end

myRecord01이라는 레코드가 이전의 레코드 정의를 기반으로 하는 경우 myRecord01.name이라는 이름은 각각 60자를 가진 3개 요소의 1차원 배열을 참조하며 myRecord01의 길이는 180입니다.

하위 구조에 대한 참조 없이 myRecord01.name의 각 요소를 참조할 수 있습니다. 예를 들어, myRecord01.name[2]은 두 번째 요소를 참조합니다. 요소 내의 하위 구조도 참조할 수 있습니다. 예를 들어, 고유성 규칙이 충족되는 경우 다음과 같은 방법으로 두 번째 요소의 마지막 20자를 참조할 수 있습니다.

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

allowUnqualifiedItemReferences 특성이 YES로 설정된 경우에만 최종 예제가 유효합니다.

다른 유형의 참조에 대한 자세한 정보는 "EGL의 참조 변수"를 참조하십시오.

다차원 구조 필드 배열

다중 요소를 가진 구조 필드가 하위 구조화되고 하위 구조 필드도 다중 요소를 가지는 경우 하위 구조 필드는 추가적인 차원을 가진 배열을 선언합니다("호환성" 참조).

또다른 레코드 파트를 생각해 보십시오.
  Record Record02
    10 siTop[3];
      20 siNext CHAR(20)[2];
  end
myRecord02라는 레코드 변수가 해당 파트를 기반으로 하는 경우에는 myRecord02.siTop 1차원 배열의 각 요소 자체가 1차원 배열입니다. 예를 들어, 세 하위 1차원 배열 중 두 번째를 myRecord02.siTop[2]로 참조할 수 있습니다. siNext 구조 필드는 2차원 배열을 선언하며 사용자는 다음 구문 중 하나를 사용하여 해당 배열의 요소를 참조할 수 있습니다.
  // 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
  // but not recommended
  myRecord02.siTop.siNext[1,2]

참조 중인 메모리의 영역을 명확하게 하려면 다차원 배열의 데이터가 저장되는 방식을 생각해 보십시오. 현재 예제에서 myRecord02는 120바이트를 구성합니다. 참조된 영역은 각각 40바이트인 세 요소의 1차원 배열로 구분됩니다.

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

1차원 배열의 각 요소는 메모리의 동일한 영역에서 각각 20바이트인 두 요소의 배열로 다시 구분됩니다.

  siNext[1,1] siNext[1,2] siNext[2,1] siNext[2,2] siNext[3,1] siNext[3,2]
2차원 배열은 행 우선 순서로 저장됩니다. 한 가지 영향은 이중 while 루프에서 배열을 초기화하면 두 번째 열을 처리하기 전에 한 행의 열을 처리하여 성능이 향상된다는 것입니다. 다음 예제에서는 이 아이디어를 보여줍니다.
  // i, j, myTopIndex, and myNextIndex are variables; 
  // myRecord02 is a record; and
  // sysLib.size() returns the number of elements in a structure field.
  i = 1;
  j = 1;
  myTopIndex = sysLib.size(myRecord02.siTop);
  myNextIndex = sysLib.size(myRecord02.siTop.siNext);
  while (i <= myTopIndex)
    while (j <= myNextIndex)
      myRecord02.siTop.siNext[i,j] = "abc";
      j = j + 1;
    end    i = i + 1;
  end

다차원 배열의 각 차원에 대해 값을 지정해야 합니다. 예를 들어, 참조 myRecord02.siTop.siNext[1]는 2차원 배열에 대해 올바르지 않습니다.

3차원 배열의 예제 선언은 다음과 같습니다.
  Record Record03
    10 siTop[3];
      20 siNext[2];
        30 siLast CHAR(20)[5];
  end
배열 색인을 포함하는 방법에 대해 이해하려면 색인이 포함되지 않은 상황을 생각해 보십시오.
  • 변수의 이름으로 시작한 후 다음 예제와 같이 각각의 이름이 마침표로 구분되는 점점 더 하위인 구조 필드의 이름으로 계속되는 목록을 지정할 수 있습니다.
      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]

호환성

표 2. 배열에 대한 호환성 고려사항
플랫폼 문제
COBOL 생성 동적 배열에 대해 다차원 배열이 지원되지 않습니다.
JavaScript 생성 ANY, BIGINT, BIN(소수 자리가 없는 경우에만), 부울, DataItem, DATE, DECIMAL, 위임, 사전, FLOAT, INT, NUM, NUMBER, SMALLFLOAT, SMALLINT, STRING(크기 제한이 없는 경우에만), TIME, TIMESTAMP, NUM, MONEY, 서비스 파트, 인터페이스 파트, 외부 유형(스테레오타입 JavaScript), 지원되는 유형의 배열, 구조화되지 않은 기본, 예외 및 SQL 레코드 파트 유형이 지원됩니다.

ArrayDictionary, BIN(소수 자리 포함), BLOB, CHAR, CLOB, DBCHAR, HEX, INTERVAL, MBCHAR, NUMC, STRING(크기 제한 있음), PACF, UNICODE 및 구조화된 레코드 파트 유형은 지원되지 않습니다.

VisualAge® Generator 호환 모드 단일 값이 필요한 컨텍스트에서 색인 없이 구조 필드 배열의 이름을 사용하는 경우 EGL은 사용자가 배열의 첫 번째 요소를 참조한다고 가정합니다.