Utilización de arrays

Los valores se escriben en, y se leen de, los elementos del array utilizando una sintaxis similar y especificando los índices necesarios entre corchetes. Para introducir un valor en un elemento, utilizaremos el método operación de asignación '='. Por ejemplo, para sustituir el valor del elemento 0 de un array unidimensional:

array1D[0] = 11;

La indexación empieza por 0. El índice del último elemento es igual a la cantidad de elementos menos 1. Por supuesto, podemos utilizar como índice tanto una constante como cualquier otra expresión que pueda reducirse al tipo entero (para más detalles sobre las expresiones, véase el capítulo siguiente), como una variable entera, una llamada a una función o un elemento de otro array con enteros (el direccionamiento indirecto).

int index;
// ... 
// index = ... // assign an index somehow
// ...
array1D[index] = 11;

En el caso de los arrays multidimensionales, deben especificarse índices para todas las dimensiones.

array2D[index1][index2] = 12;

Los tipos enteros permitidos excluyen long y ulong para los índices. Si intentamos utilizar el valor de un «entero largo» como índice, este se convertirá implícitamente en int, por lo que el compilador emite el aviso «posible pérdida de datos debido a la conversión de tipos».

El acceso de lectura a los elementos del array se organiza según el mismo principio. Por ejemplo, así es como se puede imprimir un elemento del array en el registro:

Print(array2D[1][2]);

En el script GoodTimes hemos visto ya la descripción del array estático local messages con las cadenas de saludos (dentro de la función Greeting) y el uso de sus elementos en el operador return.

string Greeting() 
{
  static int counter = 0;
  static const string messages[3] = // description
  {
    "Good morning""Good day""Good evening" // initialization
  };
  return messages[counter++ % 3];   // using
}

Al ejecutar return leemos el elemento que tiene el índice definido por la expresión counter++ % 3. El módulo de la división, 3, (denotado como '%') asegura que counter, que se incrementará cada vez que se incremente en 1, se forzará al rango de los valores correctos de los índices: 0, 1 o 2. Si no hubiera módulos de división, el índice del elemento solicitado superaría el tamaño del array, empezando por la 4ª llamada de esta función. En tales casos, se produce el error de tiempo de ejecución del programa («array fuera de rango») y se descarga del gráfico.

La API de MQL5 incluye funciones universales para muchas operaciones con arrays: la asignación de memoria (para arrays dinámicos), el rellenado, la copia, ordenación y la búsqueda en arrays se tratan en la sección Trabajar con arrays. Sin embargo, ahora vamos a presentar una de ellas: ArrayPrint permite la impresión de los elementos del array en el registro en un formato conveniente (considerando las dimensiones).

El script Arrays.mq5 muestra algunos ejemplos de descripción de arrays y los resultados se imprimen en el registro. Más adelante analizaremos las manipulaciones con los elementos de los arrays, después de haber estudiado los bucles y las expresiones.

void OnStart()
{
  char array[100];      // without initialization
  int array2D[3][2] =
  {
    {12},             // illustrative formatting
    {34},
    {56}
  };
  int array2Dt[2][3] =
  {
    {135},
    {246}
  };
  ENUM_APPLIED_PRICE prices[] =
  {
    PRICE_OPENPRICE_HIGHPRICE_LOWPRICE_CLOSE
  };
  // double d[5] = {1, 2, 3, 4, 5, 6}; // error: too many initializers
  ArrayPrint(array);    // printing random "garbage" values
  ArrayPrint(array2D);  // showing the 2D array in the log
  ArrayPrint(array2Dt); // a "transposed" appearance of the same data 2D
  ArrayPrint(prices);   // getting to know the values of the price enumeration elements
}

A continuación se representa una de las opciones de entrada en el registro.

[ 0]   0   0   0   0   0   0   0   0   0   0   0   0 -87 105  82 119   0
       0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[34]   0   0   0 -32  -3  -1  -1   7   0   0   2   0   0   0   0   0   0
       0   2   0   0   0   0   0   0   0 -96 104  82 119   0   0   0   0
[68]   0   0   3   0   0   0   0   0  -1  -1  -1  -1   0   0   0   0 100
      48   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    [,0][,1]
[0,]   1   2
[1,]   3   4
[2,]   5   6
    [,0][,1][,2]
[0,]   1   3   5
[1,]   2   4   6
2 3 4 1

El array que lleva por nombre array no tiene ninguna inicialización y, por lo tanto, la memoria asignada al mismo puede contener valores aleatorios. Los valores cambiarán en cada ejecución del script. Se recomienda inicializar siempre los arrays locales, por si acaso.

Los arrays array2D y array2Dt se imprimen en el registro de forma ilustrativa, como matrices. Esto no tiene nada que ver con el hecho de que hayamos formateado las listas de inicialización en el código fuente de la misma manera.

El array prices tiene el tipo de la enumeración integrada ENUM_APPLIED_PRICE. Básicamente, los arrays pueden ser de cualquier tipo, lo que incluye estructuras, punteros a funciones y otras cosas que vamos a ver. Dado que las enumeraciones se basan en el tipo int, los valores se muestran por dígitos, no por los nombres de los elementos (para obtener el nombre de un elemento específico de la enumeración existe la función EnumToString, pero su modo no es compatible con ArrayPrint).

La cadena con la descripción del array d contiene un error: la entidad de valores iniciales excede el tamaño del array.