ساختار در زبان MQL5 – بخش 2

مبانی زبان MQL5 - بخش 5
مبانی زبان MQL5 – بخش 5

در مقاله‌ی پیشین یعنی چهارمین مقاله آموزش زبان mql از سری مقالات مرتبط با برنامه نویسی در بازار‌ها‌ی مالی به شرح و بررسی «ساختار در زبان MQL5» پرداختیم. در پنجمین مقاله‌ی این سری نیز به تکمیل و جمع‌بندی این موضوع می‌پردازیم.

در صورت برقراری شرایط معاملات الگوریتمی در بازار هدف برای اعمال هر یک از این مفاهیم در استراتژی‌های معاملاتی می‌توانید از سفارش کد پایتون، سفارش کد mql و … برای کد کردن و بهینه‌یابی استراتژی‌های معاملاتی خود استفاده کنید. و در عین حال سوای امکان سفارش اکسپرت می‌توانید از سفارش اندیکاتور برای دریافت یک نمایش گرافیکی از محاسبات استراتژی خود بهره ببرید.

– – –

ساختار در زبان MQL5 - بخش 2
ساختار در زبان MQL5 – بخش 2

“pack” برای تراز کردن ساختار و فیلدهای کلاس #

در این بخش از آموزش زبان mql در ادامه‌ و تکمیل بخش قبل به بررسی ساختار در زبان MQL5 می‌پردازیم. در بررسی ساختار در زبان MQL5 یک از نکات حائز اهمیت توجه به بحث Alignment ساختار است.، ویژگی(attribute) pack، امکان تنظیم تراز فیلدهای ساختار یا کلاس را فراهم می‌کند.

pack([n])

که در آن n یکی از مقادیر زیر است: 1، 2، 4، 8 یا 16. و یا ممکن است وجود نداشته باشد.

   struct pack(sizeof(long)) MyStruct
     {
      // structure members are to be aligned to the 8-byte boundary
     };
or
   struct MyStruct pack(sizeof(long))
     {
      // structure members are to be aligned to the 8-byte boundary
     };
Setting new Alignment
Setting new Alignment

 

‘pack(1)’ به طور پیش فرض برای ساختارها اعمال می‌شود. به این معنی که اعضای ساختار یکی پس از دیگری در حافظه قرار می‌گیرند و اندازه ساختار برابر است با مجموع اندازه‌ی اعضای آن.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- simple structure with no alignment
   struct Simple_Structure
     {
      char              c; // sizeof(char)=1
      short             s; // sizeof(short)=2
      int               i; // sizeof(int)=4
      double            d; // sizeof(double)=8
     };
   //--- declare a simple structure instance   
   Simple_Structure s;  
//--- display the size of each structure member  
   Print("sizeof(s.c)=",sizeof(s.c));
   Print("sizeof(s.s)=",sizeof(s.s));
   Print("sizeof(s.i)=",sizeof(s.i));
   Print("sizeof(s.d)=",sizeof(s.d));
//--- make sure the size of POD structure is equal to the sum of its members' size
   Print("sizeof(simple_structure)=",sizeof(Simple_Structure));
/*
  Result:
   sizeof(s.c)=1
   sizeof(s.s)=2
   sizeof(s.i)=4
   sizeof(s.d)=8
   sizeof(Simple_Structure )=15 
*/    
  }

تراز کردن فیلدهای ساختار ممکن است در هنگام تبادل داده با کتابخانه‌های شخص ثالث (*.DLL) که چنین Alignment ای اعمال می‌شود، مورد نیاز باشد.

آشنایی با اضول کلی یک زبان برنا‌مه‌نویسی به ما کمک می‌کند که حتی در صورت نیاز به برون‌سپاری یک کد دید بهتری برای سفارش کد خود داشه باشیم. امکان سفارش کد mql و سفارش کد python از طریق سایت جهان بورس

ساختار در زبان MQL5 و نحوه عملکرد تراز(Alignment)

بیایید از چند مثال برای نشان دادن نحوه عملکرد تراز استفاده کنیم. ما ساختاری متشکل از چهار عضو بدون تراز را اعمال خواهیم کرد.

//--- simple structure with no alignment
   struct Simple_Structure pack() // no size is specified, alignment to the boundary of 1 byte is to be set
     {
      char              c; // sizeof(char)=1
      short             s; // sizeof(short)=2
      int               i; // sizeof(int)=4
      double            d; // sizeof(double)=8
     };
