新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 1413

 
Alexey Viktorov:

IntegerToString()和DoubleToString()函数只是将数字表示为一个字符串,传递给函数。在这个例子中

它是将r转换为字符串,字符串被 "添加"。但在这之前,r的值会发生变化。

我不太明白这个问题,但是如果你需要从数组中只选择偶数元素,那么循环应该这样构建


谢谢你的解释。

 
Alexey Viktorov:

IntegerToString()和DoubleToString()函数只是将数字表示为一个字符串,传递给函数。在这个例子中

它是将r转换为字符串,字符串被 "添加"。但在这之前,r的值会发生变化。



我无法理解 "添加 "字符串变量值的过程。在我的代码中,我看到了2种 "添加 "字符串的变体。

1.它们将当前迭代的字符串变量的值与上一次迭代的同一字符串变量的值相加。

2.在当前迭代中,两个项变量的值被加上,即IntegerToString(r)+ DoubleToString(LoY[r],4)。

在我看来,你指的是第一种变体。

但后来....上一次迭代时IntegerToString(r)的值="0"并在当前迭代中="1"。加法的结果应该是 "01"。

如果在当前迭代求和之前,IntegerToString(r) 的值从之前的值0变为当前的值1,我们仍然可以得到一个两位数的字符串表示的数字,即 "11"

如果我们用同样的算法将字符串变量DoubleToString(LoY[r],4) 的值相加,那么两个字符串相加的结果应该是1.61041.6105这样的值

但Print()将加法结果打印成其他数字(如应该是这样的)
,我不明白。
这是你的例子,字符串变量的值是如何相加的"......,如果你对字符串 相加DoubleToString(2.3, 1)+DoubleToString(3.6, 1),它将是2.33.6的一个字符串。"也就是说,在加法之前,每个变量的数字的字符串表示是2个字符,但在两个字符串变量相加之后,加法的结果是数字的字符串表示是4个字符。为什么你的代码中的加法不产生一个具有两倍字符数的数字?

 
Alexey Viktorov:


我不太明白这个问题,但是如果你想从一个数组中只选择偶数元素,那么这个循环应该这样构建


实际上,这就是我的意思:....下面是用BOX 2完成的原始代码

int P1=0;
double LoY[31];
void OnTick()
{
if (P1==0)
{
for(int r=0; r<31;r++)
{
LoY[r]=1.6104+(r*2)*0.0001;
Print("-------------------------------------LoY[r]--------------=",  LoY[r]);
P1=1;
}
}
//*************************************************************  Б Л О К    N 2
for(int x=0; x<31;x++)
{
if (Bid < LoY[x] )
{
LoY[x]=Bid;
ArraySort(LoY,WHOLE_ARRAY,0,MODE_ASCEND);
Print("---LoY[0]--",  X, "---LoY[1]--" ,  X,   "---LoY[2]--" ,  X,  "---LoY[3]--" ,  X,  "---LoY[4]--" ,  X, ................  "---LoY[30]--" ,  X );
}
}
}

在第二个区块中,数组元素 的值不再像第一个区块中那样有相同的delta值。 相邻元素之间的delta可以是不同的 因此,连接第一块的字符串的算法不适合第二块....,在我看来。

问题 在上述代码的第二块 中使用哪种MQL4语言结构 或函数,Print()函数在循环结束时,将 打印一次,数组元素的所有值都被填入,排列在一行中,即它将有以下形式

Print("---LoY[0]---" , X,"---LoY[1]---",X,"---LoY[2]--",X,"---LoY[3]--",X,"---LoY[4]--",X................"---LoY[30]---",X )。

不要苛责我,但我不确定我能理解文字的解释,因为在我看来,第二块比第一块要复杂得多....。
谢谢你的帮助。

 

在编程时,有很多常规工作,至少在开始时是这样。你要想清楚这个想法,然后编写代码,再进行调试。有时调试时间比其他一切都要长。

经常发生的情况是,最初的想法并不奏效。你开始从上到下依次寻找问题所在。

到处插入printf(),看看这是否是你所期望的。这样,你会更快地了解代码是如何工作的,以及你在哪里出了错误。否则,理解将需要很长的时间。


不关我的事,但要尽量写得漂亮。为自己选择一种风格并坚持下去。将托架按步骤放入托架中,使附件可见。如果你在语句之间使用空格,那么就到处使用,或者反过来说,不要到处使用。

