Logo

ماركو كانتو:
أساسي باسكال

الفصل 4
أنواع البيانات المحددة بالمستعمل

اضافة إلى مفهوم النوع، فإن أحد أعظم الأفكار التي قدمتها لغة باسكال هي القدرة على تحديد أنواع بيانات جديدة في البرنامج. يستطيع المبرمجون تحديد أنواع بيانات خاصة بهم بواسطة مشيّدات النوع type constructors، مثل أنواع المدى الفرعي subrange، نوع مصفوفة array، نوع تسجيلة record، نوع سردي enumerated، نوع مؤشّر pointer ، ونوع فئة set. أكثر أنواع البيانات المحددة بالمستعمل أهمية هي الطبقة أو الفصيلة class، و التي هي جزء من اضافات الاتجاه الكائني object-oriented في باسكال، و الغير مشمولة في هذا الكتاب.

إذا كنت تعتقد بأن مشيّدات النوع أمر عام في لغات البرمجة، فأنت على صواب، لكن باسكال كانت أول لغة قدّمت هذه الفكرة بطريقة منظمة و دقيقة جدا.

الأنواع المسمّاة وغير المسمّاة

هذه الأنواع يمكن إعطاؤها اسما للرجوع اليه لاحقا أو أن تطبّق على المتغيرات مباشرة. عندما تعطي اسما لنوع، يجب أن توفّر مساحة خاصة في التوليف، مثل الآتي:

type
  // subrange definition
  Uppercase = 'A'..'Z';

  // array definition
  Temperatures = array [1..24] of Integer;

  // record definition
  Date = record
    Month: Byte;
    Day: Byte;
    Year: Integer;
  end;

  // enumerated type definition
  Colors = (Red, Yellow, Green, Cyan, Blue, Violet);

  // set definition
  Letters = set of Char;

بناءات تحديد نوع مشابهة يمكن استخدامها مباشرة لتعريف متغير من غير تسمية صريحة للنوع، كما هو في التوليف التالي:

var
  DecemberTemperature: array [1..31] of Byte;
  ColorCode: array [Red..Violet] of Word;
  Palette: set of Colors;

ملاحظة: عموما يجب عليك أن تتجنّب استخدام الأنواع غير المسمّاة unnamed مثل التوليف السابق، و ذلك لأنك لن تستطيع أن تمرّرها كمحدّدات الى الإجرائيات، أو أن تقوم بتصريح متغيّرات أخرى من نفس النوع. إن قواعد توافقية النوع في باسكال تعتمد في الواقع على أسماء الأنواع، و ليس على ما تم تحديده فعليا من أنواع. إن متغيّرين من نوعين متطابقين لايعتبران متوافقين، إلا إذا كانا نوعاهما يحملان نفس الإسم حرفيا، أما الأنواع غير المسمّاة فإنها تُعطى أسماء داخلية من قبل المجمّع compiler. حاول أن تتعوّد على عمليات تحديد نوع البيانات في كل مرّة تحتاج فيها إلى متغير مركب و غير بسيط، و لن تأسف على الوقت الذي صرفته لذلك.

و لكن ماذا تعني تحديدات النوع هذه؟ سأقدم بعض الشروح لأؤلئك الذين هم غير متعوّدين على بناءات باسكال للنوع. سوف أحاول أيضا شرح الفروقات لنفس البناءات في لغات البرمجة الأخرى. لذلك قد يهمّك قراءة الأقسام التالية حتى لو كنت معتادا على شكل تحديدات النوع المضروبة كمثال أعلاه. أخيرا، سأعرض بعض أمثلة دلفي و أقدم بعض الأدوات التي ستسمح لك بالوصول إلى معلومات عن النوع بطريقة حية.

أنواع مدى فرعي

نوع المدى الفرعي subrange يحدد مدىً من القيم داخل نوع مدى آخر (من هنا اسم مدى فرعي). يمكنك تحديد مدى فرعي لنوع صحيح، من 1 إلى 10 او من 100 إلى 1000، أو تستطيع ان تحدد مدى فرعي من نوع حرف Char، كما في:

type
  Ten = 1..10;
  OverHundred = 100..1000;
  Uppercase = 'A'..'Z';

عند تحديد المدى الفرعي، لا تحتاج إلى تحديد اسم النوع الأساسي. أنت تحتاج فقط إلى تقديم ثابتين من نفس ذلك النوع. النوع الأصلي يجب أن يكون من نوع تراتبي ordinal، و النوع الناتج سوف يكون نوعا تراتبيا آخر.

عندما تكون قد حدّدت مدى فرعيا، يمكنك رسميا أن تخصص قيمة داخل ذلك المدى. هذا التوليف يعتبر صحيحا:

var
  UppLetter: UpperCase;
begin
  UppLetter := 'F';

ولكن هذا ليس كذلك:

var
  UppLetter: UpperCase;
begin
  UppLetter := 'e'; // compile-time error

كتابة التوليف السابق ينتج عنه خطأ في زمن التجميع compile-time error بالرسالة التالية:، "Constant expression violates subrange bounds." ("تعبير لثابت يتخطّى حدود المدى."). أما إذا كتبت بدلا من ذلك التوليف التالي:

var
  UppLetter: Uppercase;
  Letter: Char;
begin
  Letter :='e';
  UppLetter := Letter;

فإن دلفي ستقوم بتجميعه. و لكن في زمن التشغيل run-time ، و إذا قمت بتمكين خيار المجمّع لتفحّص المدى Range Checking فستحصل على رسالة خطأ Range check error. (تمكين الخيار من خلال مربع Project Options ثم صفحة Compiler).

ملاحظة: أقترح بأن تقوم بتمكين خيار المجمّع هذا عندما تقوم بتطوير برنامج ما، حتى يكون هذا البرنامج أكثر متانة و أكثر سهولة عند تنقية أخطائه، ففي هذه الحالة و عند وجود أخطاء سوف تحصل على تنبيهات صريحة و واضحة و ليس مجرّد سلوك لايمكن التكهّن به. عند البناء النهائي للبرنامج تستطيع اخماد هذا الخيار، لجعله أسرع قليلا. عموما، الفرق عمليا صغير جدا، و لهذا السبب أنصح بأن تقوم بتمكين كل خيار ات التفحّص في زمن التشغيل، حتى عند شحن البرنامج. نفس الأمر ينطبق على باقي خيارات الفحص في زمن التشغيل، مثل فحص احتمالات الفوران overflow و التكدّس stack.

الأنواع السردية

تشكّل الأنواع السردية enumerated نوعا تراتبيا آخرا محددة بالمستعمل. فبدلا من الإشارة إلى مدى من نوع موجود، فإنك في السردية تقوم بعرض القيم المحتملة للنوع. بمعنى آخر، السردية هي قائمة بالقيم. فيما يلي بعض الأمثلة:

type
  Colors = (Red, Yellow, Green, Cyan, Blue, Violet);
  Suit = (Club, Diamond, Heart, Spade);

كلّ قيمة في القائمة لها ما يصاحبها من ترتيب ordinalty، بدءاً من الصفر. عندما تطبق وظيفة ord على على قيمة من نوع سردي، تتحصّل على نفس هذه القيمة المبتدئة بصفر. مثلا، Ord (Diamond) ترجع 1.

ملاحظة: يمكن للأنواع السردية أن يكون لها تمثيلات داخلية مختلفة. ابتدائيا، تستخدم دلفي تمثيل 8-بت، ما لم يكن هناك أكثر من 256 قيمة مختلفة، في هذه الحالة تستخدم تمثيل 16-بت. يوجد أيضا تمثيل 32-بت، و الذي قد يكون مفيدا لأغراض التوافقية مع مكتبات س و س++. يمكنك في الواقع تغيير السلوك الإبتدائي، و طلب تمثيل أكبر، باستخدام توجيه المجمّع $Z .

مكتبة المكوّنات المرئية VCL (Visual Component Library) في دلفي تستخدم الأنواع السردية في عدّة أماكن. مثال ذلك، نمط الحدود لنموذج form معرّف كالتالي:

type
  TFormBorderStyle = (bsNone, bsSingle, bsSizeable,
    bsDialog, bsSizeToolWin, bsToolWindow);

عندما تكون السِمة property قيمتها سردية، عادة ما تختار من قائمة القيم المعروضة في معاين الكائنات Object Inspector ، كما هو معروض في الشكل 4.1.

الشكل 4.1: سمة نوع سردي في معاين الكائنات Object Inspector

يعرض ملف مساعدة دلفي بصفة عامة القيم المحتملة لأي نوع سردي enumeration. كبديل يمكنك استخدام برنامج OrdType والمتوفر في موقع www.marcocantu.com، ليتسنى لك رؤية ما لدى دلفي من أنواع سردية، فئات، مدى فرعي، أو أي نوع تراتبي آخر. يمكنك رؤية مثال لمخرجات هذا البرنامج في الشكل 4.2.

الشكل 4.2: معلومات مفصّلة عن نوع سردي، كما يعرضه برنامج OrdType (متوفّر بموقعي على الشبكة).

نوع فئة

أنواع الفئة set تشير إلى مجموعة من القيم. فهي صفّ من القيم المحتملة ذات نفس النوع التراتبي ordinal الذي للفئة. هذه الأنواع التراتبية عادة ما تكون محدودة، و غالبا ما يتم تمثيلها بسردية enumeration أو مدى فرعي subrange. إذا أخذنا المدى الفرعي 1..3، فإن القيم المحتملة للفئة التي ستبنى على هذا المدى سوف تتضمن إما: فقط 1، فقط 2، فقط 3، كلا 1 و 2، كلا 1 و 3، كلا 2 و 3، كل القيم الثلاث، أو لا واحدة منهم.

أي متغيّر عادة ما يضّم أحد هذه القيم المحتملة من المدى الذي يسمح به نوعه. أما المتغير الذي من نوع فئة، يمكنه أن يحوي أكثر من قيمة واحدة، فقد يحوي لا شيء، واحدة، إثنتان، ثلاثة، أو قيم أكثر ضمن المدى. بل يمكنه أن يتضمن كلّ القيم. ها هنا مثال عن فئة:

type
  Letters = set of Uppercase;

الآن يمكنني أت أعرّف متغيرا من هذا النوع و أخصّص له بعض القيم حسب النوع الأصلي. للإشارة إلى بعض القيم في فئة، تقوم بكتابة سردا مفصول بفاصلة comma-separated، و محصورا بين قوسين مربعين brackets. التوليف التالي يعرض تخصيصات لمتغير: بقيم متعدّدة، بقيمة واحدة، و بقيمة فارغة:

var
  Letters1, Letters2, Letters3: Letters;
begin
  Letters1 := ['A', 'B', 'C'];
  Letters2 := ['K'];
  Letters3 := [];

في دلفي، تستخدم الفئة عموما للإشارة إلى قيم غير حصرية. مثلا، سطرا التوليف التاليان (و هما جزء من مكتبة دلفي) يعرّفان سردا enumeration من الأيقونات المحتملة لإطار نافذة window ثم ما يوافق ذلك من نوع فئة:

type
  TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);
  TBorderIcons = set of TBorderIcon;

في الواقع، أية نافذة إما أن لا يكون لها أيا من هذه الأيقونات، واحدة منها، أو أكثر من ذلك. عند التعامل مع معاين الكائنات Object Inspector (انظر الشكل 4.3)، بإمكانك إعطاء قيم الفئة بتوسيع الإختيار (بلمسة مزدوجة على اسم السِمة أو بلمس علامة الجمع يسار الاسم) و تبادل تمكين أو إخماد حضور كلّ قيمة.

الشكل 4.3: سمة من نوع فئة في معاين الكائناتObject Inspector

سِمة أخرى porperty مبنية على نوع فئة و هي نمط الخط font style. القيم المحتملة تشير لخط داكن bold، مائل italic، تحته خط underline، و خط مقطوع strikethrough. بالطبع نفس الخط قد يكون مائلا و داكنا معا، أو بلا أي نمط، أو أن يملك أنماط الخط كلّها. لهذا السبب تم تعريف نمط الخط كفئة. و يمكنك تخصيص قيم لهذه الفئة في توليف برنامج كالتالي:

Font.Style := []; // no style
Font.Style := [fsBold]; // bold style only
Font.Style := [fsBold, fsItalic]; // two styles

يمكنك اجراء عمليات على الفئة بطرق مختلفة، بما في ذلك جمع متغيرين من نفس نوع الفئة (لنكون أكثر دقّة، حساب اتحاد فئتين):

Font.Style := OldStyle + [fsUnderline]; // two sets

مرّة أخرى، تستطيع استخدام مثال OrdType والموجود في دليل TOOLS في التوليف المصدري للكتاب، لرؤية قائمة بالقيم المحتملة للعديد من الفئات المعرّفة في مكتبة مكونات دلفي.

أنواع مصفوفة

أنواع مصفوفة Array types تحدد قوائما بعدد ثابت من العناصر من نوع محدد. أنت ستستعمل عادة دليلا index بين قوسين مربعين للوصول إلى أحد عناصر المصفوفة. الأقواس المربعة تستعمل أيضا لتحديد القيم المحتملة لعدد العناصر عند تعريف المصفوفة. مثلا، يمكنك تحديد مجموعة من 24 صحيحا بالتوليف التالي:

type
  DayTemperatures = array [1..24] of Integer;

عند تعريف المصفوفة، تحتاج إلى تمرير نوع مدى فرعي subrange بين قوسين مربعين، أو تحديد نوع مدى فرعي جديد خاص باستخدام ثابتين constant من نوع تراتبي. المدى الفرعي هذا يحدد الأدلة indexes المسموح بها في المصفوفة. و حيث انك ستحدد كل من الدليل الأعلى و الدليل الأدنى في المصفوفة، فإن الأدلة لا حاجة لها بأن تبدأ بصفر zero-based، عكس الحال في س، و س++، و جافا، و لغات برمجة أخرى.

و حيث أن أدلة المصفوفة مبنية على مدى فرعي subrange، يمكن لدلفي أن تتفحّص مداها كما رأينا سابقا. فأي ثابت خارج النطاق في مدى فرعي سينتج خطأ عند زمن التجميع؛ كما أن أي دليل خارج النطاق يستخدم في زمن التشغيل ينتج عنه خطأ زمن التشغيل، في حالة تمكين الخيار ذو العلاقة في المجّمع.

باستخدام تعريف المصفوفة أعلاه، يمكنك جعل قيمة المتغير DayTemp1 من نوع DayTemperatures كالتالي:

type
  DayTemperatures = array [1..24] of Integer;

var  
  DayTemp1: DayTemperatures;
  
procedure AssignTemp;  
begin  
  DayTemp1 [1] := 54;
  DayTemp1 [2] := 52;
  ...
  DayTemp1 [24] := 66;
  DayTemp1 [25] := 67; // compile-time error

قد يكون للمصفوفة أكثر من بعد واحد، كما في المثال التالي:

type
  MonthTemps = array [1..24, 1..31] of Integer;
  YearTemps = array [1..24, 1..31, Jan..Dec] of Integer;

نوعي المصفوفة هذين بُنيا على النوع الأساسي نفسه. يمكنك تعريفهما باستخدام أنواع البيانات السابقة، كما في التوليف التالي:

type
  MonthTemps = array [1..31] of DayTemperatures;
  YearTemps = array [Jan..Dec] of MonthTemps;

هذا التعريف يقلب تريب الأدلّة كما هو أعلاه، لكنّه أيضا يسمح بتخصيص كُتل كاملة فيما بين المتغيرات. مثلا، التعليمة التالية تنسخ درجات حرارة temperatures شهر يناير إلى فبراير:

var
  ThisYear: YearTemps;
begin
  ...
  ThisYear[Feb] := ThisYear[Jan];

يمكنك أيضا تعريف مصفوفة تبدأ بصفر zero-based ، نوع مصفوفة حدّها الأدني يساوي صفر. عموما، استخدام حدّين منطقيين أكثر يعدّ ميزة، حيث لا تضطر إلى استخدام الدليل 2 للوصول إلى العنصر 3، و هكذا. إلا أن ويندوز وبصورة ثابتة تستخدم مصفوفات تبدأ بصفر (لأنها مؤسسة على لغة س)، و مكتبة مكونات دلفي تتجه لفعل نفس الشيء.

إذا احتجت إلى الاشتغال على مصفوفة، يمكنك دائما اختبار حدّيها باستخدام الوظيفتين النمطيتين Low و High، و اللتين ترجعان الحدّ الأدنى والحدّ الأعلى. يُنصح بشدّة باستخدام Low و High عند التعامل مع المصفوفة، خاصة في الحلقات loops، ما دامتا تجعلان من التوليف غير محتاج لمعرفة نطاق المصفوفة مقدما. لاحقا يمكنك تغيير النطاق المعرّف لأدلة المصفوفة، و يبقى التوليف الذي يستعمل Low و High بدون تغيير و مستمرا في عمله. أما إذا كتبت حلقة loop مع تحديد صريح لنطاق المصفوفة، فستجد نفسك مضطرا لتحديث التوليف الخاص بالحلقة كلما تغيّر حجم المصفوفة. Low و High تجعلان من توليفك أكثر سهولة عند الصيانة و أكثر اعتمادية.

ملاحظة: بالمناسبة، لايوجد أي إرهاق تشغيلي عند إستعمال Low و High مع المصفوفات. ففي زمن التجميع compile-time يتم ارجاعهما إلى ثابتين constant، و ليس إلى استدعاءات حقيقية لوظيفة. هذه الحلول التي تتم في زمن التحويل للتعبيرات و استدعاءات الوظائف تحدث أيضا لكثير من وظائف النظام البسيطة الأخرى.

كثيرا ما تستعمل دلفي المصفوفات في شكل سِمات نوع مصفوفة array properties. نحن رأينا بالفعل سِمة مماثلة في مثال TimeNow، للوصول إلى سِمة Items عناصر في مكوّن ListBox. سأقوم بعرض بعض الأمثلة الاضافية لسِمات نوع مصفوفة في الفصل التالي، عند الحديث عن حلقات loops دلفي.

ملاحظة:أدخلت دلفي 4 المصفوفات الحيوية في اوبجكت باسكال، و هي المصفوفات التي يمكن أن يتغير حجمها في زمن التشغيل متخذة لنفسها ما يناسبها من كمية من الذاكرة، استخدام المصفوفات الحيوية أمر سهل، لكن في مناقشتنا هذه عن باسكال شعرت بأنها ليست موضوعا مناسبا لتغطيته. يمكنك أن تجد وصفا لمصفوفات دلفي الحيوية في الفصل 8.

Record Types

نوع تسجيلة record types تحدّد مجموعة ثابتة من عناصر ذات أنواع مختلفة. كل عنصر، أو حقل field ، له نوعا خاصا به. تعريف نوع تسجيلة تعرض قائمة بكل هذه الحقول، تعطي لكل منها اسما لتستخدمه لاحقا من أجل الوصول إليه.

ها هنا عرضا بسيطا لتعريف من نوع تسجيلة، ثم تعريف لمتغير من هذا النوع، و بعض التعليمات التي تستخدم هذا المتغيّر:

type
  Date = record
    Year: Integer;
    Month: Byte;
    Day: Byte;
  end;
  
var
  BirthDay: Date;
  
begin
  BirthDay.Year := 1997;
  BirthDay.Month := 2;
  BirthDay.Day := 14;

يمكن اعتبار الطبقات Classes و الكينونات objects امتدادا لنوع تسجيلة. مكتبات دلفي تتجه لاستخدام أنواع طبقة عوضا عن نوع تسجيلة، و لكن يوجد العديد من أنواع تسجيلة في مكتبات API ويندوز.

يمكن لأنواع تسجيلة أن يكون لها جزءا متباينا variant part؛ عدّة حقول يمكن توجيهها لنفس مساحة الذاكرة، حتى إذا كان لها نوع بيانات مختلف. (يطابق هذا مفهوم union في لغة س.) فكبديل، يمكنك استخدام الحقول أو مجموعات الحقول المتباينة للوصل إلى نفس موقع الذاكرة ضمن التسجيلة، لكنها تتعامل مع هذه القيم من زوايا مختلفة. الإستخدامات الرئيسية لهذه الأنواع هي لتخزين بيانات متشابهة لكن مختلفة، و للحصول على تأثير شبيه بتلبيس النوع typecasting (الأمر الذي يعد أقل فائدة الآن حيث أن تلبيس النوع تم ادخاله أيضا في باسكال). ان استخدام أنواع تسجيلة متباينة تم استبداله بصورة كبيرة بمفاهيم الاتجاه للكائن object-oriented و بتقنيات حديثة أخرى، بالرغم أن دلفي تستدخدمها في بعض الحالات الغريبة.

استخدام نوع تسجيلة متباينة ليست آمنة النوع type-safe ، و ليست من العادات البرمجية التي ينصح بها، خاصة مع المبتدئين. بالتأكيد يمكن للمبرمجين الخبراء استخدام أنواع تسجيلة متباينة، بل أن لُبّ مكتبات دلفي تقوم باستخدامها، لكنك، على كل حال، لست محتاجا لأن تتعامل معها حتى تصبح بالفعل خبيرا في دلفي.

Pointers

نوع مؤشّر pointer يحدّد متغيرا يحوي عنوان متغير آخر في الذاكرة ذو نوع بيانات محدد (أو نوع غير محدد). لذا فإن متغير المؤشر و بطريقة غير مباشرة يشير إلى قيمة. تعريف نوع مؤشّر لا يستلزم كلمة مفتاحية معينة، انه يستعمل حرفا خاصا بدلا من ذلك. الحرف أو الرمز الخاص هو علامة الادراج caret (^):

type
  PointerToInt = ^Integer;

حالما عرّفت متغيرا مؤشرا، يمكنك أن تخصص له العنوان الخاص بمتغير آخر من نفس النوع، باستخدام العامل @:

var
  P: ^Integer;
  X: Integer;
begin
  P := @X;
  // change the value in two different ways
  X := 10;
  P^ := 20;  

عندما يكون لديك المؤشّر P، فإنه بواسطة التعبير P أنت تشير إلى موقع في الذاكرة يشير إليه المؤشر، و بواسطة التعبير P^ أنت تشير إلى المحتويات الفعلية في موقع الذاكرة هذا. لهذا السبب في التوليف السابق فإن P^ تطابق X .

بدلا من الإشارة إلى موقع ذاكرة موجود، يمكن للمؤشر أن يشير إلى مساحة جديدة في الذاكرة يتم تخصيصها بصورة حيّة (في منطقة من محيط الذاكرة) بواسطة الإجرائية New. في هذه الحالة، و عند إنتهاء حاجتك للمؤشر، عليك أيضا أن تتخلص من الذاكرة التي قمت بحجزها، بإستدعاء الوظيفة Dispose .

var
  P: ^Integer;
begin
  // initialization
  New (P);
  // operations
  P^ := 20;
  ShowMessage (IntToStr (P^));
  // termination
  Dispose (P);
end;

إذا كان المؤشر خاليا من أية قيمة، يمكنك تخصيص قيمة nil لا شيء له، بعدها تستطيع إختبار خلوّ المؤشر لمعرفة إذا ما هو حاليا يشير إلى قيمة. و هذا يستعمل عادة، لأن التأشير الخاطئ بمؤشر فارغ يسبّب انتهاكا لحرمة الدخول access violation. (أيضا يعرف بخطأ حماية عام general protection fault ، أو GPF):

