BBTrading - 量化交易社区 | 交易干货分享 | 助力投资交易更好成功!

【0基础学编程2-3】数据结构 – 数组应用实例

数组的概念



数组是一种数据结构,用于存储相同类型的多个元素。它是一种有序的集合,每个元素可以通过索引访问。
以下是一些关于数组的重要概念:

  • 元素:数组由一系列元素组成。每个元素都有一个特定的位置,可以通过索引来唯一标识。元素可以是任何数据类型,如整数、实数、布尔值、字符串等。
  • 索引:数组中的每个元素都有一个索引(坐标),用于唯一标识该元素。索引通常从0开始,逐个递增。通过索引,可以访问和修改数组中的特定元素。
  • 大小:数组的大小是指数组中元素的数量。它决定了数组的容量和可用的索引范围。大小可以在创建数组时指定,也可以在使用中通过数组操作函数指定。
  • 初始化:初始化是指在创建数组时为数组的元素赋予初始值。可以在声明数组时进行初始化,也可以在后续的代码中赋值给数组的元素。
  • 访问元素:通过使用数组的名称和索引,可以访问和操作数组中的元素。通过将索引放在方括号内,可以获取或修改特定位置的元素。
  • 遍历:遍历是指访问数组中的每个元素。可以使用循环结构(如for循环或while循环)来遍历整个数组,以便处理每个元素。
  • 多维数组:多维数组是指具有两个或多个维度的数组。它们可以用于表示表格、矩阵和更复杂的数据结构。多维数组可以通过多个索引来访问和操作。

    数组是编程中常用的数据结构之一,它提供了一种有效的方式来组织和处理大量的相似数据。了解这些数组的概念和特性可以帮助您更好地理解和使用数组在编程中的重要性。

数组的分类与作用


在MQL4中,数组可以存储整数、实数、布尔值和字符串等不同类型的数据。使用中括号[ ]表示。括号内的数值可以表示当前数组的索引值或者容量,其中,数组可以用维度来表示类型的多样性,包括1维、2维、多维数组,在EA编程中,1维是使用频率最高的数组。其次是二维,另外在MQL4中,数组的维度最高支持4维,每一种维度的数组在使用上具有不同的方式和难度,应用场景也不同。本期我们主要讲解一下1、2维数组。

数组分类

  • 一维数组
    一维数组是最简单的数组形式,它由一系列按顺序排列的元素组成。每个元素在数组中都有一个唯一的索引,通过索引可以访问和操作数组中的元素,也可以称为线性数据结构。在数组中,每个位置的排序位置称之为“索引”,既每个位置的编号,索引位置从0开始计数(0也算一个单位)。在下列图示中是一个具有9个元素单位的一维数组,排序从0到8开始,每个位置存放了同类型不同值的数据,组成了一个完整的数据结构(线性数据结构)。
  • 二维数组:
    二维数组的使用方式和一维有些类似,元素在数组中都有一个唯一的索引,访问和操作同样需要以索引位置来定位。但它是一种具有两个维度的数组,由行和列组成的表格状结构,也称之为矩阵数据结构。在日常的表格中,我们通常以第几行第几列来查找数据,而二维数组中也是同样的方法。在下列图示中是一个具有3行9列(x27)元素大小的二维数组,其中每一个位置的配列是按照[行][列]的格式来代表索引位置,组成了一个完整的矩阵数据结构。举例此时我们要寻找第二行第七列的数据,那索引位置就是[1][6],值是25.1,比如此时我们声明的是浮点类型的数组,用表达式:double cvalue=[1][6];就可以直接表示该位置的实际数值。

数组形态

下列两种形态,严格意义上来说并不是真正意义上的形态,而是一种以使用习惯划分的概念,无论是动态还是静态,在MQL4中都可以使用ArrayResize()函数在为后续的运行中为其分配新的大小,在此之前,对默认数组大小调整只是一种提前初始化的手段。但值得一提的是,养成这种习惯可以更好的对程序的运行效率做管控,也有利于代码的可读性与可维护性得到提升

  • 静态数组:
    静态数组指的是在定义静态数组时,直接指定数组的大小,即称为静态。静态数组常用于存储已知元素数量时声明和使用,其内存分配机制是固定的。
  • 动态数组:
    动态数组在定义时无需分配大小,可在使用时再根据需求再分配容量的数组,

数组的应用

简单认识一下MQL4中的几个常用数组操作函数:

1、定义数组
其中ibars为静态数组,在定义时我们直接设置成x5的大小,并给每一个元素赋值,这里我们使用货币名称来演示。另外两个数组为动态数组,其值为空。

2、初始化操作/使用前准备
由于初始化并不需要多次操作,这里我们只需要OnInit()函数中执行即可,该函数的含义请查阅第一期的教程。
初始化时,我们需要用到ArrayResize()函数,该函数的构造为3个传入参数,这里我们只使用两个即可,第一个参数为需要初始化的数组名称,第二个为要设置的大小。但此时我们暂时先设0,随后使用ArrayCopy()函数将已经定义好的ibars数组元素复制到symbol数组中来。

再使用for循环遍历的方式,更改每一个元素,这里因为我们使用的是自定义的货币名称,为了尽可能适配各个平台,我采用了一种特殊手法去做二次赋值,后续我会在“字符串函数”的章节中细说。这里先顺便复习一下for循环的基本概念:
(知识回顾:for循环)

  • for 循环:通过循环遍历数组中的每个元素。
  • int i = 0:初始化循环变量 i,将其设置为数组的起始索引。
  • i < ArraySize(symbol):循环条件,当 i 小于 symbol 数组的大小时,继续执行循环体。
  • i++:每次循环结束后,递增 i 的值。
  • 在循环体内部,执行以下操作:
    symbol[i]:访问数组 symbol 中的第 i 个元素。
    StringSubstr(Symbol(), 6, 6):使用 StringSubstr 函数从当前货币对的名称中提取子字符串。第一个参数 Symbol() 返回当前货币对的名称,第二个参数 6 表示子字符串的起始位置,第三个参数 6 表示子字符串的长度。
    symbol[i] + StringSubstr(Symbol(), 6, 6):将数组 symbol 中的第 i 个元素与提取的后缀名进行拼接。
    symbol[i] = symbol[i] + StringSubstr(Symbol(), 6, 6):将拼接后的结果赋值给数组 symbol 中的第 i 个元素。

3、实践
##一维数组:这次我们同样使用OnTimer()来演示。

  • 第1步:清空并刷新 modeBid 数组,确保每次调用函数时都是最新的数据。
  • 第2步:调整 modeBid 数组的大小为 symbol 数组的大小,以确保两者的元素个数一致。
  • 第3步:使用 for 循环遍历 modeBid 数组,通过 symbol 数组中对应索引的货币名称获取相应的买入价格,并将其存储到 modeBid 数组中。
  • 第4步:将获取到的数组元素输出到图表上,这里我们也是使用同样的循环遍历手法,通过一系列图形函数创建和设置元素的显示属性,以显示货币名称和对应的买入价格。
  • 第5步:使用 Comment 函数在终端窗口中显示单独访问数组元素的结果,这里我设置显示第三个元素的货币名称和对应的买入价格。
  • 输出结果:

##二维数组:二维数组中的内容我们直接在当前函数中进行,添加以下代码。

  • 第1步:定义一个二维数组double bidAskArray[ ][2] ;用于存储BID和ASK价格两种元素,因此第二维大小为2。[ ][2] 表示数组的第一维大小不指定,将所有元素的初始值设置为0。
  • 第2步:ArrayResize(bidAskArray, ArraySize(symbol));ArrayResize 函数用于调整数组的大小。这里将二维数组 bidAskArray 的行数(第一维)设置为 symbol 数组的大小,以便存储每个货币对应的BID和ASK价格。
    特别提示:
    假如symbol数组的大小是5,由于bidAskArray是二维并且第二维度大小为2,因此bidAskArray数组的大小总量即为5*2=10,所以直接使用ArraySize()函数来遍历是不科学的,因为我们还需要用到symbol数组(X5),必然会造成数组越界的情况发生(error:
    array out of range in!)。这里有多重解决办法:

    除此之外,ArrayRange()函数也能派上用场,直接指定用哪一个维度来遍历,这里选择第一维,用0表示:ArrayRange(bidAskArray,0);
  • 第3步:开始整活
    for (int i = 0; i < ArrayRange(bidAskArray,0); i++){
    bidAskArray[i][0] = MarketInfo(symbol[i], MODE_BID);
    bidAskArray[i][1] = MarketInfo(symbol[i], MODE_ASK);
    }
    这段代码使用循环遍历 symbol 数组,并通过 MarketInfo 函数获取每个货币对应的BID和ASK价格,然后将这些价格分别存储到二维数组 bidAskArray 的第一列和第二列中。
    第五步:将获取到的BID和ASK价格显示在图表上。通过循环遍历 symbol 数组,生成每个货币对应的唯一标识符 ,构建图形输出片段,最终,每个货币对应的BID和ASK价格会以相应的格式显示在图表上,看效果:

本节知识总结

当使用数组时,在MQL4中需要注意以下几个方面:上述代码片段可加群私信威廉获取。

  • 一维数组:
    索引从0开始:MQL4中的一维数组索引从0开始,即第一个元素的索引为0,第二个元素的索引为1,以此类推。在访问和操作数组元素时,要使用正确的索引值。
    数组长度和容量:使用ArrayResize函数可以调整一维数组的长度和容量。在调整数组长度时,要确保在有效范围内,避免数组越界错误。
    初始化和赋值:在使用一维数组之前,通常需要对其进行初始化或赋值操作。可以使用循环或直接赋值语句来初始化一维数组。
    进阶用法:在MQL4中,一维数组是最常用的数组类型。如果需要表示更复杂的数据结构,可以使用一维数组的嵌套来模拟多维数组的效果。
  • 二维数组:
    定义和声明:二维数组是由多个一维数组组成的数组结构。在MQL4中,可以使用类似type array_name[row_size][column_size]的语法来定义和声明二维数组。
    访问和操作:二维数组的元素可以通过两个索引进行访问和操作,第一个索引表示行号,第二个索引表示列号。例如,array_name[row_index][column_index]。
    初始化和赋值:可以使用嵌套的循环语句来初始化和赋值二维数组。也可以单独赋值,最好是通过循环遍历每个元素,并为其指定初始值或赋予特定的值。
    数组长度和容量:二维数组的长度和容量由行数和列数决定。在定义二维数组时,要确保指定的行数和列数与实际需求相符。
  • 三维数组:
    MQL4中极少用到,了解概念即可
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容