データ型
プログラムはデータで動作します。データは目的によって異なった型で存在します。例えば、整数データは配列要素のアクセスに使用されます。価格データは倍精度浮動小数点に属します。これは MQL5 には価格データ型のための特別なデータ型がないという事実と関係があります。
データ処理速度は型によって違います。最も速く処理されるのは整数データです。倍精度データの処理には、特別なコプロセッサが使用されます。しかし、浮動小数点データは内部表現が複雑なために、整数より処理速度が遅くなります。
文字列データは動的なコンピュータメモリの割り当て / 再配分を必要とするために処理速度が最も遅くなります。
基本データ型は次の通りです。
- 整数型(char、short、int、long、uchar、ushort、uint、ulong)
- 論理型(bool)
- リテラル型(ushort)
- 文字列型(string)
- 浮動小数点型(double、float)
- カラー型(color)
- 日付時刻型(datetime)
- 列挙型(enum)
複合データ型は次の通りです。
OOPの視点からすると、複合データ型は抽象データ型と呼ばれています。
カラー及び日付時刻型は、外部のエキスパートアドバイザーまたはカスタム指標のプロパティで定義されたパラメータの可視化と入力を容易にするためにのみ意味をなします(インプットタブ)。カラー及び日付時刻型のデータは整数として表されます。整数型と浮動小数点型は、算術演算(数値)型と呼ばれています。
式には、明示的なキャストが指定されていない限り、暗黙の型キャストのみが利用されます。
Char、Short、Int 及び Long 型
char #
char 型は、メモリの 1 バイト(8 ビット)を占め、2 進数で 2^8=256 個の値を表現することが出来ます。char 型は、正と負の両方の値を含むことが出来ます。値の範囲は -128 から 127 です。
uchar #
uchar 整数型も char 型のようにメモリの 1 バイトを占めますが、uchar は char と違って正の値のみを含むことが出来ます。 最小値は 0 で最大値は 255 です。uchar 型の名称の最初の文字の u は unsigned の略です。
short #
short 型は 2 バイト(16 ビット)で、2 から 2 の 16 乗の 2^16 = 65,536 までの数を表すことが出来ます。short 型は符号付きなので、-32,768 から 32,767 の正と負の値を含むことが出来ます。
ushort #
符号なしの short 型は ushort で 2 バイトです。最小値は 0 で最大値は 65,535 です。
int #
int 型は 4 バイト(32 ビット)です。最小値は -2,147,483,648 で最大値は 2,147,483,647 です。
uint #
符号なしの整数型は uint です。この型は 4 バイトのメモリを取り、0 から4,294,967,295 の整数を表すことが出来ます。
long #
long 型は 8 バイト(64 ビット)です。最小値が -9,223,372,036,854,775,808 で最大値は 9,223,372,036,854,775,807 です。
ulong #
ulong 型も 8 バイトを占し、0 から18,446,744,073,709,551,615 の値を格納することが出来ます。
例:
char ch=12; short sh=-5000; int in=2445777; |
符号なしの整数型は負の値の格納には設計されていないので、格納の試みは予期しない結果につながることがあります。下記の簡単なスクリプトが無限ループにつながります。
//— 無限ループ void OnStart() { uchar u_ch; for(char ch=-128;ch<128;ch++) { u_ch=ch; Print(“ch = “,ch,” u_ch = “,u_ch); } } |
正しいバージョンは下記です。
//— 正しいバージョン void OnStart() { uchar u_ch; for(char ch=-128;ch<=127;ch++) { u_ch=ch; Print(“ch = “,ch,” u_ch = “,u_ch); if(ch==127) break; } } |
結果:
ch= -128 u_ch= 128 ch= -127 u_ch= 129 ch= -126 u_ch= 130 ch= -125 u_ch= 131 ch= -124 u_ch= 132 ch= -123 u_ch= 133 ch= -122 u_ch= 134 ch= -121 u_ch= 135 ch= -120 u_ch= 136 ch= -119 u_ch= 137 ch= -118 u_ch= 138 ch= -117 u_ch= 139 ch= -116 u_ch= 140 ch= -115 u_ch= 141 ch= -114 u_ch= 142 ch= -113 u_ch= 143 ch= -112 u_ch= 144 ch= -111 u_ch= 145 … |
例:
//— 負の値は unsigned 型に格納出来ない uchar u_ch=-120; ushort u_sh=-5000; uint u_in=-401280; |
16 進数は、数字の 0〜9 及び 10〜15 の値を記す a〜f または A〜F の文字で表され、0x または 0X で始まります。
例:
0x0A、0x12、0X12、0x2f、0xA3、0Xa3、0X7C7 |
整数型の変数の値は、B プレフィックスを使用して2 進数で設定出来ます。例えば、取引セッションの作業時間はint 型の変数にエンコードし、必要なアルゴリズムに従って、情報を使用することが出来ます。
//+——————————————————————+ //| スクリプトプログラムを開始する関数 | //+——————————————————————+ void OnStart() { //— 操作時間には 1、それ以外には 0 を設定する int AsianSession =B’111111111′; // 亜州セッション( 0:00〜9:00) int EuropeanSession=B’111111111000000000′; // 欧州セッション(9:00〜18:00) int AmericanSession =B’111111110000000000000011′; // 北米セッション(16:00〜02:00) //— セッションの数値を導き出す PrintFormat(“Asian session hours as value =%d”,AsianSession); PrintFormat(“European session hours as value is %d”,EuropeanSession); PrintFormat(“American session hours as value is %d”,AmericanSession); //— セッションの操作時間を文字列として表示する Print(“Asian session “,GetHoursForSession(AsianSession)); Print(“European session “,GetHoursForSession(EuropeanSession)); Print(“American session “,GetHoursForSession(AmericanSession)); //— } //+——————————————————————+ //| セッションの操作時間を文字列として返す | //+——————————————————————+ string GetHoursForSession(int session) { //— チェックには AND ビット演算子を使用して 1 ビットで左シフトする( <<=1) //— 最下位ビットからチェックを開始 int bit=1; string out=“working hours: “; //— 0〜23 の 24 ビットをすべてチェックする for(int i=0;i<24;i++) { //— ビットの状態を数で受け取る bool workinghour=(session&bit)==bit; //— 時間の数をメッセージに追加する if(workinghour )out=out+StringFormat(“%d “,i); //— 左に 1 ビットシフトし、次の値をチェックする bit<<=1; } //— 結果の文字列 return out; } |
文字定数
MQL5 では文字列の要素としての文字は、Unicode 文字セットのインデックスです。文字は整数にキャスト出来る16 進数値で、加算と減算のような整数演算 によって操作することが出来ます。
引用符内の文字及び「\x10」などの文字の 16 進数の ASCII コードは文字定数で、ushort 型です。例えば、「0」タイプのレコードは、文字のテーブルのインデックス 0 に対応し、数値 30 を持ちます。
例:
void OnStart() { //— 文字定数を定義する int symbol_0=’0′; int symbol_9=symbol_0+9; // 「9」シンボルを取得 //— 定数の出力値 printf(“In a decimal form: symbol_0 = %d, symbol_9 = %d”,symbol_0,symbol_9); printf(“In a hexadecimal form: symbol_0 = 0x%x, symbol_9 = 0x%x”,symbol_0,symbol_9); //— 文字列に定数を入れる string test=“”; StringSetCharacter(test,0,symbol_0); StringSetCharacter(test,1,symbol_9); //— 文字列で表示する Print(test); } |
バックスラッシュは、コンパイラがプログラムのソーステキスト内の定数文字列と文字定数を扱う際の制御文字です。単一引用符( ‘ )、二重引用符( ” )、バックスラッシュ( \ )及び制御文字などの記号は、以下の表に従って、バックスラッシュ(\)で始まるシンボルの組み合わせとして表すことが出来ます。
| | | |
改行(ラインフィード) | LF | ‘\n’ | 10 |
水平タブ | HT | ‘\t’ | 9 |
キャリッジリターン | CR | ‘\r’ | 13 |
バックスラッシュ | \ | ‘\\’ | 92 |
単一引用符 | ‘ | ‘\” | 39 |
二重引用符 | “ | ‘\”‘ | 34 |
16 進コード | hhhh | ‘\xhhhh’ | 1〜4 個の16 進文字 |
10 進コード | d | ‘\d’ | 0〜65,535 の 10 進数 |
バックスラッシュに上記以外の文字が続く場合、結果は未定義です。
例
void OnStart() { //— 文字定数を宣言する int a=’A’; int b=’$‘; int c=’©’; // コード 0xA9 int d=’\xAE’; // シンボル ® のコード //— 定数を出力する Print(a,b,c,d); //— 文字列に文字を追加する string test=“”; StringSetCharacter(test,0,a); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,b); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,c); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,d); Print(test); //— 文字を数として表す int a1=65; int b1=36; int c1=169; int d1=174; //— 文字列に文字を追加する StringSetCharacter(test,1,a1); Print(test); //— 文字列に文字を追加する StringSetCharacter(test,1,b1); Print(test); //— 文字列に文字を追加する StringSetCharacter(test,1,c1); Print(test); //— 文字列に文字を追加する StringSetCharacter(test,1,d1); Print(test); } |
上述されたように、文字定数(または変数)の値は、文字のテーブルのインデックスです。インデックスは整数なので、様々な方法で記述することが出来ます。
void OnStart() { //— int a=0xAE; // ® のコードは ‘\xAE’ リテラルに対応する int b=0x24; // $ のコードは ‘\x24’ リテラルに対応する int c=0xA9; // © のコードは ‘\xA9’ リテラルに対応する int d=0x263A; // ☺ のコードは ‘\x263A’ リテラルに対応する //— 値を表示する Print(a,b,c,d); //— 文字列に文字を追加する string test=“”; StringSetCharacter(test,0,a); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,b); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,c); Print(test); //— 文字列内の文字を置換する StringSetCharacter(test,0,d); Print(test); //— スートのコード int a1=0x2660; int b1=0x2661; int c1=0x2662; int d1=0x2663; //— スペードの文字を追加する StringSetCharacter(test,1,a1); Print(test); //— ハートの文字を追加する StringSetCharacter(test,2,b1); Print(test); //— ダイヤの文字を追加する StringSetCharacter(test,3,c1); Print(test); //— クラブの文字を追加する StringSetCharacter(test,4,d1); Print(test); //— 文字列内の文字リテラルの例 test=“Queen\x2660Ace\x2662”; printf(“%s”,test); } |
リテラル文字の内部表現は ushort 型です。文字定数は 0 から 6,5535 までの値を受け入れることが出来ます。
日付時刻型
日付時刻型は日付と時刻を 1970 年 1 月 1 日からの経過秒数として格納するために意図されています。この型はメモリの 8 バイトを有します。
日付と時刻の定数は、年、月、日(または日、月、年)、時間、分、秒の 6 つの数値を示す部分で構成され、文字列リテラルとして表すことが出来ます。定数は、一重引用符で囲まれ、D の文字で始まります。
値の範囲は 1970 年 1 月 1 日から 3000 年 12 月 31 日までです。日付(年、月、日)と時間(時間、分、秒)は片方づつ、または両方とも、省略することが出来ます。
リテラルの日付指定では、年、月及び日を指定することが望ましいです。そうでないとコンパイラが不完全なエントリについて警告を返します。
例:
datetime NY=D’2015.01.01 00:00′; // 2015 年の初めの時刻 datetime d1=D’1980.07.19 12:30:27′; // 年月日時分秒 datetime d2=D’19.07.1980 12:30:27′; // D’1980.07.19 12:30:27′ と同じ datetime d3=D’19.07.1980 12′; // D’1980.07.19 12:00:00′ と同じ datetime d4=D’01.01.2004′; // D’01.01.2004 00:00:00′ と同じ datetime compilation_date=__DATE__; // コンパイル日付 datetime compilation_date_time=__DATETIME__; // コンパイル日付と時刻 datetime compilation_time=__DATETIME__–__DATE__;// コンパイル時刻 //— コンパイラが警告を返す宣言の例 datetime warning1=D’12:30:27′; // D'[date of compilation] 12:30:27′ と同じ datetime warning2=D”; // __DATETIME__ と同じ |
カラー型
カラー型は、色に関する情報を格納するもので、メモリ内で 4 バイトを有します。最初のバイトは無視され、残りの 3 バイトが RGB 成分を含有します。
カラー定数は、リテラル、整数、または(名称のついた ウェブカラー のみ)名称によっての 3 つの方法で表現することが出来ます。
リテラル表現は、三原色(赤、緑、青)の割合を表す 3 つの部分から構成されます。定数は C で始まり、単一引用符で囲まれています。色成分の割合の範囲は 0〜255 です。
整数値は 16 進数または 10 進数として表現されます。16 進数は 0x00BBGGRR のような形をとります。RR は赤色、GG は緑色、BB は青色成分の割合です。10 進数の定数は直接 RGB を反映しません。それらは 16 進数表現の 10 進数での値を表します。
特定の色がいわゆる ウェブカラー セットを表します。
例:
//— リテラル C’128,128,128′ // 灰色 C’0x00,0x00,0xFF’ // 青色 // 色の名称 clrRed // 赤色 clrYellow // 黄色 clrBlack // 黒色 //— 整数表現 0xFFFFFF // 白色 16777215 // 白色 0x008000 // 緑色 32768 // 緑色 |
ブール型
ブール型は true または false の論理値の格納に意図されています。それぞれの数値表現は 1 と 0 です。
例:
bool a = true; bool b = false; bool c = 1; |
内部表現は 1 バイトサイズの整数です。論理式では、他の整数または実数型や式を使用することが出来ることに留意すべきです。コンパイラはエラーを生成しません。この場合、ゼロ値は false として解釈され、他の全ての値は true とされます。
例:
int i=5; double d=-2.5; if(i) Print(“i = “,i,” and is set to true”); else Print(“i = “,i,” and is set to false”); if(d) Print(“d = “,d,” and has the true value”); else Print(“d = “,d,” and has the false value”); i=0; if(i) Print(“i = “,i,” and has the true value”); else Print(“i = “,i,” and has the false value”); d=0.0; if(d) Print(“d = “,d,” and has the true value”); else Print(“d = “,d,” and has the false value”); //— 実行結果 // i= 5 and has the true value // d= -2.5 and has the true value // i= 0 and has the false value // d= 0 and has the false value |
列挙型
列挙 型のデータは特定の限定されたセットに属します。下記が列挙型の定義です。
値のリストは、コンマで区切られた名前付き定数の識別子のリストです。
例:
enum months // 名前付き定数の列挙 { January, February, March, April, May, June, July, August, September, October, November, December }; |
列挙の宣言後、新しい 4 バイトの整数値を持つデータ型が出現します。列挙は新しい名前付き定数を導入するため、新しいデータ型の宣言によって、コンパイラは渡されたパラメータの型を厳密に制御するようになります。上記の例では、January と名付けられた定数が 0、February が 1、December が 11 です。
規則:列挙型のメンバである名前付き定数に 特定の値が割り当てられていない場合は、新しい値が自動的に形成されることになります。それが列挙体の最初のメンバである場合、0 の値が割り当てられます。後続するメンバの全ての値は、前のメンバの値に 1 を足すことによって計算されます。
例:
enum intervals // 名前付き定数の列挙 { month=1, // 1 ヶ月の間隔 two_months, // 2 ヶ月 quarter, // 3ヶ月(四半期) halfyear=6, // 半年 year=12, // 1 年(12ヶ月) }; |
注意事項
- C++とは異なり、MQL5 での列挙型の内部表現のサイズは常に 4 バイトです。つまり、sizeof(月の名称)は 4 を返します。
- C++とは異なり、MQL5 では匿名の列挙は宣言することは出来ません。つまり、enum キーワードの後に常に一意の名称を指定する必要があります。
Originally posted 2019-07-27 09:39:23.