procedure TFormGPF.BtnGpfClick(Sender: TObject);
var
  P: ^Integer;
begin
  P := nil;
  ShowMessage (IntToStr (P^));
end;

يمكنك رؤية مثالا عن تأثير هذا التوليف بتشغيل مثال GPF (أو رؤيته كما في الشكل 4.4). المثال يحوي أيضا أجزاء التوليف المعروض أعلاه.

الشكل 4.4: خطأ نظام ناتج عن الدخول بمؤشر خال، من مثال GPF.

في نفس البرنامج يمكن أن تجد مثالا لكيفية الوصول الآمن للبيانات. في هذه الحالة الثانية تمّ تخصيص المؤشر لمتغير محلي موجود، و يمكن استخدامه بأمان، لكني أضفت إليه فحص أمان للتأكيد:

procedure TFormGPF.BtnSafeClick(Sender: TObject);
var
  P: ^Integer;
  X: Integer;
begin
  P := @X;
  X := 100;
  if P <>  nil then
    ShowMessage (IntToStr (P^));
end;

تعرّف دلفي أيضا نوع بيانات مؤشر تدلّ على مؤشرات بلانوع untyped (مثل void* في لغة س). إذا استخدمت مؤشرات بلا نوع يجب أن تستخدم GetMem بدلا من New. إجرائية GetMem مطلوبة في كل مرة يكون فيها حجم متغير الذاكرة المطلوب حجزه غير محدد.

حقيقة أن المؤشرات pointers نادرة ما تكون ضرورية، هي ميزة مثيرة للإهتمام في هذه البيئة. لا شك، بأن فهم المؤشرات مهمّ للبرمجة المتقدمة و لفهم متكامل لنماذج كائنات دلفي، التي تستخدم المؤشرات "من خلف الكواليس".

ملاحظة: بالرغم من أنك لاتستعمل المؤشرات غالبا في دلفي، فأنت عادة ما تستعمل بنية شبيهة جدا، ما يعرف بالإشارة reference. كل حضور لكائن object هو في الواقع مؤشر أو إشارة صريحة لبياناته الفعلية. عموما، هذا الأمر يعد مغيّبا بالكامل عن المبرمج، الذي سيستعمل متغيرات كائن تماما مثله مثل أي نوع بيانات آخر.

أنواع ملفّ

مشيّد نوع باسكال آخر هو نوع ملف file. أنواع ملف File types تمثل الملفات الفعلية بقرص التخزين، مؤكّدة غرابة لغة باسكال. يمكنك تعريف نوع بيانات ملف جديد كالتالي:

type
  IntFile = file of Integer;

بعد ذلك تستطيع فتح ملف فعلي مرتبطا بهذه البنية، وتقوم بكتابة قيم بأرقام صحيحة فيه أو قراءة القيم الحالية منه.

ملاحظة أخرى: الأمثلة المتعلقة بالملفات كانت جزءا من الإصدارات القديمة لكتاب Mastering Delphi و أخطّط لإضافتها هنا كذلك.

التعامل مع الملفات في باسكال يسيط جدا، لكن في دلفي توجد أيضا العديد من المكونّات components القادرة على تخزين أو تحميل محتوياتها من و إلى ملف. هناك بعض الدعم للتسلسلية serialization، و ذلك على هيئة دفقات streams، و يوجد أيضا دعما لقواعد البيانات database.

ملخّص

ناقش هذا الفصل أنواع بيانات محددة بالمستعمل، مكملا تغطيتنا لنظام أنواع باسكال. الآن نحن جاهزون للنظر للتعليمات التي توفرها اللغة للتعامل مع المتغيرات التي حدّدناها.

الفصل التالي: التعليمات

حقوق النسخ محفوظة لماركو كانتو؛ وينتش ايطاليا © Copyright Marco Cantù, Wintech Italia Srl 1995-2000
حقوق الترجمة: خالد الشقروني ، 2000