Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 6. - страница 263

 
evillive:

int Mas[];


потом циклом заполнять, при необходимости юзать

ArrayResize(Mas,size);

ArrayInitialize(Mas,0);

"потом циклом заполнять"
Если не очень затруднит, маленький пример, можно?
 
Leo59:
"потом циклом заполнять"
Если не очень затруднит, маленький пример, можно?


 double MACDBuffer[]; int x=20;       // если известен размер буфера то              
 ArrayResize(MACDBuffer,x);         // то можно и просто  MACDBuffer[20], но  MACDBuffer[] нельзя.
 double min,max;
 int start(){
    for(int i=0; i<20; i++)
      MACDBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);
    min=ArrayMinimum(MACDBuffer);
    max=ArrayMaximum(MACDBuffer);
    Print(min,"____",max);
 }

Вам говорили что для заполнения динамического массива MACDBuffer[] необходимо сделать его статическим ArrayResize() (а то все время результатом присваивания будут нули),

и, для обеспечения стабильности в адекватности расчетов, далее массив лучше проинициализировать ArrayInitialize().

 
ALXIMIKS:


Вам говорили что для заполнения динамического массива MACDBuffer[] необходимо сделать его статическим ArrayResize() (а то все время результатом присваивания будут нули),

и, для обеспечения стабильности в адекватности расчетов, далее массив лучше проинициализировать ArrayInitialize().


Спасибо!
Суть в том, что есть работающий эксперт.
int CD=0; // порядковый номер закрытой сделки
double Balance=0; // результат закрытой сделки
double Mas[]; // массив значений результатов закрытых сделок


Как в int Start() заполнить Mas[] результатами закрытых сделок?

Может быть в init() и deinit() нужно что-то прописать? Инициализаци, или ещё чего-то?
Как правильно должен выглядеть код?

 
Leo59:
Суть в том, что есть работающий эксперт.
int CD=0; // порядковый номер закрытой сделки
double Balance=0; // результат закрытой сделки
double Mas[]; // массив значений результатов закрытых сделок


Как в int Start() заполнить Mas[] результатами закрытых сделок?

Может быть в init() и deinit() нужно что-то прописать? Инициализаци, или ещё чего-то?
Как правильно должен выглядеть код?

Понятие "правильно" у каждого свое.

Возможно вас устроит в инит Mas[10000] с инициализацией, а в старте при изменении значения CD присваивание Mas[СD]=Balance ?

а может вы захотите двухмерный массив в котором для каждой сделки будут хранится все необходимые данные (баланс, время, пункты, макс еквити, мин еквити ....)

 
ALXIMIKS:


Вам говорили что для заполнения динамического массива MACDBuffer[] необходимо сделать его статическим ArrayResize() (а то все время результатом присваивания будут нули),

и, для обеспечения стабильности в адекватности расчетов, далее массив лучше проинициализировать ArrayInitialize().

ArrayResize() изменяет размер массива. В mql4 все массивы по-умолчанию статические.
 
artmedia70:
ArrayResize() изменяет размер массива. В mql4 все массивы по-умолчанию статические.

Был не прав. Учебник подтверждает:

Если размер одномерного инициализируемого массива не указан, то он определяется компилятором, исходя из размера инициализирующей последовательности. Инициализация массива может быть выполнена также с помощью стандартной функции ArrayInitialize(). Все массивы являются статическими, т.е. имеют вид static, даже если при инициализации это явно не указано. Это значит, что все элементы массива сохраняют свои значения в промежутке между вызовами на исполнение функции, в которой объявлен массив.

Но почему тогда такой "статический" массив не присваивает значений ??? Результат нули как и ожидалось из за ArrayResize(buffer,0) от компилятора?

int start(){
   double buffer[];
   for(int i=10;i>=0;i--){
      buffer[i]=i;
      Print ("buffer[i]=",buffer[i]);
   }
}
 
ALXIMIKS:

Был не прав. Учебник подтверждает:

Но почему тогда такой "статический" массив не присваивает значений ??? Результат нули как и ожидалось из за ArrayResize(buffer,0) от компилятора?

Потому, что массив динамический. Его размер в первом измерении можно посмотреть функцией ArraySize() - для одномерного массива и ArrayRange() - для указанного измерения многомерного массива.

Статический - не означает "имеющий размер по-умолчанию ". Не сопоставляйте два понятия "статический" и "динамический". Это не антонимы. Здесь они из разных областей применения. Аналогии: Статический массив - "статическая переменная". Динамический массив - "размер, задаваемый и изменяемый программно".

int start(){
   double buffer[];
   for(int i=0;i<10;i++){
      ArrayResize(buffer,i+1);
      buffer[i]=i;
      Print ("Размер массива = "+(string)ArraySize(buffer)+", Значение в buffer["+(string)i+"] = ",buffer[i]);
   }
   return(0);
}
 
Leo59:

Спасибо!
Суть в том, что есть работающий эксперт.
int CD=0; // порядковый номер закрытой сделки
double Balance=0; // результат закрытой сделки
double Mas[]; // массив значений результатов закрытых сделок


Как в int Start() заполнить Mas[] результатами закрытых сделок?

Может быть в init() и deinit() нужно что-то прописать? Инициализаци, или ещё чего-то?
Как правильно должен выглядеть код?

Все результаты закрытых сделок можно посмотреть в истории счёта. Программно. А постоянно массив ими забивать - оно надо? Их же может быть очень много. Лучше ограничиться необходимой глубиной истории и заполнить массив, если совсем уж без него жить не можется.
 
Ребят,знает ли кто-нибудь как в RSI на андроиде добавить вспомогательные уровни?
 
ALXIMIKS:

Был не прав. Учебник подтверждает:

Но почему тогда такой "статический" массив не присваивает значений ??? Результат нули как и ожидалось из за ArrayResize(buffer,0) от компилятора?


Потому, что это не массив, если быть точным. Хотите более подробно - смотрите описания языка С. Ссылаюсь не него, поскольку разработчики с самого начала говорили, что по поводу всего, что не понятно или неполно изложено - смотри стандарт С.

А если "на пальцах": когда объявляете переменную double buffer[]; то выделяется память под одну переменную, которая в терминах С называется "указатель", имеет целочисленный тип и в которой хранится адрес ячейки памяти с которой начнется потом массив. Если проверить размерность переменной buffer средствами МКЛ, то получите значение 0. Это обозначает, что памяти под сам массив не отведено и, когда Вы пытаетесь присвоить какое-либо значение, то его просто некуда записать: в МКЛ нет адресной арифметики и с указателями работать нельзя. В С записать можно, но, при "невыделенной" памяти, это обычно приводит к краху системы. Когда применяете АрейРесайз(массив,N), (N>0), то этим самым выделяется память под массив (хотя бы один элемент) и появляется место для записи значений. Тогда при проверке размерность массива будет отлична от 0.

Понятие статического массива в терминах С имеет несколько значений:

1. статический массив (как и статическая переменная/тип) - это такие переменные/массивы размерность которых известна на этапе компиляции (предкомпиляции для МКЛ4) . Например, при описании double buff[10000]; компилятору сообщается размер переменной и он сразу может выделить память. В противовес этому понятию, есть понятие "динамического массива" - то есть, такой массив, размерность которого на этапе компиляции неизвестна и становится известна только на этапе исполнения программы, это все массивы переменной размерности. При обращении к таким массивам нужно предварительно память выделять. Память выделяется за пределами статической памяти программы.

В С/С++ если массив описан в блоке, то и видимость его ограничена блоком - хоть статический массив, хоть динамический. С динамическими массивами, описанными локально, связаны такие ошибки в программах, как "утечки памяти" - это когда указатель на память был уничтожен в силу выхода из области видимости, а память, выделенная под него, осталась занятой.

2 Понятие "статический" массив, как переменная описанная с модификатором static - такие переменные не уничтожаются при выходе из области видимости блока - они располагаются в отдельной области памяти - потому и значения в них сохраняются. Риск утечек памяти уменьшен. Массив, объявленный динамическим в смысле п.1 (то есть массив, размерность которого не известна на этапе компиляции), так же может быть статическим в смысле п.2, то есть декларирован с модификатором "статик".

При завершении программ необходимо память, выделенную динамически, освобождать для исключения утечек памяти. Я не знаю следят ли за этим разработчики МКЛ, но в своих программах всегда память освобождаю - привычка от С - АррейРесайз(массив,0);

В МКЛ все массивы статические в смысле п.2.

Теперь по поводу Вашего вопроса: "Почему статический массив double buffer[]; нельзя присвоить значения ?". Потому, что под него не отведена память (по сути это динамический массив с модификатором статик). Перед присвоением значений необходимо память выделить - то есть применить АррайРесайз с размерностью больше 0, к данному массиву. Для массивов нужно контролировать выход за пределы выделенной памяти (за пределы массива).

ЗЫ Надеюсь, понятно изложил. Постарался как можно проще.

Причина обращения: