انواع داده‌هاي غيراستاندارد

 

در فصل اول با انواع داده‌هاي استاندارد پاسكال آشنا شديم. پاسكال اين قابليت را دارد كه هر برنامه‌نويس بتواند انواع داده‌هاي جديد (غيراستاندارد) را نيز معرفي نموده و در برنامه به كار گيرد.

تعريف انواع داده‌ها با استفاده از دستور Type  انجام مي‌شود. در فصل اول ملاحظه شد كه يكي از قسمتهاي اختياري برنامه‌، دستور Type  مي‌باشد. به اين مثال توجه نمائيد :

Type

 Float = Real ;

Var

 x,y : Float

در اينجا به كمك دستور Type ، داده‌اي به نام Float را تعريف نموديم كه البته از نوع Real مي‌باشد. سپس براي تعريف متغيرهاي x و y از نوع جديد يعني Float استفاده كرديم. شكل كلي دستور Type به اين صورت است :

Type

نوع داده = شناسه داده جديد  ;

نوع ترتيبي (Ordinal)

داده‌هاي ترتيبي، داده‌هايي هستند كه مي‌توان براي آنها ترتيب خواهد شد به طوري كه براي هر عنصر، بتوانيم عنصر بلافاصله بعدي يا قبلي را دقيقاً مشخص نمائيم. اعداد صحيح، كاراكترها و داده‌هاي منطقي، از نوع داده‌هاي ترتيبي هستند.

داده‌هاي اعشاري، ترتيبي نيستند زيرا به عنوان مثال بين 5/2 تا 3 ، اعداد حقيقي بيشماري وجود دارد و نمي‌توان تعداد آنها را مشخص كرد.

همچنين داده‌هاي كاراكتري (تك حرفي) نيز كه داراي كد اسكي (عدد صحيح) هستند، ترتيب مشخص دارند. مثلاً حرف B (با كد 66 ) ، پس از حرف A (با كد 65 ) قرار مي‌گيرد.

داده‌هاي منطقي(بولين) شامل يكي از دو مقدارFalse(متناظر با عدد0) و يا True(متناظر با عدد1) هستند و آنها هم از نوع ترتيبي محسوب مي‌گردند.

نوع زيرقلمرو (Subrange)

اين داده‌ها، نوعي داده ترتيبي هستند كه مقاديرشان محدود به يك ابتدا و يك انتها مي‌باشد كه توسط برنامه‌نويس مشخص مي‌گردد. به اين مثال توجه نمائيد :

Type

 Class = 1 .. 5 ;

 Codes = ‘D’ .. ‘H’ ;

Var

 x: Class ;

 m: Codes ;

در اينجا، Class ، نوعي داده صحيح است كه مقادير مجاز و قابل قبول آن در بازة ] 5 , 1[ قرار دارد. پس اگر مقدار خارج از محدوده را با دستور Readln يا دستور جايگزيني در متغير x قرار دهيم با مشكل مواجه خواهيم شد. همچنين Codes نوعي دادة كاراكتري است و متغير m فقط مي‌تواند شامل يكي از حروف G , F , E , D  و يا H  باشد. پس شكل كلي داده‌هاي زيرقلمرو بدين صورت است:

Type

انتهاي محدوده .. ابتداي محدوده = شناسه زيرقلمرو  ;

تعريف صفحه قبل باعث مي‌شود تا داده‌ زيرقلمرو به عنوان يك نوع داده‌ جديد تعريف شود و در قسمت‌هاي مختلف برنامه مي‌توان، متغيرهايي از آن نوع را تعريف كرد.

علاوه بر اين مي‌توان متغيرهاي زيرقلمرو را مي‌توان مستقيماً در قسمت Var تعريف نمود.

Var

 انتهاي محدوده .. ابتداي محدوده : متغير زيرقلمرو  ;

مثال : 

Type  

 num = 1 .. 5 ;

Var 

 g_num : num ;

 x : 1 .. 10 ;

x يك متغير زيرقلمرو است كه مقادير بين 1 تا 10  را مي‌تواند بپذيرد. به دليل اينكه x يك متغير زيرقلمرو است و نه يك نوع داده زيرقلمرو، نمي‌توان متغيرهايي را از نوع x تعريف كرد يعني عباراتي نظير x:y; صحيح نيستند.

نكته1 : در زمان تعريف دادة زيرقلمرو، مقدار ابتداي محدوده بايد كوچكتر يا مساوي انتهاي محدوده باشد.

نكته2 : داده‌هاي ترتيبي را مي‌توان به صورت زيرقلمرو نشان داد بنابراين تعريف داده‌هاي زيرقلمرو از روي مقادير اعشاري يا رشته‌اي از ساير داده‌هاي غيرترتيبي، صحيح نيست.

 

نوع داده شمارش پذير (Enumeration)

گاهي لازم است براي خواناتر شدن برنامه‌ها، به جاي استفاده مستقيم از برخي مقادير عددي، به ظاهر از شناسه‌هاي با معني استفاده نمائيم. داده‌هاي شمارش‌پذير در حقيقت شامل شناسه‌هايي هستند كه متناظر با يك عدد صحيح مثبت و يكتا مي‌باشند. به اين مثال توجه نمائيد :

Type

 City = (Tehran , Gorgan , Tabriz , Yazd) ;

Var

 x,y : City ;

Begin

 x := Tabriz ;

 .

 .

 .

در اينجا، نوع داده جديدي به نام City معرفي و مقادير قابل قبول در آن مشخص شده است. مترجم پاسكال به ترتيب اولين مقدار (Tehran) را متناظر با 0 قرار مي‌دهد و به همين ترتيب تا Yazd كه را متناظر با عدد 3 در نظر مي‌گيريم.

متغير x را از نوع City در نظر گرفته و مقدار آن را درون برنامه، برابر Tabriz قرار داده‌ايم. توجه نمائيد كه مقدار متغير x ، رشته كاراكتري Tabriz ، نيست بلكه مقدار عددي 2 مي‌باشد. پس نحوه معرفي داده‌هاي شمارش‌پذير به اين شكل است:

Type

شناسه نوع داده جديد =  ( شناسه 1 ,شناسه 2 , … )

نكته1 : در ليست شناسه‌هاي يك نوع دادة شمارشي جديد به كار بردن اعداد ، رشته‌ها و استفاده از كاراكترهاي و مجاز نيست.

مثال :  Type

 M = (1, ‘Ali’ , “red”) ;

در نوع داده m ، هيچ يك از مقادير ذكر شده، صحيح نيستند.

نكته2 : داده‌هاي شمارشي را نمي‌توان در دستورات ورودي / خروجي به كار برد.

مثال : 

Type

 m = (red , true , green , false) ;

Var

 s : m ;

Begin

 Read(s) ;

 Write(s) ;

End.

در مثال فوق، دستور Read و دستور Write به دليل به كار بردن متغير شمارشي در آنها، صحيح نيستند.

نكته3 : هر شناسه حداكثر در ليست مقادير يك داده شمارشي مي‌تواند قرار گيرد.

مثال :       Type

 Color = (red , green , blue) ;

 m = (red , true , false) ;

در تعريف داده شمارشي m ، شناسه Red  نمي‌تواند در ليست شناسه‌ها قرار گيرد زيرا اين شناسه قبلاً در ليست مقادير داده شمارشي color قرار گرفته است.

نكته4 : داده شمارشي يك داده ترتيبي است يعني مي‌توان داده زيرقلمرو از روي يك دادة شمارشي تعريف كرد و يا داده‌هاي شمارشي را به عنوان انديس آرايه استفاده نمود و ساير اعمال مجاز روي داده‌هاي ترتيبي بر روي داده‌هاي شمارشي نيز قابل اعمال است.

مثال :

Type

 Color = (red , green , blue) ;

Var

 s : Color ;

 m : red .. blue ;

m يك متغير زيرقلمرو است كه مقادير موجود در بازة red .. blue را مي‌تواند بپذيرد.

نكته5 : داده‌هاي شمارشي را نمي‌توان در عبارات محاسباتي به كار برد ولي استفاده از اين داده‌ها در عبارات مقايسه‌اي مجاز است.

مثال :        Type

 Color = (red ,green ,blue) ;

Var

 m,s : Color ;

Begin

 s := s + 1 ;

 .

 .

 .

IF m < s Then

 .

 .

 .

End.

عبارت محاسباتي s := s + 1  صحيح نيست ولي عبارت مقايسه‌اي ذكر شده صحيح مي‌باشد. در عبارات مقايسه‌اي، مقايسه ميان اعداد متناظر با هر مقدار دادة شمارشي، صورت مي‌گيرد.

نكته6 :  دادة شمارشي يك بايت حافظه اشغال مي‌كند؛ بنابراين در ليست شناسه هاي  يك دادة شمارشي حداكثر 256 شناسه را مي‌توان تعريف كرد.

 

توابع مرتبط با داده‌هاي ترتيبي، زيرقلمرو و شمارش‌پذير

پاسكال، داراي برخي توابع پيش‌ساخته براي داده‌هاي ترتيبي مي‌باشد كه بدين شرح هستند :

 

نام تابع

پارامتر

نتيجه عمل

Pred

(متغير يا مقدار ترتيبي)

عنصر قبلي از همان نوع داده

Ord

(متغير يا مقدار ترتيبي)

شمارش ترتيب آن داده (عدد)

Succ

(متغير يا مقدار ترتيبي)

عنصر بعدي از همان نوع داده

براي درك بهتر از توابع شمارشي به مثال زير توجه نمائيد :

Type

 City = (Tehran , Gorgan , Tabriz , Yazd) ;

Var

 x,y: City ;

 ch: char ;

 k: integer ;

Begin

 x := Gorgan ;

 Writeln(Ord(x)) ; {عدد يك چاپ مي‌شود.}

 y := Pred(x) ; {y = Tehran}

 ch := ‘E’ ;

 k := Ord(ch) ; {k = 69  را داريم. ‘E’ چون كد اسكي }

 Writeln (k) ; { عدد 69 چاپ مي‌شود}

 Writeln (succ(ch)) ; {چاپ مي‌شود. ‘F’ حرف}

End.

مثال فوق نياز به توضيح چنداني ندارد و توضيحات به كار رفته در آن گويا مي‌باشد. حال كه بحث داده‌هاي كاراكتري نيز مطرح گرديد، بهتر است دو تابع ديگر را نيز معرفي نمائيم. كه عبارتند از :

نام تابع

پارامتر

نتيجه عمل

Chr

(عدد صحيح بين 0 تا 255 )

كاراكتر معادل در جدول اسكي

Upcase

(كاراكتر يا متغير كاراكتري)

همان كاراكتر (با حروف برزرگ الفبايي)

مثال:

var

  x,y,z:char;

begin

 x := ‘a’ ;

 Writeln(Upcase(x)) ; {چاپ مي‌شود. ‘A’ حرف}

 Y := Chr(67) ; {y=’c’}

 Z := #67 ; {z=’c’}

 Writeln(y) ; {چاپ مي‌شود. ‘C’ حرف}

 Writeln(z) ; {چاپ مي‌شود. ‘C’ حرف}

End.

نكته :  در توربوپاسكال، عملگر # معادل تابع Chr عمل مي‌كند و بيانگر يك مقدار ثابت كاراكتري است مثلاً #65 معادل حروف ‘A’ مي‌باشد. همچنين از نظر مقادير داده‌اي، حروف A و a با هم تفاوت دارند. زيرا كد اسكي در اولي 65 بوده و براي دومي 97 مي‌باشد. پس ‘a’ از ‘A’ بزرگتر است! زيرا در ترتيب قرار گرفتن، بعد از آن مي‌باشد.

 

ثابت (Constant)

در برنامه مي‌توان از مقادير ثابت به طور مستقيم استفاده كرد و يا شناسه‌هاي ثابتي را تعريف نمود و با آن شناسه‌ها كار كرد. در پاسكال دو نوع ثابت وجود دارد : 1ـ ثابت حقيقي (بدون نوع) ، 2ـ ثابت مجازي (نوع دار).

ثابت حقيقي : ثابتي است كه مقدار آن را در طول برنامه نمي‌توان تغيير داد بنابراين استفاده از اين نوع ثابتها در دستورات ورودي يا به عنوان متغير حلقه For و يا هر دستورالعملي كه منجر به تغيير مقدار ثابت‌ مي‌شود، صحيح نيست.

شكل كلي تعريف اين ثابتها به صورت زير است:

Const

 مقدار اوليه 1= شناسه ثابت 1 ;

  .

  .

  .

مثال :

Const

 P = 3.14 ;

 S = ‘Ali’ ;

P به عنوان يك ثابت اعشاري و S به عنوان يك ثابت رشته‌اي در نظر گرفته مي‌شود.

ثابت مجازي :  مي‌توان گفت ثابت مجازي، متغيري است كه در زمان تعريف مقدار اوليه مي گيرد . يعني برخلاف ثابت حقيقي مقدار ثابتهاي مجازي را مي توان در طول برنامه تغيير داد. شكل كلي تعريف اين ثابت ها به صورت زير است:

Const

  مقدار اوليه 1 = نوع 1 : شناسه 1 ;

  .

   .

  .

مثال :

Const

 m: Real = 12.3 ;

 a: Byte = 48 ;

 s: String = ‘test’ ;

در قسمت نوع ، هر نوع مجاز در پاسكال مي تواند قرار گيرد. از جمله نوع هايي كه مي تواند در اين قسمت قرار گيرد نوع آرايه است. كه در اين صورت به تعداد عناصر آرايه بايدمقدار اوليه ذكر شود:

مثال‌ :

   Const

  m:Array[1..5] of char = (‘A’,’B’,’C’,’D’,’E’);

 همان طوري كه ملاحظه مي شود ، آرايهm داراي 5  عضو مي باشد و در ليست مقادير اوليه نيز5 مقدار اوليه ذكر شده است.

درآرايهm ،‘A’ = [1] m  , [5]=’E’  m  مي باشد.

نكته1: در تعريف يك ثابت نمي توان ازهمان ثابت استفاده كرد:

Const

 m=m;

 s:Byte=s;

اين تعريف ها صحيح نيستند.

نكته2: از ثابت هاي حقيقي مي توان براي تعين حدود آرايه استفاده كرد ولي از ثابت هاي مجازي نمي- توان چنين استفاده اي را نمود:

Const

 m=12;

 k:Byte=13;

Var

 a:Array[1..m] of Byte;

  b:Array[1..k] of Char;

تعريف آرايه a صحيح است ولي تعريف آرايهb صحيح نيست.

نكته3: ثابت نوعدار را مي توان از ركورد نيز تعريف كرد:

مثال:      

Type

 Trec=Record

 i:Integer;

  c:Char;

 End;

 Const

 Rec:trec=(i:14; c:’B’);

 

با اين نحوه مقدار دهي، به فيلدi  عدد 14 و به فيلد c  ، كراكترB  نسبت داده مي شود.

براي مقدار دهي اوليه به ركورد(در قسمت ثابتهاي مجازي) به ترتيب اسم هر فيلد و مقدار آن به صورت زير بيان مي شود:

مثال:

Const

 rec:trec=(i:14);  {مقداري نامعلوم دارد.  c عدد 14 نسبت داده مي‌شود و  i به فيلد }

  rec1:trec=(c:’A’); {مقدار دهي مي‌شود.  i ،ابتدا بايد فيلد c اين مقدار دهي خطا دارد، زيرا براي مقدار دهي به فيلد}

 

ثابتهاي استاندارد :  در پاسكال ثابتهاي استاندارد و از پيش تعريف شده‌اي وجود دارند كه از آن جمله مي‌توان دو ثابت Maxint و Maxlongint را نام برد.

Const

 Maxint = 32767 ;

 Maxlongint = 2147483647 ;

 

كه Maxint  مبين بزرگترين عدد صحيح و Maxlongint مبين بزرگترين عدد Longint است.