Любой эксперт оперирует с некоторыми данными - ценами, значениями индикаторов, объемами, количеством открытых позиций и пр. Те, места, где эти данные хранятся в эксперте, называются переменными. В качестве имен переменных можно использовать цифры (0-9), латинские прописные и строчные буквы (а - z и А - Z, следует помнить, что буквы 'a' и 'A' - совершенно разные символы), символ подчеркивания (_). Первый символ не может быть цифрой. Также имя переменной не должно совпадать с зарезервированным словом (т.е. словом, которое имеет особый смысл в языке MetaQuotes Language 4 - но об этом позже).
Желательно в качестве имени переменной использовать такое, из которого сразу становится понятным предназначение переменной. Например, переменная, содержащая количество открытых позиций, может иметь такое имя: OpenPositionsNumber.Можно создавать переменные разных типов:
- int - целое число (от -2147483648 до 2147483647);
- bool - логический тип (или ложь - false, или истина - true);
- datetime - дата и время (в формате D'YYYY.MM.DD HH:MM:SS');
- color - цвет (о формате я расскажу в следующих выпусках);
- double - вещественное число (-1.7 * 10-308 до 1.7 * 10308, точность - 15 значащих цифр);
- string - заключенная в двойные кавычки строка (например, "это строка").
тип имя; или тип имя = начальное_значение;Примеры объявлений переменных:
int Count; datetime InitialDate = D'2006.07.12 00:00'; string ip_address = "127.0.0.1";В дальнейшем для того, чтобы обратиться к значению переменной, надо будет просто указать ее имя:
i = 5 + Count;Иногда требуется сохранить не одно значение, а определенное количество взаимосвязанных значений. Например, значение индикатора на текущем баре, на предыдущем баре, ... , N-баров назад. Для таких целей существуют массивы. Массив - это индексированная совокупность однотипных данных.
Предположим, что у нас в эксперте есть такое описание массива Prices:
double Prices[50];Это означает, что массив-переменная Prices предоставляет доступ к 50 элементам типа double. Для доступа к i-му элементу надо указать Prices[i]. Нумерация элементов начинается с нуля и заканчивается 49-м элементов (в нашем случае).
Если Вы попробуете обратиться к элементу вне этого диапазона, то будет зафиксирована ошибка ERR_ARRAY_INDEX_OUT_OF_RANGE (4002), которую можно получить при помощи функции GetLastError().
В случае необходимости можно использовать не только одномерные массивы (у которых только один индекс), но и многомерные массивы.
Пример описания двухмерного массива, состоящего из шести массивов, каждый из которых состоит из 50 элементов:
int mas[6] [50];При описании массива можно в фигурных скобках задать начальные значения для каждого элемента:
int a[4][4] = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };Начальные значения элементов массивов могут быть только константами. Если Вы в фигурных скобках при инициализации массива указали меньшее количество начальных значений, чем размерность массива, то недостающие элементы инициализируются нулями.
Существует несколько видов переменных: локальные, статические, внешние, глобальные переменные и формальные параметры функций.
Постоянный адрес статьи: "Хранение данных в переменных"
Локальные и статические переменные.
Единственным нераскрытом моментом остались области видимости переменных. Дело в том, что переменные бывают нескольких типов:
- локальные переменные,
- статические переменные,
- глобальные переменные,
- внешние переменные,
- параметры функций.
Если переменная объявлена в пределах какой-нибудь функции, то она является локальной переменной и видна только в пределах этой функции. За пределами этой функции к этой переменной обращаться нельзя.
Инициализация (присвоение начального значения) локальной переменной происходит каждый раз при вызове функции. Присваиваемое начальное значение может быть как константой, так и выражением.
Пример объявления и инициализации локальной переменной:
int CalcFactorial(int n) { int i = 0; ... }Cтатические переменные
Статические переменные объявляются директивой static. Они инициализируются только один раз - при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.
Статические переменные объявляются в пределах описания функции и поэтому доступны для использования только в пределах той функции, в которой они объявлены.
Пример объявления статической переменной:
int GetOpenPositionsNumber() { static int Count = 0; ... }
Постоянный адрес статьи: "Локальные и статические переменные"
Внешние переменные.
Мы уже сталкивались с внешними переменными, когда описывали параметры эксперта MAPeriod и LotsNumber в коде нашего первого эксперта.
Внешние переменные описываются с помощью зарезервированного слова extern:
extern int MAPeriod=13; extern double LotsNumber=1.0;Внешние переменные не могут быть массивами.
Внешние переменные - это параметры эксперта, которые можно изменять.
"Прикрепите" эксперт к графику. Для этого нажмите правую кнопку мыши на названии эксперта в окне "Навигатор" и в появившемся контекстном меню выберите "Присоединить к графику". Появится окно свойств эксперта. Во вкладке "Входные параметры" Вы можете изменить значения внешних переменных, описанных в эксперте (см. рис. 1).
Если эксперт уже "прикреплен" к графику (в правом верхнем углу графика Вы видите улыбающуюся или грустную рожицу), то для изменения его параметров - значений внешних переменных - нажмите на рожице правую кнопку мыши и выберите в в появившемся контекстном меню пункт "Советники - Свойства ...". Более быстрый способ - использовать горячую клавишу F7. Появится окно с параметрами эксперта (см. рис. 1), в котором Вы сможете изменить значения внешних переменных.
Постоянный адрес статьи: "Внешние переменные"
Глобальные переменные.
Для человека, имеющего уже опыт написания экспертов, выражение "глобальные переменные" может внести небольшую путанницу. Дело в том, что на самом деле существует два вида "глобальных переменных":
- переменные, которые видны из любой функции ОДНОГО эксперта (т.е. являются глобальными в пределах этого эксперта); и
- переменные, которые являются общими для ВСЕХ экспертов.
Второй же тип глобальных переменных я рассмотрю в следующих выпусках, когда буду рассказывать о функциях, с помощью которых к таким переменным получают доступ, - GlobalVariable...().
Если Вы хотите, чтобы к значению переменной можно было бы обращаться из разных функций одного эксперта, сделайте ее глобальной переменной, т.е. определите ее на том же уровне, что и функции:
//---- глобальные переменные int CurrentState; int MyOrderTicket; //---- определения функций int init() { ... }Начальное значение глобальной переменной может быть только константой (если не задано никакого значения, то она инициализируется нулем). Это значение присваивается глобальной переменной только один раз, до выполнения функции init().
Постоянный адрес статьи: "Глобальные переменные"
Параметры функций.
В этом выпуске я продолжу рассмотрение функций и детально разберу, как в функцию можно передать значения и получить результат функции.
Формальные параметры функций
Как я уже говорил в выпуске "Создание собственных функций" функцию можно описать следующим образом:
тип имя ( формальные параметры ) { действия }Формальные параметры функции - это значения, которые передаются в функцию. Они указываются через через запятую в круглых скобках после имени функции. Для каждого параметра указывается тип (любой из стандартных: массивы, int, bool, datetime, double, color, string).
В функцию не может быть передано более 64 параметров.
Областью видимости формальных параметров функции является сама функция, т.е. доступ к их значениям может быть получен только в пределах этой функции.
В описании функции параметрам можно присваивать значения по умолчанию. При этом следует иметь в виду, что все параметры, следующие за первым параметром со значением по умолчанию, должны также иметь значения по умолчанию:
int GetSomethingUseful ( int a, int b = 0, bool f = true, double r = 5.9) { ... }В этом случае все или часть параметро по умолчанию можно упускать при вызове функции, а вместо них автоматически будут подставлены значения по умолчанию:
- Вызов GetSomethingUseful(3, 5, false) будет эквивалентен вызову GetSomethingUseful(3, 5, false, 5.9).
- Вызов GetSomethingUseful(3, 5) будет эквивалентен вызову GetSomethingUseful(3, 5, true, 5.9).
- Вызов GetSomethingUseful(3) будет эквивалентен вызову GetSomethingUseful(3, 0, true, 5.9).
Если мы импортируем функцию из другого модуля, то такие параметры таких функций не могут иметь значения по умолчанию.
Все, что я рассказал выше, касалось передачи параметров в функцию по значению. Чтобы все стало ясно, давайте рассмотрим небольшой пример:
void MyFirstFunction () { int a = 10; MySecondFunction ( a ); } void MySecondFunction ( int b ) { b = b + 1; Print ( b ); }В этом примере мы вызываем MySecondFunction, передавая в качестве параметра значение переменной "a" (в нашем случае - 10). Таким образом, при вызове MySecondFunction переменной "b" - формальному параметры функции - будет присвоено значение 10, которое будет следующей строчкой увеличено на единицу и выведено в лог. Однако при этом значение переменной a в MyFirstFunction не изменится и останется равным 10.
Существует и другой способ передачи параметров в функцию - по ссылке (используя после описания типа знак амперсенда - &). Рассмотрим новый пример:
void MyFirstFunction () { int a = 10; MySecondFunction ( a ); } void MySecondFunction ( int& b ) { b = b + 1; Print ( b ); }В этом примере мы вызываем MySecondFunction, передавая в качестве параметра ссылка на переменную "a". Таким образом, в функции MySecondFunction всегда, когда будет идти обращение к переменной b, реально будет идти обращение к переменной a. Т.е. следующей строчкой значение переменной "a" будет увеличено на единицу и выведено в лог. После завершения функции MySecondFunction переменная "а" будет равна 11.
В качестве параметров по ссылке можно передавать как переменные стандартных типов (но только в пределах одного модуля), так и массивы (как в пределах одного модуля, так и в другие модули).
Мы изучили константы и переменные. Однако для того, чтобы что-то сделать с данными или совершить операции по торговому счету, требуется нечто большее - нужно отдать команду. В языке программирования такие команды называются операторами. В следующем выпуске я расскажу о составном операторе.
Постоянный адрес статьи: "Параметры функций"
2 коммент.:
Привет! А сам че-нить пишешь? В плане советников иль тока выкладываешь советы ;)
Пока ни одного не написал!
Но темы выкладываю по мере изучения!
Планирую изучить и написать !!!
Особенно в этом помогает бесплатный курс http://fxlab.info/
Отправить комментарий