Matrices

EGL da soporte a los siguientes tipos de matrices:

En cualquier caso, el número máximo de dimensiones soportadas es siete.

Matrices dinámicas

Cuando declara una matriz de variables primitivas o de registros (tipo BasicRecord, DLISegment o SQLRecord), la matriz tiene una identidad independiente de los elementos de la matriz:
  • Hay un conjunto de funciones específicas de la matriz que permite aumentar o disminuir el número de elementos en tiempo de ejecución.
  • La propiedad específica de la matriz maxSize indica cuántos elementos son válidos en la matriz. El valor por omisión no está enlazado, el número de elementos solo está limitado por los requisitos del entorno destino.

No es necesario especificar un número de elementos en la declaración pero, si lo hace, el número indica el número inicial de elementos. También puede especificar el número inicial de elementos listando una serie de constantes de matriz en la declaración, como puede hacerse solo con variables primitivas, no con registros.

La sintaxis para declarar una matriz dinámica se muestra en los ejemplos siguientes:

  // Una matriz de 5 elementos o memos
  myDataItem01 CHAR(30)[] { maxSize=5 };

  // Una matriz de 6 elementos o menos, 
  // con 4 elementos inicialmente
  myDataItem02 myDataItemPart[4] { maxSize=6 };

  // Una matriz que no tiene elementos 
  // pero cuyo tamaño máximo es el mayor posible
  myRecord ExampleRecordPart[];

  // Una matriz de 3 elementos a cuyos elementos 
  // se asignan los valores 1, 3 y 5
  position int[] = [1,3,5]; 

Puede utilizar un entero literal para inicializar el número de elementos pero ni una variable ni una constante son válidas.

Cuando declara una matriz de matrices, un número inicial de elementos es válido en la dimensión especificada más a la izquierda y en cada dimensión subsiguiente hasta que a una dimensión le falte un número inicial. Las declaraciones siguientes son válidas:
  // Válida, con maxsize indicando el máximo 
  // para la primera dimensión
  myInt01 INT[3][];
  myInt02 INT[4][2][] {maxsize = 12};
  myInt03 INT[7][3][1];

  // En el ejemplo siguiente, las constantes de matriz indican 
  // que la matriz externa tiene 3 elementos inicialmente.
  // El primer elemento de la matriz externa es 
  // una matriz de dos elementos (con valores 1 y 2).
  // El segundo elemento de la matriz externa es
  // una matriz de tres elementos (con valores 3, 4, 5).
  // El tercer elemento de la matriz externa es 
  // una matriz de dos elementos (con valores 6 y 7).
  myInt04 INT[][] = [[1,2],[3,4,5],[6,7]];
En el ejemplo siguiente, la sintaxis no es válida porque (por ejemplo) la matriz myInt04 se declara como una matriz sin elementos pero a cada uno de esos elementos se le asignan 3 elementos:
  // NO válido
  myInt04 INT[][3];
  myInt05 INT[5][][2];

Una matriz especificada como un parámetro de función o programa no puede especificar el número de elementos.

Cuando el código hace referencia a una matriz o a un elemento de matriz, se aplican las siguientes normas:
  • Un subíndice de elemento puede ser cualquier expresión numérica que dé como resultado un entero, pero la expresión no puede incluir una invocación de función.
  • Si el código hace referencia a una matriz dinámica pero no especifica subíndices, la referencia se hace a la matriz en su totalidad.

Una situación de memoria insuficiente se trata como un error catastrófico y finaliza el programa.

Funciones de matriz dinámica

Para cada matriz dinámica existe un conjunto de funciones y variables de sólo lectura. En el ejemplo siguiente, la matriz se llama series:
  series.reSize(100);
El nombre de la matriz puede incluir un conjunto de corchetes, cada uno con un entero. A continuación se ofrece un ejemplo:
  series INT[][];

  // redimensiona el segundo elemento 
  // de series, que es una matriz de matrices 
  series[2].reSize(100);

En las secciones siguientes, sustituya el nombre de matriz por nombreMatriz y tenga en cuenta que el nombre puede calificarse mediante un nombre de paquete, un nombre de biblioteca o ambos.

appendAll()

  nombreMatriz.appendAll(añadirMatriz  Array in)
Esta función realiza lo siguiente:
  • Se añade a la matriz a la que se hace referencia mediante nombreMatriz, añadiendo una copia de la matriz a la que se hace referencia mediante añadirMatriz
  • Incrementa el tamaño de la matriz en el número de elementos añadidos
  • Asigna un valor de índice apropiado a cada uno de los elementos añadidos

Los elementos de añadirMatriz deben ser del mismo tipo que los elementos de nombreMatriz.

appendElement()

  nombreMatriz.appendElement(contenido ArrayElement in)

Esta función coloca un elemento al final de la matriz especificada e incrementa el tamaño en uno. Para contenido, puede sustituir una variable del tipo apropiado; como alternativa, puede especificar un literal que se asigna a un elemento creado durante la operación. El proceso copia datos; si asigna una variable, dicha variable todavía está disponible para fines de comparación u otros.

Las normas para asignar un literal se especifican en la sección Asignaciones.

getMaxSize()

  nombreMatriz.getMaxSize ( ) returns (INT)

Esta función devuelve un entero que indica el número máximo de elementos permitidos en la matriz.

getSize()

  nombreMatriz.getSize ( ) returns (INT)

Esta función devuelve un entero que indica el número de elementos dn la matriz. Es recomendable utilizar esta función en lugar de SysLib.size al trabajar con matrices dinámicas.

Otra función proporciona una funcionalidad equivalente a la de nombreMatriz.getSize:
SysLib.size( ) returns (INT)

Sin embargo, es recomendable utilizar nombreMatriz.getSize ( ) al trabajar con matrices dinámicas.

insertElement()

  nombreMatriz.insertElement (contenido ArrayElement in, índice INT in)
Esta función realiza lo siguiente:
  • Coloca un elemento delante del elemento que ahora está en la ubicación especificada de la matriz
  • Incrementa el tamaño de la matriz en uno
  • Incrementa el índice de cada elemento que reside después del elemento insertado

contenido es el nuevo contenido (una constante o variable del tipo apropiado para la matriz) e índice es un literal entero o una variable numérica que indica la ubicación del nuevo elemento.

Si índice tiene un elemento más que el número de elementos de la matriz, la función crea un nuevo elemento al final de la matriz e incrementa el tamaño de la matriz en uno.

removeAll()

  nombreMatriz.removeAll( )

Esta función elimina de la memoria los elementos de la matriz. La matriz puede utilizarse, pero su tamaño es cero.

removeElement()

  nombreMatriz.removeElement(índice INT in)

Esta función elimina el elemento de la ubicación especifica, disminuye el tamaño de la matriz en uno y disminuye el índice de cada elemento que reside después del elemento eliminado.

índice es un literal entero o una variable numérica que indica la ubicación del elemento que debe eliminarse.

resize()

  nombreMatriz.resize(tamaño INT in)

Esta función aumenta o disminuye el tamaño actual de la matriz hasta el tamaño especificado en tamaño que es un literal entero, una constante o una variable. Si el valor de tamaño es mayor que el tamaño máximo permitido para la matriz, la unidad de ejecución termina.

reSizeAll()

  nombreMatriz.reSizeAll(tamaños INT[
] in)

Esta función añade o disminuye cada dimensión de una matriz multidimensional. El parámetro tamaños es una matriz de enteros en la que cada elemento sucesivo especifica el tamaño de una dimensión sucesiva. Si el número de dimensiones redimensionadas es mayor que el número de dimensiones en nombreMatriz o si un valor de un elemento de tamaños es mayor que el tamaño máximo permitido en la dimensión equivalente de nombreMatriz, la unidad de ejecución termina.

