Особенности языка mql5, тонкости и приёмы работы - страница 159

 
Yurixx:

Подскажите, pls.

В индикаторе порядок в сериях, напр. close[], устанавливается ArraySetAsSeries() один раз или как-то иначе ?

Это делается в OnCalculate() или можно в OnInit() ?

Столкнулся с непонятной ситуацией:

Порядок в  close[], установленный AS_SERIES при входе на первом тике, на следующем тике спонтанно меняется на обычный, т.е. !AS_SERIES.

Так и не нашел с чем это связано в коде.

в любой функции получающей scalar &arr[] нельзя быть стопроцентно уверенным в направлении индексации массива :-(

более того, если вы внутри поменяете "серийность", то это направление останется и по завершению вашей функции..это получится side-effect, нежданчик которого никто не ждёт

поэтому к сожалению, получая на входе в функцию массив, запоминайте его серийность, ставьте удобную вам и при любом выходе из функции ВСЕГДА возвращайте оригинал обратно

с OnCalculate это редкий случай, но на практике бывало что и его вызывают из прочего кода.

 
Maxim Kuznetsov:

более того, если вы внутри поменяете "серийность", то это направление останется и по завершению вашей функции..

На это собственно я и рассчитывал. Поэтому и поставил  ArraySetAsSeries(close,true)  в  OnCalculate()  в блоке, который исполняется только один раз при первом входе. И эта "серийность" действительно была установлена. Однако, к моему удивлению, на втором тике, и дальше, "серийность" была уже противоположная.

Maxim Kuznetsov:

с OnCalculate это редкий случай, но на практике бывало что и его вызывают из прочего кода.

У меня нет такой экзотики и, более того, я не меняю "серийность" таймсерий и буферных массивов внутри программы. Поэтому мне было бы достаточно установить ее один раз, в начале работы индикатора. Но, если нельзя быть уверенным в том, что "серийность" этих массивов сохраняется, то надо устанавливать ее в начале каждого цикла  OnCalculate().    Это кажется чем-то совершенно неестественным.

 
input string inStr = NULL; // Входная строка не может быть NULL, но об этом нигде не сообщается.

#define PRINT(A) Print(#A + " = " + (string)(A));

void OnStart()
{
  string Str = NULL;
  
  PRINT(inStr == NULL); // false
  PRINT(Str == NULL);   // true


  PRINT(inStr == ""); // true
  PRINT(Str == "");   // false
}
 Хорошо бы предупреждение генерировать на этапе компиляции.
 
fxsaber:
 Хорошо бы предупреждение генерировать на этапе компиляции.

Если ничего не изменилось с давних времён, NULL != "" На этом попадались уже многие.

 
Alexey Viktorov:

Если ничего не изменилось с давних времён, NULL != "" На этом попадались уже многие.

Речь о другом.

 
fxsaber:

Речь о другом.

Тогда объясните почему не может быть. Почему

input string inStr = "";

может быть, а

input string inStr = NULL;

быть не может.

 
Alexey Viktorov:

Тогда объясните почему не может быть.

Приведенный скрипт это показывает.

 
fxsaber:

Приведенный скрипт это показывает.

Если-бы показывал не возникали-бы вопросы. Вы-же всегда считаете, что все вокруг должны читать ваши мысли, или быть подготовленнее вас в программировании.

 
Alexey Viktorov:

Если-бы показывал не возникали-бы вопросы. Вы-же всегда считаете, что все вокруг должны читать ваши мысли, или быть подготовленнее вас в программировании.

Не понимаю причин такой реакции. Лаконичный код демонстрирует особенность на 100%.

 
fxsaber:

Не понимаю причин такой реакции. Лаконичный код демонстрирует особенность на 100%.

Нормальная реакция. Я не понимаю ваших кодов, просил объяснить, а в ответ...

NULL такая неопределённость, что с ней надо внимательно разбираться. Особенно в применении к строковым переменным.

Из документации

//--- если строка не инициализирована, то присвоим ей наше предопределенное значение 
if(some_string==NULL) some_string="empty";

Следовательно в данном примере NULL означает не то, что длина строки равна нулю, а то что переменная не инициализирована.

В вашем примере

input string inStr = NULL;

переменная инициализирована. Чем, не понятно для меня, да и нет желания разбираться.

Следовательно

PRINT(inStr == NULL); // false

говорит о том, что переменная инициализирована. Опять-же чем, большой вопрос. Почему вы посчитали что инициализировать значением NULL нельзя?

Видимо такая инициализация приводит к тому, что длина строки равна нулю, о чём и говорит эта проверка

PRINT(inStr == ""); // true
Причина обращения: