Выпущен MetaTrader 4 Client Terminal build 600 с обновленным языком MQL4 и Маркетом приложений - страница 102

 
Bobs:
Было бы неплохо сделать функцию которая позволит организовать всплывающие подсказки для extern в настройках входных параметров.

Зачем? Добавьте после внешней переменной комментарий в той же строке, и в окне параметров будет отображаться текст комментария, а не имя переменной.
 

Цитаты из справки:

1. "Переменная, объявленная внутри блока (часть кода, заключенная в фигурные скобки), принадлежит локальной области видимости. Такая переменная не видна (поэтому и недоступна) за пределами блока, в котором она объявлена. Самый распространенный случай локального объявления – переменная, объявленная внутри функции. ... Так как областью видимости локальной переменной является блок, в котором она объявлена, то существует возможность объявлять переменные с именем, совпадающим с именами переменных, объявленных в других блоках; а также объявленных на более верхних уровнях, вплоть до глобального."

Но если я объявляю на глобальном уровне int i; и в функции также объявляю int i; то компилятор выдает предупреждение: "declaration of 'i' hides global declaration at line 43 111.mq4 192 12"

2. "Переменная, объявленная локально, располагается на стеке, и время жизни такой переменной совпадает со временем жизни функции. "

Я полагаю, после обращения к функции, переменная объявленная в функции, умирает. При новом обращении, переменная инициализируется, и если значение не задано, то по умолчанию будет "0". (во всяком случае так было раньше). Приведенный ниже код использую для определения значений по каждому инструменту при переборе массива расположенного в функции start(). При объявлении double fProfit; происходит накопление значений (нарастающим итогом). А когда инициализировал double fProfit=0;, тогда все стало работать нормально.

Это ошибки в справке? в программе? или я что-то неправильно понимаю?

double sumClosedProfit(string Symb)
   {
   double fProfit;
   for(int m=0;m<OrdersHistoryTotal();m++)
      {
      if(!OrderSelect(m,SELECT_BY_POS,MODE_HISTORY)||OrderType()>1||OrderSymbol()!=Symb)continue;
      fProfit+=OrderProfit()+OrderSwap()+OrderCommission();
      }
   return(fProfit);
   }
 
Bobs:

Цитаты из справки:

1. "Переменная, объявленная внутри блока (часть кода, заключенная в фигурные скобки), принадлежит локальной области видимости. Такая переменная не видна (поэтому и недоступна) за пределами блока, в котором она объявлена. Самый распространенный случай локального объявления – переменная, объявленная внутри функции. ... Так как областью видимости локальной переменной является блок, в котором она объявлена, то существует возможность объявлять переменные с именем, совпадающим с именами переменных, объявленных в других блоках; а также объявленных на более верхних уровнях, вплоть до глобального."

Но если я объявляю на глобальном уровне int i; и в функции также объявляю int i; то компилятор выдает предупреждение: "declaration of 'i' hides global declaration at line 43 111.mq4 192 12"

2. "Переменная, объявленная локально, располагается на стеке, и время жизни такой переменной совпадает со временем жизни функции. "

Я полагаю, после обращения к функции, переменная объявленная в функции, умирает. При новом обращении, переменная инициализируется, и если значение не задано, то по умолчанию будет "0". (во всяком случае так было раньше). Приведенный ниже код использую для определения значений по каждому инструменту при переборе массива расположенного в функции start(). При объявлении double fProfit; происходит накопление значений (нарастающим итогом). А когда инициализировал double fProfit=0;, тогда все стало работать нормально.

Это ошибки в справке? в программе? или я что-то неправильно понимаю?


Пора бы уже привыкать к явной инициализации переменных. Если переменная не инициализирована, то ее значение не определено. Может быть что угодно. Если Вас это устраивает, то продолжайте задавать вопросы.
 
Bobs:

Цитаты из справки:

1. "Переменная, объявленная внутри блока (часть кода, заключенная в фигурные скобки), принадлежит локальной области видимости. Такая переменная не видна (поэтому и недоступна) за пределами блока, в котором она объявлена. Самый распространенный случай локального объявления – переменная, объявленная внутри функции. ... Так как областью видимости локальной переменной является блок, в котором она объявлена, то существует возможность объявлять переменные с именем, совпадающим с именами переменных, объявленных в других блоках; а также объявленных на более верхних уровнях, вплоть до глобального."

Но если я объявляю на глобальном уровне int i; и в функции также объявляю int i; то компилятор выдает предупреждение: "declaration of 'i' hides global declaration at line 43 111.mq4 192 12"

2. "Переменная, объявленная локально, располагается на стеке, и время жизни такой переменной совпадает со временем жизни функции. "

Я полагаю, после обращения к функции, переменная объявленная в функции, умирает. При новом обращении, переменная инициализируется, и если значение не задано, то по умолчанию будет "0". (во всяком случае так было раньше). Приведенный ниже код использую для определения значений по каждому инструменту при переборе массива расположенного в функции start(). При объявлении double fProfit; происходит накопление значений (нарастающим итогом). А когда инициализировал double fProfit=0;, тогда все стало работать нормально.

Это ошибки в справке? в программе? или я что-то неправильно понимаю?

По п1. На то и Глобальная переменная - область видимости вся программа. И не надо путать глобальную переменную с переменной объявленной внутри start() и внутри функций. И там и там можете использовать ее по количеству функций включая терминальные.

Мало того, можете внутри одной функции несколько раз инициализировать одну и ту же переменную например в циклах

for(int m=0;m<OrdersHistoryTotal();m++) {} 
for(int m=0;m<OrdersHistoryTotal();m++) {} 

По п2. Да, уж....

double pl,pl_sum=0;
...........  
pl=OrderProfit();        // так можно, в переменную pl передается конкретное значение 
pl_sum+=OrderProfit();   // переменная pl_sum в первом проходе =0 и к ней прибавляется конкретное значение, далее нарастающимитогом
//--------
double pl;
pl+=OrderProfit();       // так нельзя, в переменной случайное значение и к нему прибавляется  OrderProfit()

 
Bobs:

Но если я объявляю на глобальном уровне int i; и в функции также объявляю int i; то компилятор выдает предупреждение: "declaration of 'i' hides global declaration at line 43 111.mq4 192 12"

Всё правильно. Глобальные переменные ведь внутри функции тоже видны, и если вы внутри функции объявляете локальную переменную с тем же именем, то глобальная переменная внутри этой функции становится вам недоступна, ведь вы её переопределили. А если в этой функции глобальная переменная тоже используется (вернее, вы предполагаете, что используется, забыв о том, что вы её переопределили), то такое переопределение приведёт к ошибке. Компилятор в таких случаях обязательно должен выдать предупреждение, что он и делает.

Я полагаю, после обращения к функции, переменная объявленная в функции, умирает. При новом обращении, переменная инициализируется, и если значение не задано, то по умолчанию будет "0". (во всяком случае так было раньше).

Теперича - не то, что давеча. (с) Возьмите за правило никогда не писать:

double i;

а всегда писать:

double i = 0;

Это хорошая привычка, от многих неожиданностей убережёт. Объявление переменной - это просто выделение памяти под неё. А в выделенной памяти может содержаться любой хлам, оставшийся от предыдущего использования, она не обязательно пустая.

 
Spy:

Теперича - не то, что давеча. (с) Возьмите за правило никогда не писать:

double i;

а всегда писать:

double i = 0;

Это хорошая привычка, от многих неожиданностей убережёт. Объявление переменной - это просто выделение памяти под неё. А в выделенной памяти может содержаться любой хлам, оставшийся от предыдущего использования, она не обязательно пустая.

Но ведь раньше тол было нормально - обнулялись автоматом!... Зачем надо было ухудшать условия при якобы прогрессивном развитии... :(
 
Раньше - да, инициализировались сами, теперь - нет. Но это не ухудшение, это правильное нововведение. Инициализация переменной требует времени. Небольшого, несколько десятков тактов процессора, но если это происходит в каком-нибудь цикле, потери времени могут стать заметными. Программист сам должен решать, когда инициализировать переменные при объявлении, а когда нет. Все "взрослые" языки (С++ и т.д.) работают именно так.
 
Spy:

Зачем? Добавьте после внешней переменной комментарий в той же строке, и в окне параметров будет отображаться текст комментария, а не имя переменной.

Покажите пожалуйста как это выглядит, не встречал подобного тому, что Вы описали.

Кроме как типа: extern string S1 = "нужный комментарий". Но отдельная строка неудобна, т.к. ширина колонок "Переменная/Значение" и ширина окна настроек не регулируются, поэтому иногда видимой части недостаточно для отображения необходимого текста. Еще бывает необходимо давать комменты чуть ли не по каждой строке, и этот способ не добавляет удобочитаемости списка настроек.

 
Bobs:

Покажите пожалуйста как это выглядит, не встречал подобного тому, что Вы описали.

Кроме как типа: extern string S1 = "нужный комментарий". Но отдельная строка неудобна, т.к. ширина колонок "Переменная/Значение" и ширина окна настроек не регулируются, поэтому иногда видимой части недостаточно для отображения необходимого текста. Еще бывает необходимо давать комменты чуть ли не по каждой строке, и этот способ не добавляет удобочитаемости списка настроек.



input int kjh456jjr785 = 0; //Этот текст будет вместо kjh456jjr785

 
kazakov.v:


input int kjh456jjr785 = 0; //Этот текст будет вместо kjh456jjr785

Поставил как Вы написали, и ничего нету ...

input int kjh456jjr785 = 0; //Этот текст будет вместо kjh456jjr785

как задано "kjh456jjr785", так это и показывает. Что-то не так?

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