setMaxSize()

  nombreMatriz.setMaxSize (tamaño INT in)

La función establece el número máximo de elementos permitidos en la matriz. Si establece el tamaño máximo en un valor menor que el tamaño actual de la matriz, la unidad de ejecución termina.

setMaxSizes()

  nombreMatriz.setMaxSizes(tamaños INT[
] in)

Esta función establece cada dimensión de una matriz multidimensional. El parámetro tamaños es una matriz de enteros en la que cada elemento sucesivo especifica el tamaño máximo de una dimensión sucesiva. Si el número de dimensiones especificado es mayor que el número de dimensiones de nombreMatriz o si un valor de un elemento de tamaños es menor que el número actual de elementos de la dimensión equivalente de nombreMatriz, la unidad de ejecución termina.

Utilización de matrices dinámicas como argumentos y parámetros

Una matriz dinámica puede pasarse como argumento a una función EGL. El parámetro relacionado debe definirse como una matriz dinámica del mismo tipo que el argumento; y para un elemento de datos, el tipo debe incluir la misma longitud y posiciones decimales, si existen.

Una matriz dinámica de los siguientes tipos puede pasarse a un programa:
  • Un tipo primitivo
  • Un registro de tipo BasicRecord, DLISegment o SQLRecord
A continuación se ofrece un ejemplo de una función que utiliza una matriz dinámica como parámetro:
  Function getAll (employees Employee[])
   ;
  end

Durante la ejecución, el tamaño máximo de un parámetro es el tamaño máximo declarado para el argumento correspondiente. La función invocada puede cambiar el tamaño de la matriz y el cambio se aplica en el código invocante.

Proceso SQL y matrices dinámicas

EGL permite utilizar una matriz dinámica para acceder a las filas de una base de datos relacional. Para obtener información detallada sobre cómo leer varias filas, consulte la sección get. Para obtener información detallada sobre cómo añadir varias filas, consulte la sección add.

Matrices de campos de estructura

Una matriz de campo de estructura se declara cuando se especifica que un campo de una estructura fija tiene varias apariciones, como en el ejemplo siguiente:
  Record ExampleFixedRecordPart
    10 mySi CHAR(1)[3];
  end

Si un registro fijo llamado myRecord se basa en dicho componente, el símbolo myRecord.mySi hace referencia a una matriz unidimensional de tres elementos, cada uno de los cuales es un carácter.

Utilización de una matriz de campos de estructura

Puede hacer referencia a toda una matriz de campos de estructura (por ejemplo, myRecord.mySi) en los siguientes contextos:
  • Como segundo operando que utiliza un operador in. El operador prueba si un determinado valor está contenido en la matriz.
  • Como parámetro de la función sysLib.size. Esta función devuelve el valor de apariciones del campo de estructura.

Un elemento de matriz que no es en sí mismo una matriz es un campo como cualquier otro, y se puede hacer referencia a dicho campo de varias maneras; por ejemplo, en una sentencia assignment o como argumento en una invocación de función.

Un subíndice de elemento puede ser cualquier expresión numérica que dé como resultado un entero, pero la expresión no puede incluir una invocación de función.

Matriz de campo de estructura unidimensional

Puede hacer referencia a un elemento de una matriz unidimensional, como por ejemplo myRecord.mySi, utilizando el nombre de la matriz seguido de un subíndice entre corchetes. El subíndice es un entero o un campo que se resuelve en un entero; por ejemplo, puede hacer referencia al segundo elemento de la matriz de ejemplo como myStruct.mySi[2]. El subíndice puede variar de 1 al valor de apariciones del campo de estructura, y se produce un error de entorno de ejecución si el subíndice está fuera de este rango.

Si utiliza el nombre de una matriz de campos de estructura en un contexto que requiere un campo, pero no especifica un subíndice entre corchetes, EGL presupone que hace referencia al primer elemento de la matriz, pero sólo si está en modalidad de compatibilidad de VisualAge Generator. Es aconsejable identificar cada elemento explícitamente. Si no está en modalidad de compatibilidad de VisualAge Generator, será necesario que identifique cada elemento explícitamente.

Los ejemplos siguientes muestran cómo hacer referencia a elementos de una matriz unidimensional. En estos ejemplos, valueOne se resuelve en 1 y valueTwo se resuelve en 2:
  // estos ejemplos hacen referencia al primero de tres elementos:
  myRecord.mySi[valueOne]

  // no recomendado y válido 
  // sólo si la compatibilidad de
  // VisualAge Generator está en vigor:
  myRecord.mySi                                    

  // este ejemplo hace referencia al segundo elemento:
  myRecord.mySi[valueTwo]
Una matriz unidimensional puede tener subestructuras, como en el siguiente ejemplo:
  record myRecord01Part
    10 name[3];
      20 firstOne CHAR(20);
      20 midOne CHAR(20);
      20 lastOne CHAR(20);
  end

Si un registro llamado myRecord01 se basa en el componente anterior, el símbolo myRecord01.name hace referencia a una matriz unidimensional de tres elementos, cada uno de los cuales tiene 60 caracteres y la longitud de myRecord01 es 180.

Puede hacer referencia a cada elemento de myRecord01.name sin hacer referencia a la subestructura; por ejemplo, myRecord01.name[2] hace referencia al segundo elemento. También puede hacer referencia a una subestructura dentro de un elemento. Si, por ejemplo, se cumplen las normas de exclusividad, puede hacer referencia a los 20 últimos caracteres del segundo elemento de las siguientes maneras:

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

Los dos últimos son válidos solo si la propiedad de componente generable allowUnqualifiedItemReferences se establece en yes.

Para obtener detalles sobre los diferentes tipos de referencias, consulte la sección Referencias a variables y constantes.

Matriz de campos de estructura multidimensional

Si un elemento de estructura con un valor de apariciones mayor que uno tiene subestructuras y si una estructura subordinada también tiene un valor de apariciones mayor que uno, el elemento de estructura subordinada declara una matriz con una dimensión adicional.

Consideremos otro componente de registro:
  record myRecord02Part
    10 siTop[3];
      20 siNext CHAR(20)[2];
  end
Si un registro llamado myRecord02 se basa en dicho componente, cada elemento de la matriz unidimensional myRecord02.siTop es en sí mismo una matriz unidimensional. Por ejemplo, puede hacer referencia a la segunda de las tres matrices unidimensionales subordinadas como myRecord02.siTop[2]. El elemento de estructura siNext declara una matriz bidimensional, y se puede hacer referencia un elemento de dicha matriz mediante cualquiera de estas sintaxis:
  // fila 1, columna 2.
  // la sintaxis siguiente se recomienda encarecidamente
  // porque también funciona con matrices dinámicas
  myRecord02.siTop[1].siNext[2]

  // la sintaxis siguiente está soportada a efectos
  // de compatibilidad con VisualAge Generator
  myRecord02.siTop.siNext[1,2]

Para aclarar a qué área de memoria se hace referencia, consideremos cómo se almacenan los datos en una matriz multidimensional. En el ejemplo actual, myRecord02 constituye 120 bytes. El área a la que se hace referencia se divide en una matriz unidimensional de tres elementos, cada uno de los cuales tiene 40 bytes:

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

Cada elemento de la matriz unidimensional se vuelve a subdividir en una matriz de dos elementos, de 20 bytes cada uno, en la misma área de memoria:

  siNext[1,1] siNext[1,2] siNext[2,1] siNext[2,2] siNext[3,1] siNext[3,2]
Una matriz bidimensional se almacena en orden de fila principal. Una implicación es que si se inicializa una matriz en un bucle while doble, se obtiene un mayor rendimiento procesando las columnas de una fila antes de procesar las columnas de una segunda fila:
  // i, j, myTopOccurs y myNextOccurs son elementos de datos; 
  // myRecord02 es un registro; y
  // sysLib.size() devuelve el valor de apariciones de un elemento de estructura.
  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