for(int x=0; x<31;x++)

if (Bid < LoY[x] )

那么你就会更容易阅读自己的代码。

-----------------

在第二个街区。

在第二块中,小写的x和大写的x是不同的变量,代码不会按照你想要的方式工作。

最好是在循环外对数组进行排序。

在打印中,你使用X多次,你将打印相同的次数。

-----------------

关于代码。这个问题很难理解,所以我告诉你我所理解的内容。

如果你在一个循环中写Print,你会得到与该循环迭代次数一样多的打印结果。如果你需要打印一次输出,把Print放在循环之后。

在这种情况下,使用一个变量,你将把每次迭代的值写入其中,以收集信息。我们的变量是一个字符串,所以所有的数字都必须转换为字符串。

我们有一个字符串变量,因为Print函数接受一个字符串。

发生了什么事。

第一关。在循环之前的第一遍,我们有一个空变量:string str="";
接下来,我们给变量加上一个空值"--LoY["+IntegerToString(r)+"]--, "+DoubleToString(LoY[r],4)+",";
这里r是0,我们实际上添加一些字符串。

"--LoY["+

IntegerToString(0)+

"]--, "+

DoubleToString(LoY[0],4)+

", ";

第二遍。

对所有这些,我们加上第二个元素的信息

"--LoY["+IntegerToString(1)+"]--, "+DoubleToString(LoY[1],4)+", ";

这不会改变第一个元素的字符串。



你最好用语言解释目的,你需要什么,而不是你怎么做。否则,我们可能会讨论你的代码这么久,结果发现你的目标可以用其他方式解决。

 
ANDREY:

我无法理解 "添加 "字符串变量值的过程。我看到在我的代码中,有2个 "添加 "字符串的选项。

1.当前迭代的字符串变量的值与上一次迭代的同一字符串变量的值相加。

2.在当前的迭代中,两个项变量的值被加上,即IntegerToString(r)+ DoubleToString(LoY[r],4)。

在我看来,你指的是第一种变体。

但后来....上一次迭代时IntegerToString(r)的值="0"并在当前迭代中="1"。加法的结果应该是 "01"。

如果在加法之前的当前迭代中,IntegerToString(r) 的值从之前的0变为当前的1,我们仍然可以得到一个两位数的字符串表示的数字,即 "11"。

如果我们用同样的算法将字符串变量DoubleToString(LoY[r],4)的值相加,那么两个字符串相加的结果一定是1.61041.6105这样的值

但Print()由于某种原因将加法结果打印成其他数字(如应该是这样的)
,我不明白。
这是你的例子,添加字符串变量的值"......,如果你添加字符串DoubleToString(2.3, 1)+DoubleToString(3.6, 1),它将是2.33.6的一个字符串。"也就是说,在加法之前,每个变量的数字的字符串表示是2个字符,但在两个字符串变量相加之后,加法的结果是数字的字符串表示是4个字符。为什么你的代码中的加法不产生一个具有两倍字符数的数字?

事实上,这就像写任何文本一样。我们从一张白纸开始,或者我应该说是白线。然后我们写下第一个字,将第二个字附加到它上面,以此类推..........,当我们在文本中看到数字时,我们将它们写成一个行符号。也就是说,如果我们把2+5相加,就会得到7,如果我们只是写这些相同的数字,那么先写2,再写5......这样我们就得到两个数字25,挨着写。我不知道还能怎么解释。

实际上,如果你忽略了编译器的警告,在你的样本中把r值转换为字符串是没有必要的。在这里,你可以检查这两个选项

Print("Test 1 " + (string)1 + (string)2);
Print("Test 2 " + 1 + 2);
 
Aleksei Stepanenko:


谢谢你的帮助和建议。

 
Alexey Viktorov:

事实上,这与撰写任何文本完全一样。首先,我们有一张白纸,或者我应该说是一条白线。然后我们写下第一个字,再把第二个字加进去,以此类推..........,当我们在文中看到数字时,我们把它们写成行符号。也就是说,如果我们把2+5相加,就会得到7,如果我们只是写这些相同的数字,那么先写2,再写5......这样我们就得到两个数字25,挨着写。我不知道还能怎么解释。

实际上,如果你忽略了编译器的警告,在你的样本中把r值转换为字符串是没有必要的。在这里,你可以检查两个这样的变体

谢谢你所做的一切

 
ANDREY:

这实际上是我的意思:....以下是原始代码,由BOX 2补充。

在第二个区块中,数组元素 的值与第一个区块中的值不存在相同的delta。 相邻元素之间的delta可能是不同的 因此,连接第一块的字符串的算法不适合第二块....,在我看来。

问题 在上述代码的第二块 中使用哪种MQL4语言结构 或函数,Print()函数在循环结束后将 打印1次,所有数组元素的值都填在一行中,即它将有以下形式

Print("---LoY[0]---" , X,"---LoY[1]---",X,"---LoY[2]--",X,"---LoY[3]--",X,"---LoY[4]--",X................"---LoY[30]---",X )。

不要苛责我,但我不确定我能理解文字的解释,因为在我看来,第二块比第一块要复杂得多....。
谢谢你的帮助。

为什么要在循环的每次迭代中对数组进行排序?因为如果你替换了数组中第0个元素的值,并在排序后将其放到了数组的末尾,那么0将是第一个元素的值,而第一个元素将是第二个元素的值。因此,第一个数组项的值将被跳过,你将得到 "垃圾"。总而言之,你的代码是不合适的东西。

你需要的第一个区块是什么,你在其中填充阵列?马上用你需要的值填充数组,然后对其进行排序。是的,你必须再运行一个循环来填充字符串并打印它。我希望mql4有ArrayPrint()......但它只是实验性的,而且你实际上不需要打印数组的值。

 
Aleksei Stepanenko:

最好用语言解释你的目标,你需要什么,而不是你怎么做。否则,我们可以讨论你的代码这么久,结果发现你的目标可以用其他方式解决。

在研究mql4(和一点点mql5) 的时候,我正在写各种代码这包括使用数组的代码。经常需要在代码的某些地方检查数组项目。我已经学会了如何在一个循环中使用Print()进行操作。但在这种情况下,Print()是在每次迭代时打印的当有很多迭代时,对程序和阅读都是不方便的。你说得很对,Print()必须在Print()循环外删除,数组项的值只能打印一次。在你的话之前,我已经猜到了。

我很快学会了把Print()放在循环之外。现在我正试图学习如何让Print()在一行中打印出数组元素的所有值。

关于我的代码的第一块,有人向我解释了如何做到这一点。到目前为止,在一般情况下,我已经理解了这项技术。我将继续绞尽脑汁,了解这种方法的细节。
但是在我的代码的第二块中,在我看来,第一块中的方法不适合,因为与第一块不同,第二块中数组元素的值之间的delta是不同的。
如果我是对的,第一个区块的方法不适合第二个区块,如果你能告诉我如何做与第一个区块相同的事情,但参照第二个区块,我将非常感激。

我纠正了第二块。我把Print() ArraySort()放在循环之外。我已经从Print() 中删除了X变量,以免误导你。

int P1=0;
double LoY[31];
void OnTick()
{
if (P1==0)
{
for(int r=0; r<31;r++)
{
LoY[r]=1.6104+(r*2)*0.0001;
P1=1;
}
}
//*************************************************************  Б Л О К    N 2
for(int x=0; x<31;x++)
{
if (Bid < LoY[x] )
{
LoY[x]=Bid;
}
}
ArraySort(LoY,WHOLE_ARRAY,0,MODE_ASCEND);
Print("-LoY[0]-", (знач.эл.масс с инд.0), "---LoY[1]--" ,  (знач.эл.масс с инд.1),   "---LoY[2]--" ,  (знач.эл.масс с инд.2),  "---LoY[3]--" ,  (знач.эл.масс с инд.3),................  "---LoY[30]--" ,  (знач.эл.масс с инд.30) );
}
 
Print("-LoY[0]-", DoubleToString(LoY[0],4), "---LoY[1]--", DoubleToString(LoY[1],4), "---LoY[2]--" , DoubleToString(LoY[2],4), "---LoY[3]--" , DoubleToString(LoY[3],4),................  "---LoY[30]--" ,  DoubleToString(LoY[30],4) );

或做一个单独的数组打印函数。

void PrintArray(double &eArray)
   {
   string eStr="";
   int eSize=ArraySize(eArray);
   for(int i=0; i<eSize; i++)
      {
      eStr+=IntegerToString(i)+": "+DoubleToString(eArray[i],4)+", ";
      }
   Print(str);
   }

并从任何地方调用它

PrintArray(LoY);