MQL4ドキュメントに関するディスカッション - ページ 18

 
まあ...私が思うに、それが正解なのです。

void SendMail() 文字列 subject, 文字列 some_text)
メール」タブの設定画面で指定したアドレスに、メールを送信します。
テストモードでは、この機能は動作しません。また、この関数はユーザーインジケータから呼び出すことはできません。
設定で送信を禁止している場合や、メールアドレスが指定されていない場合があります。エラー情報を取得するためには、GetLastError() 関数を呼び出す必要があります。
[...]

インジケーターでは、たしかに確認していないが...。:)

Z.U. トピックのタイトルに異議を唱え、以下のような名前に変更することを提案します。"MQL4ドキュメントの改善:不正確な点や不備の除去"。そんな感じです。
 
OrderSelect()関数の例で、そのような表現に出くわしました。
if(OrderSelect(12470, SELECT_BY_TICKET)==true) ...
その後、ドキュメントの他の場所でも見かけるようになりました。

単なるプログラミングスタイルなのか、解説をお願いします。
そうでないとすると、論理変数に比較演算を使う理由は何なのでしょうか?
なぜ、もっとシンプルな表現にしないのでしょうか?
if(OrderSelect(12470, SELECT_BY_TICKET)) ...
 
Yurixx:
なぜ、もっとシンプルな表現にしないのか。

前者の表現の方が直感的に理解しやすく、特に初心者の方でも議論の余地はないと思いますが、後者の表現の方がより広く使われていると思われます。
 
フォーマルパラメータとは 何か、参照渡しされるパラメータとの関係は?
 
値を計算するための関数では、入力としていくつかのパラメータを必要とすることがよくあります。例えば、OrderSend()関数を見てみると、このようなパラメータがたくさんあります。
  • シンボルマーク
  • 注文の種類
  • ポジション数量(ロット
  • 発見の代償
  • スリッページ(単位:pips
といった具合に。関数に渡されるパラメータには、呼び出された関数の動作中に何ら変化しないものと、関数の中で処理できるものの2種類があります。
例えば、次のような関数を考えてみましょう。

//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
SplitString() には 3 つのパラメータが渡されます。参照用の ArrayRes 配列 (先頭はアンパサンド &) と 2 つの形式パラメータ InputStrung (分割する文字列) および splitter (分割するための分割子) です。
この関数が実行されると、ArraRes 配列に複数の文字列が格納されます。MQL4では関数自体が複雑な型(配列など)を返すことができませんが、パラメータを参照渡しすることでこの制約を回避しています。

スクリプトの全文は以下の通りです。

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   
   SplitString(strResult,strInfo,"|");
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
あなたの環境で実行し、結果をご覧ください。
 
もうひとつ、残念な資料があります。

double OrderClosePrice() )
選択された注文の終値を返します。
注文は、OrderSelect() で事前に選択されている必要があります。
 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); if(ctm>0) Print("Open time for order 10 ", ctm).If(オーダーオープン時間)は、オーダーオープン時間です。
     ctm=OrderCloseTime(); if(ctm>0) Print("Close time for the order 10 ", ctm); } else Print("OrderSelect failed error code is",GetLastError());
・・・。
説明はOrderClosePrice関数について、例はOrderClosePrice関数についてです。
そのため、私たちがレビューするエキスパートアドバイザーの99%は、注文タイプの全く不要な分析を行っているのでしょう。
if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 0);
と書けばいいものを
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)
 
はい、先週取り上げたポイントです。そのようなものだと思います。

 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true)
    {
     datetime  ctm= OrderOpenTime();if(ctm>0)
     Print("Open time for the order 10 ", TimeToStr(ctm)); 
     double price=OrderClosePrice();
     if(price>0) Print("Close price for the order 10 ", DoubleToStr(price,MarketInfo(OrderSymbol(),MODE_DIGITS)));
    }
  else
    Print("OrderSelect failed error code is",GetLastError());
 
Quote
------
SplitString() には、3つのパラメータが渡されます:参照によるArrayRes配列(前にアンパサンド&があります)、2つの形式パラメータ InputStrung(解析される文字列)とsplitter(解析用の分割子です)です。
この関数が実行されると、ArraRes 配列に複数の文字列が格納されます。MQL4では関数自体が複雑な型(配列など)を返すことができませんが、パラメータを参照渡しすることでこの制約を回避しています。
------

それはわかりました。なぜ "フォーマル "と言ったのか理解できない。これらのパラメータは、純粋に形式的に楽しむために渡されるものなのでしょうか?C言語にはそんなものはない。

パラメータタイプの説明が「変数」にあり、「関数」にないのはなぜですか?
 
cout:
それはわかります。なぜ「形式的」と言うのか理解できません。 純粋に形式的に渡されるだけのパラメータなのでしょうか? C言語にはそのようなものはありません。


なぜなら、関数に渡される変数は、変数としてではなく、その値として形式的に渡されるからです。変数は操作する(値を変える)ことができるが、値に対する操作は意味がない。
この例の別バージョンを紹介します。

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   InputString="Входная строка";
   splitter="разделитель";
   Print("InputString=",InputString,"    splitter=",splitter);
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   string devider="|";
   SplitString(strResult,strInfo,devider);
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
   Print("strInfo=",strInfo,"    devider=",devider);   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
そこで、「値によるパラメータの受け渡し」と呼ぶことにします。
形式的には、何もその値に依存しないことを意味し、例えば、将来の使用のために予約されている :) 。しかし、値で渡されるパラメータは何かに依存しており、そうでなければ形式的と呼ばれるでしょう :) 。