Features of the mql5 language, subtleties and tricks - page 314

 
Andrei Iakovlev #:

#define  LOOP_Up(loop_body)   for(i = start; i <  22;    i++) loop_body
#define  LOOP_Down(loop_body) for(i = 21;    i >= start; i--) loop_body
void OnStart() {
   #define  LOOP_BODY { int res = MathRand(); printf("index=%d, result=%d", i, res); }
   if(Up) LOOP_Up(LOOP_BODY) else LOOP_Down(LOOP_BODY)
}
 
dcstoyanov #:
amrali #:

Thank you. Informative.
 
Andrei Iakovlev #:
Is there some way to choose which loop to use depending on the value of the bool variable?
// search elements from first to last in the required direction, depending on whether last is greater or less than first
for( int i=first, increment=(last>=first?1:-1) ;
      i!=last+increment ;
      i+=increment ) {
      ...
}
something like this :-)
 
Maxim Kuznetsov #:
something like this :-)

Interesting implementation, thanks.

amrali #:

That's the way to do it too:

#define  LOOP_BODY {...}
#define  LOOP_Up   for(i = start; i <  22;    i++) LOOP_BODY 
#define  LOOP_Down for(i = 21;    i >= start; i--) LOOP_BODY
if(Up) 	 LOOP_Up   else LOOP_Down
 
Andrei Iakovlev #:

Is there any way to choose which loop to use depending on the value of the bool variable? Inside the loops everything is the same, so I want to select the loop itself 1 time.

#define  LOOP_Up   for(i = 21;    i >= start; i--)
#define  LOOP_Down for(i = start; i <  22;    i++)
if(Up)  LOOP_Up   else LOOP_Down {

This option causes an error

The error occurs due to the fact that before compilation you substitute the names specified after #define with the names specified next in this directive.

That is why your variant unfolded in:

if(Up)
   for(i = 21;    i >= start; i--)
else
   for(i = start; i <  22;    i++) {
      //...
   }
There is no loop body after the first for(), but else immediately follows. This is what is reported in the error.
 
Yuriy Bykov #:
There is no loop body after the first for(), but else comes right after it. This is what is reported in the error.

I understand.

dcstoyanov #:
up ? i >= start : i < end

I didn't know that the conditional operator ? : in the 2nd and 3rd operands you can use expressions of relation operations, and I didn't realise to check it. I've been wondering for a long time how you can quickly change ">" to "<".

bool h = true; char g = 3, q = 4;
Print((h ? g > q : g < q) ? 5 : 6);
 
Andrei Iakovlev #:

I didn't know that in the conditional operator ? : in the 2nd and 3rd operands you can use expressions of relation operations, but I didn't realise to check it. I've been wondering for a long time how you can quickly change ">" to "<".

As far as I remember, in a ternary operator in the last two operands you can use any expression of any complexity, the result of which will be values of the same type. In this example, there are two expressions that turn into logical values. But "can" does not always mean "must". That is, sometimes it is better to write more lines of code that will be more understandable to a human than a cumbersome construct with ternary operators. But here everyone decides for himself how it is more convenient for him.
 

Friends, please remind me, somewhere I read about constructors and destructors. The order of creation and destruction, but I can't find it....

Should a parent's constructor be called in a descendant?

Should the parent's destructor be called in the descendant?


Please show some examples, especially about destructor.

 
Vladimir Pastushak #:

Friends, please remind me, somewhere I read about constructors and destructors. The order of creation and destruction, but I can't find it....

Should the parent's constructor be called in the descendant?

Should the parent's destructor be called in the descendant?


Please show some examples, especially about destructor.

In the descendant you must specify which of the parent's constructors is used.

class Child: public Parent { 
 // construct
 Child(double arg):Parent() {

 }
 // copy cons
 Child(const Child &orig):Parent(orig) {
 }
 ~Child() {
 }

}

You don't need to write or specify anything like that in destructors

 
Vladimir Pastushak #:

Does the parent's constructor need to be called in the descendant?

Should the parent's destructor be called in the descendant?

Write this line in all constructors/destructors.

::Print(__FUNCSIG__);

Then you will see the sequence of all calls in the log. And the picture will be formed.