//--- declare a simple structure instance  
   Simple_Structure s;

فیلدهای ساختار باید یکی پس از دیگری با توجه به ترتیب تعریف و اندازه نوع در حافظه قرار گیرند. اندازه ساختار 15 است، در حالی که افست فیلدهای ساختار در آرایه ها تعریف نشده است.

تراز کردن یک ساختار ساده-00
تراز کردن یک ساختار ساده-00

حالا همان ساختار را با تراز 4 بایت تعریف کرده و کد را اجرا کنید.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- simple structure with the 4-byte alignment
   struct Simple_Structure pack(4)
     {
      char              c; // sizeof(char)=1
      short             s; // sizeof(short)=2
      int               i; // sizeof(int)=4
      double            d; // sizeof(double)=8
     };
   //--- declare a simple structure instance   
   Simple_Structure s;  
//--- display the size of each structure member  
   Print("sizeof(s.c)=",sizeof(s.c));
   Print("sizeof(s.s)=",sizeof(s.s));
   Print("sizeof(s.i)=",sizeof(s.i));
   Print("sizeof(s.d)=",sizeof(s.d));
//--- make sure the size of POD structure is now not equal to the sum of its members' size
   Print("sizeof(Simple_Structure)=",sizeof(Simple_Structure));
/*
  Result:
   sizeof(s.c)=1
   sizeof(s.s)=2
   sizeof(s.i)=4
   sizeof(s.d)=8
   sizeof(Simple_Structure)=16 // structure size has changed
*/    
  }

اندازه ساختار تغییر کرده است به طوری که تمام اعضای 4 بایت و بیشتر دارای یک افست از ابتدای ساختار مضرب 4 بایت هستند. اعضای کوچکتر باید با مرز اندازه خودشان تراز شوند (مثلاً 2 برای «short»). اینگونه به نظر می رسد (بایت اضافه شده به رنگ خاکستری نشان داده شده است).

تراز کردن یک ساختار ساده-01
تراز کردن یک ساختار ساده-01

در این حالت، 1 بایت بعد از عضو s.c اضافه می شود، به طوری که فیلد s.s (sizeof(short)==2) دارای مرز 2 بایت است (تراز برای نوع ‘short’).

افست ابتدای ساختار در آرایه نیز با مرز 4 بایت تراز می‌شود، یعنی آدرس‌های عناصر a[0]، a[1] و a[n] برای Simple_Structure باید مضرب 4 بایت باشند. []arr.

بیایید دو ساختار دیگر متشکل از انواع مشابه با تراز 4 بایتی اما ترتیب اعضای متفاوت را در نظر بگیریم. در ساختار اول، اعضا به ترتیب اندازه نوع صعودی قرار گرفته‌اند.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- simple structure aligned to the 4-byte boundary
   struct CharShortInt pack(4)
     {
      char              c; // sizeof(char)=1
      short             s; // sizeof(short)=2
      int               i; // sizeof(double)=4
     };
//--- declare a simple structure instance  
   CharShortInt ch_sh_in;
//--- display the size of each structure member  
   Print("sizeof(ch_sh_in.c)=",sizeof(ch_sh_in.c));
   Print("sizeof(ch_sh_in.s)=",sizeof(ch_sh_in.s));
   Print("sizeof(ch_sh_in.i)=",sizeof(ch_sh_in.i));
 
//--- make sure the size of POD structure is equal to the sum of its members' size
   Print("sizeof(CharShortInt)=",sizeof(CharShortInt));
/*
  Result:
   sizeof(ch_sh_in.c)=1
   sizeof(ch_sh_in.s)=2
   sizeof(ch_sh_in.i)=4
   sizeof(CharShortInt)=8
*/   
  }

همانطور که می‌بینیم، اندازه ساختار 8 است و از دو بلوک 4 بایتی تشکیل شده است. بلوک اول شامل فیلدهایی با انواع ‘char’ و ‘short’ است، در حالی که بلوک دوم حاوی فیلدهایی با نوع ‘int’ است.

تراز کردن یک ساختار ساده-02
تراز کردن یک ساختار ساده-02

حالا بیایید با حرکت دادن عضو نوع ‘short’ به انتها، ساختار اول را به ساختار دوم تبدیل کنیم، که فقط در ترتیب فیلد متفاوت است.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- simple structure aligned to the 4-byte boundary
   struct CharIntShort pack(4)
     {
      char              c; // sizeof(char)=1
      int               i; // sizeof(double)=4
      short             s; // sizeof(short)=2
     };
