Возврат параиметров после обработки их в функции.

 
Подскажите, функция возвращает только одно значение или может возвращать несколько параметров?


У меня функция - выбор последнего закрытого ордера (пример брал здесь - 'Вопрос от новичка - как определить по SL или TP закрылся предыдущий ордер?'),
и, в зависимости, от того как этот ордер закрыт - рассчитываем объём открываемой позиции и стоп-лосс.

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

alexnau писал (а):
Подскажите, функция возвращает только одно значение или может возвращать несколько параметров?

Вариант №1 - Формальные параметры:

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

Пример:

void func(int& x, double& y, double& z[])
{
double calculated_tp;
...
for(int i=0; i<OrdersTotal(); i++)
{
if(i==ArraySize(z)) break;
if(OrderSelect(i)==false) break;
z[i]=OrderOpenPrice();
}
x=i;
y=calculated_tp;
}

Массивы также можно передавать по ссылке, все изменения отразятся в исходном массиве. В отличие от простых параметров массивы можно передавать по ссылке и в библиотечные функции.

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


Вариант №2 - Глобальные переменные:

Глобальные переменные определяются на том же уровне, что и функции, т. е. не локальны ни в каком блоке.

Пример:

int GlobalFlag=10;   // глобальная переменная

int start()
{
...
}

Область видимости глобальных переменных - вся программа, глобальные переменные доступны из всех функций, определенных в программе. Инициализируются нулем, если явно не задано другое начальное значение. Глобальная переменная может быть проинициализирована только соответствующей ее типу константой. Инициализация глобальных переменных производится однократно перед выполнением функции init().

Замечание: не следует путать переменные, объявленные на глобальном уровне, с глобальными переменными клиентского терминала, доступ к которым осуществляется при помощи функций GlobalVariable...().


Первый - предпочтительнее ;)

 
komposter:

Вариант №1 - Формальные параметры:

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

Пример:

void func(int& x, double& y, double& z[])
{
double calculated_tp;
...
for(int i=0; i<OrdersTotal(); i++)
{
if(i==ArraySize(z)) break;
if(OrderSelect(i)==false) break;
z[i]=OrderOpenPrice();
}
x=i;
y=calculated_tp;
}

Массивы также можно передавать по ссылке, все изменения отразятся в исходном массиве. В отличие от простых параметров массивы можно передавать по ссылке и в библиотечные функции.

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



При передаче массива по ссылке надо не забывать указывать размер массива, иначе выйдет
хрень.


int start()
  {
    double dim[12,4];
 
     dim[7,2]=6.0;
    
    funk_prim(dim);
 
     print("",dim[7,2]);
   
    }
 
 int funk_prim(double &dim[12,4])
    {
     dim[7,2]=11.0;
  
      return(0);
       }
 
Все равно пока не очень понятно.

В моем случае я должен передать в функцию две переменные по ссылке, без умолчательных параметров (double& Lots, double& SL)
double lastorders(string val, int dig, double& Lots, double& SL)
   {&
   int i, k, j=-1;
   double   ocp, otp, oop, osl;
   datetime oct;
 
   dig=MarketInfo(val,MODE_DIGITS);
   k=OrdersHistoryTotal();
   if (k!=0)
      {
      // Poisk poslednego zakritogo ordera
      for (i=0; i<k; i++) {
         if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
            if (OrderType()==OP_BUY) {
               if (oct<OrderCloseTime()) {
                  oct=OrderCloseTime();
                  j=i;
                  }
               }
            }
         }
      if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) 
         {
         oop=NormalizeDouble(OrderOpenPrice(), dig);
         osl=NormalizeDouble(OrderStopLoss(), dig);
         if (osl-oop>0) 
            {
            SL= ... ; Lots= ...;
            }
         }
      }   
   else
      {
      SL= ...; Lots= ...; 
      }   
   return (SL); 
   return (Lots);
   }
Примерно так?
А как организовать возврат значений переменных?
Думаю, что return ы неверны или не выполняются, хотя ошибки компилятор не выдает.
Пробовал в один return через запятую записать переменые чтобы две сразу вернуть выдает ошибку.
 
New:

При передаче массива по ссылке надо не забывать указывать размер массива, иначе выйдет
хрень.
О  массивах я думаю пока еще рано говорить, здесь хотя бы с простым разобраться. Но все равно спасибо за поддержку!
 

alexnau писал (а):
А как организовать возврат значений переменных?
Думаю, что return ы неверны или не выполняются, хотя ошибки компилятор не выдает.

Не надо return-ов - достаточно присвоить значения переменным:
            {
            SL= ... ; Lots= ...;
            }
         }
      }   
   else
      {
      SL= ...; Lots= ...; 
      }   
   }
И после вызова этой функции переменные SL и Lots будут содержать нужные значения ;)
 
komposter:

alexnau писал (а):
А как организовать возврат значений переменных?
Думаю, что return ы неверны или не выполняются, хотя ошибки компилятор не выдает.

Не надо return-ов - достаточно присвоить значения переменным:
,,,
И после вызова этой функции переменные SL и Lots будут содержать нужные значения ;)
Так все просто!
Я зачем-то зациклисля, на передаче и возврате значений переменных. Бывает.
Спасибо буду разбираться дальше!

Еще один вопрос: переменные передавать по ссылке, как я записал в коде ( double& Lots, double& SL ), или простым объявлением (без знака &)?
 
alexnau:

Еще один вопрос: переменные передавать по ссылке, как я записал в коде ( double& Lots, double& SL ), или простым объявлением (без знака &)?
Когда вы передаёте переменную по ссылке (со значком &), то фактически вы работаете с самой переменной, которую передаёте (а точнее с той областью памяти компьютера, в которую она записана). И все изменения её значения будут отображены и в функции, из которой вы вызываете функцию для работы с ней (то есть вы модифицируете область памяти компьютера где хранится переменная, которую вы передаёте по ссылке).
В том случае когда вы передаёте переменную стандартным способом (без знака &), то вы фактически работаете лишь с простой отдельной копией единственного переданного значения этой переменной (эта копия хранится в другой области памяти компьютера). То есть чтобы вы с этим значением ни делали изменения никак не повлияют на саму переменную, которую вы передавали в функцию.

Вам об этом уже komposter написал:
Существует возможность передавать параметры по ссылке. В этом случае модификация таких параметров отразится на соответствующих переменных в вызываемой функции, переданных по ссылке.
 
solandr:
alexnau:

Еще один вопрос: переменные передавать по ссылке, как я записал в коде ( double& Lots, double& SL ), или простым объявлением (без знака &)?
Когда вы передаёте переменную по ссылке (со значком &), то фактически вы работаете с самой переменной, которую передаёте (а точнее с той областью памяти компьютера, в которую она записана). И все изменения её значения будут отображены и в функции, из которой вы вызываете функцию для работы с ней (то есть вы модифицируете область памяти компьютера где хранится переменная, которую вы передаёте по ссылке).
В том случае когда вы передаёте переменную стандартным способом (без знака &), то вы фактически работаете лишь с простой отдельной копией единственного переданного значения этой переменной (эта копия хранится в другой области памяти компьютера). То есть чтобы вы с этим значением ни делали изменения никак не повлияют на саму переменную, которую вы передавали в функцию.

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


Да, я прочел все, что написал komposter появилось ощущение, что разобрался, но для верности переспросил.
После Вашего ответа, solandr, вопрос полностью прояснился.

Всем спасибо за помощь!