使用数组

使用类似的语法在数组元素中读写值,用在方括号指定所需的索引。为了给元素赋值,我们要使用 赋值运算 '='。例如,要替换一维数组的第 0 个元素的值:

array1D[0] = 11;

索引从 0 开始。最后一个元素的索引等于元素的个数减 1。当然,我们可以使用常量和任何其他可以简化为整数类型的表达式作为索引(有关表达式的更多详细信息,参见 下一章),如整数变量、函数调用或另一个整数数组的元素(这种方式称为间接寻址)。

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

对于多维数组,必须为所有维度指定索引。

array2D[index1][index2] = 12;

用于索引时,允许的整数类型不包括 longulong。如果我们尝试使用“长整型”的值作为索引,它将被隐式转换为 int,因此编译器给出警告“类型转换可能会导致数据丢失。”

根据相同原则对数组元素进行读取访问。例如,以下是在日志中打印数组元素的命令:

Print(array2D[1][2]);

GoodTimes 脚本中,我们看到了带问候语字符串(包含在 Greeting 函数中)的本地静态数组 messages 的描述,以及该数组元素在 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
}

执行 return 时,我们读取用表达式定义索引的元素:counter++ % 3。模 3 除法(用 '%' 表示)确保递增 1 的 counter 被限定在索引的正确值范围内:0、1 或 2。如果不用模除,则从第四次调用该函数开始,所请求元素的索引将超过数组大小。在这种情况下,会出现程序执行时错误(“数组超出范围”),并将其从图表中卸载。

MQL5 API 包括用于许多数组操作的通用函数:分配内存(仅限动态数组)、填充、复制、排序和在数组中搜索都将在 处理数组一节中介绍。不过现在我们就展示其中一个:ArrayPrint 允许以方便的格式打印日志中的数组元素(考虑维度)。

Arrays.mq5 脚本演示了一些描述数组的例子,其结果在日志中打印。在学习了循环和表达式之后,我们将讨论数组元素的操作。

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
}

其中一个日志条目选项如下所示。

[ 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

名为 array 的数组未进行初始化,因此为其分配的内存可能包含随机值。每次脚本运行时,这些值都会发生变化。建议始终初始化局部数组,以避免出错。

array2Darray2Dt 数组以直观的矩阵形式在日志中打印。这与我们在源代码中以同样方式格式化初始化列表的做法完全无关。

prices 数组具有嵌入式枚举类型 ENUM_APPLIED_PRICE。基本上,数组可以是任何类型,包括结构,函数指针以及其他我们将要分析的类型。由于枚举类型是基于 int 类型,所以值是按数字显示,而不是按元素名称显示(要获得枚举的特定元素的名称,可以使用 EnumToString函数,但 ArrayPrint 中不支持此模式)。

包含 d 数组说明的字符串中存在一处错误:初始值的实体超过了数组大小。