//--- declare a simple structure instance  
   CharIntShort ch_in_sh;
//--- display the size of each structure member  
   Print("sizeof(ch_in_sh.c)=",sizeof(ch_in_sh.c));
   Print("sizeof(ch_in_sh.i)=",sizeof(ch_in_sh.i));
   Print("sizeof(ch_in_sh.s)=",sizeof(ch_in_sh.s));
//--- make sure the size of POD structure is equal to the sum of its members' size
   Print("sizeof(CharIntShort)=",sizeof(CharIntShort));
/*
  Result:
   sizeof(ch_in_sh.c)=1
   sizeof(ch_in_sh.i)=4
   sizeof(ch_in_sh.s)=2
   sizeof(CharIntShort)=12
*/   
  }

اگرچه محتوای ساختار تغییر نکرده است، تغییر توالی اعضا باعث افزایش اندازه آن شده است.

تراز کردن یک ساختار ساده-03
تراز کردن یک ساختار ساده-03

تراز(Alignment) در وراثت

در هنگام وراثت باید تراز را در نظر گرفت. بیایید این را با استفاده از ساختار Parent ساده که دارای یک عضو از نوع “char” است نشان دهیم. اندازه ساختار(structure) بدون تراز 1 است.

struct Parent
  {
   char              c;    // sizeof(char)=1
  };

بیایید کلاس فرزند Children را ایجاد کنیم که دارای عضو نوع short’ (sizeof(short)=2)’ است.

struct Children pack(2) : Parent
  {
   short             s;   // sizeof(short)=2
  };

در نتیجه، هنگام تنظیم alignment روی 2 بایت، اندازه ساختار برابر با 4 است، اگرچه اندازه اعضای آن 3 است. در این مثال، 2 بایت باید به کلاس Parent اختصاص داده شود، به طوری که دسترسی به فیلد ‘short’ کلاس فرزند به 2 بایت تراز شده است.

دانش نحوه تخصیص حافظه برای اعضای ساختار ضروری است اگر یک برنامه MQL5 با داده های شخص ثالث با نوشتن/خواندن در سطح فایل ها یا جریان ها تعامل داشته باشد.

فهرست MQL5\Include\WinAPI کتابخانه استاندارد شامل توابع کار با توابع WinAPI است. این توابع ساختارها را با یک تراز مشخص برای مواردی که برای کار با WinAPI مورد نیاز است اعمال می کنند.

offsetof یک فرمان ویژه است که مستقیماً با ویژگی pack مرتبط است. این به ما امکان می دهد از ابتدای ساختار یک افست عضو را بدست آوریم.

//--- declare the Children type variable
   Children child;  
//--- detect offsets from the beginning of the structure
   Print("offsetof(Children,c)=",offsetof(Children,c));
   Print("offsetof(Children,s)=",offsetof(Children,s));  
/*
  Result:
   offsetof(Children,c)=0
   offsetof(Children,s)=2
*/

‘Specifier ‘final #

استفاده از مشخص کننده “final” در طی تعریف ساختار، ارث بردن بیشتر از این ساختار را ممنوع می کند. اگر ساختاری نیازی به تغییرات بیشتر نداشته باشد، یا تغییراتی به دلایل امنیتی مجاز نباشد، این ساختار را با اصلاح کننده “final” تعریف کنید. علاوه بر این، تمام اعضای ساختار نیز به طور ضمنی نهایی تلقی خواهند شد.

struct settings final
  {
  //--- Structure body
  };
 
struct trade_settings : public settings
  {
  //--- Structure body
  };
  • اگر همانطور که در مثال بالا نشان داده شده است سعی کنید از ساختاری با اصلاح کننده ‘final‘ ارث‌بری کنید، کامپایلر یک خطا را برمی‌گرداند :
cannot inherit from 'settings' as it has been declared as 'final'
see declaration of 'settings'

 

در مقالات بعدی آموزش ام کیو ال، مطالب آموزش ساختار در زبان MQL پی گرفته و سایر نکات مربوط به این بخش را شرح خواهیم داد.

همچنین می‌توانید از سسله مقالات آموزش Python سایت جهان بورس استفاده نمایید.

5 1 رای
امتیازدهی به مقاله
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
سبد خرید
هیچ محصولی در سبد خرید وجود ندارد!
خرید را ادامه دهید