Debe especificar un valor para cada dimensión de una matriz multidimensional. La referencia myRecord02.siTop.siNext[1], por ejemplo, no es válida para una matriz bidimensional.

A continuación se ofrece una declaración de ejemplo de una matriz tridimensional:
  record myRecord03Part
    10 siTop[3];
      20 siNext[2];
        30 siLast CHAR(20)[5];
  end
Si un registro llamado myRecord03 se basa en dicho componente y se cumplen las normas de exclusividad, puede hacer referencia al último elemento de la matriz de las siguientes maneras:
  // se muestra cada nivel y hay un 
  // subíndice en cada nivel, tal como se recomienda.
  myRecord03.siTop[3].siNext[2].siLast[5]

  // se muestra cada nivel y los subíndices están en niveles inferiores
  myRecord03.siTop.siNext[3,2].siLast[5]
  myRecord03.siTop.siNext[3][2].siLast[5]

  // se muestra cada nivel y los subíndices están en el nivel más bajo
  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]

  // se muestran el contenedor y el último nivel, con subíndices
  myRecord03.siLast[3,2,5]
  myRecord03.siLast[3,2][5]
  myRecord03.siLast[3][2,5]
  myRecord03.siLast[3][2][5]

  // solo se muestra el último nivel, con subíndices
  siLast[3,2,5]
  siLast[3,2][5]
  siLast[3][2,5]
  siLast[3][2][5]

Tal como indica el ejemplo anterior, puede hacer referencia a un elemento de una matriz multidimensional añadiendo un conjunto de subíndices entre corchetes de cualquiera de las maneras posibles. En todos los casos, el primer subíndice hace referencia a la primera dimensión, el segundo subíndice hace referencia a la segunda dimensión y así sucesivamente. Cada subíndice puede variar de 1 al valor de apariciones del elemento de estructura relacionado, y se produce un error de entorno de ejecución si un subíndice se resuelve en un número que está fuera de dicho rango.

Primero, considere la situación en la que no hay subíndices implicados:
  • Puede especificar una lista que empieza por el nombre de la variable y continúa con los nombres de elementos de estructura subordinada, con cada nombre separado del siguiente por un punto, como en este ejemplo:
      myRecord03.siTop.siNext.siLast
  • Puede especificar el nombre de la variable, seguido por un punto, seguido por el nombre del elemento de interés de nivel más bajo, como en este ejemplo:
      myRecord03.siLast
  • Si el elemento de interés de nivel más bajo es exclusivo en un espacio de nombres dado, puede especificar solamente ese elemento, como en este ejemplo:
      siLast
A continuación, considere las reglas para colocar subíndices de matriz:
  • Puede especificar un subíndice en cada nivel en el que uno de varios elementos sea válido, como en este ejemplo:
      myRecord03.siTop[3].siNext[2].siLast[5]
  • Puede especificar una serie de subíndices en cualquier nivel en el que uno de varios elementos sea válido, como en este ejemplo:
      myRecord03.siTop.siNext[3,2].siLast[5]
  • Puede especificar una serie de subíndices en cualquier nivel en el que uno de varios elementos sea válido, como en este ejemplo:
      myRecord03.siTop.siNext.siLast[3,2,5]
  • Si asigna más subíndices de los que corresponde en un nivel dado, se produce un error, como en el siguiente ejemplo:
      // NO válido
      myRecord03.siTop[3,2,5].siNext.siLast
  • Puede aislar un subíndice en un corchete o puede visualizar una serie de subíndices, cada uno separado del siguiente por una coma o puede combinar los dos usos. Los ejemplos siguientes son válidos:
      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]
Comentarios
(C) Copyright IBM Corporation 2000, 2005. Reservados todos los derechos.