dark prince
02-03-2013, 06:51 AM
السلام عليكم ورحمة الله وبركاته..
اخواتي هذه مجموعة دروس في تعلم لغة الباسكال...
الفصل 1
تاريخ باسكال
لغة اوبجيكت باسكال (Opject Pascal) التي نستخدمها في دلفي لم يتم اختراعها في 1995 مع ظهور بيئة البرمجة المرئية لبورلاند. هي ببساطة امتداد للغة اوبجيكت باسكال التى كانت موجودة في منتجات باسكال السابقة لبورلاند. الا ان بورلاند لم تقم بابتكار باسكال، ولكنها فقط ساعدت على جعلها اكثر شعبية كما طورتها قليلا..
هذا الفصل سوف يحوي خلفية تاريخية عن لغة باسكال وتطورها. في الوقت الحالي سيتضمن فقط نُبذ قصيرة جدا.
باسكال ويرذ
تم تصميم لغة باسكال في الأصل سنة 1971 من قبل نيكلوس ويرذ (Niklaus Wirth)، البروفيسور في معهد زيوريخ التقني بسويسرا. وصممت باسكال بحيث تكون نسخة مبسطة لأغراض تعليمية من لغة أخرى هي الكول Algol ، التي يرجع تاريخها الى 1960.
عندما تم تصميم باسكال، كانت توجد العديد من لغات البرمجة الأخرى، لكن القليل منها الذي انتشر استعماله: فورتران، س، اسيمبلر، كوبول. الفكرة الرئيسية في اللغة الجديدة كانت التنظيم. أي أن تكون لغة منظمة من خلال مفهوم قوي لأنواع البيانات، و الزام وجود تعريفات مسبقة، وتحكمات هيكلية للبرنامج. كما تم تصميم اللغة ايضا لتكون اداة تعليمية للطلبة في فصول البرمجة.
تربو باسكال
محول باسكال الأكثر شهرة عالميا من بورلاند ، يدعى تربو باسكال Turbo Pascal ، تم تقديمه في 1983، مراعيا فيه تنفيذ كتاب "دليل المستخدم والتقارير لباسكال" لكل من جينسن و ويرذ،. وقد اصبح محول تربو باسكال احد اكثر المحولات مبيعا، واكسب اللغة شعبية خاصة بيئات الحواسيب الشخصية، ويرجع الفضل في ذلك الى الموائمة بين البساطة والقوة.
قدم تربو باسكال بيئة تطوير متكاملة (IDE) حيث يمكنك كتابة البرنامج (في محرر نصوص متوافق مع وورد ستار) ، ثم تقوم بتشغيل المحوّل، تتطّلع عل الاخطاء، تقفز مباشرة للعودة لأسطر البرنامج التي تحوي هذه الأخطاء. قد يبدو هذا شيئا عاديا الآن، لكن في السابق كان عليك ان تغلق محر النصوص الذي فيه برنامجك، تعود الى دوس؛ تقوم بتشغيل المحول ذو الأوامر السطرية، تكتب الأخطاء التي تظهر في ورقة خارجية، تعود لفتح محرر النصوص من جديد لتبحث فيه.
أكثر من هذا؛ قامت بورلاند ببيع تربو باسكال بسعر 49 دولار، في الوقت التي كانت فيه ميكروسفت تبيع محول الباسكال الخاص بها ببضع مئات. وقد كان لنجاح تربو باسكال على مدى سنوات الأثر في قرار ميكروسفت بوقف انتاجها لمحول باسكال الخاص بها.
باسكال دلفي
بعد 9 اصدارات من محولات تربو وبورلاند باسكال، والتي من خلالها تطورت اللغة تدريجيا، اصدرت بورلاند دلفي في 1995، ناقلة بذلك باسكال الى لغة برمجة مرئية.
دلفي مدّت في لغة باسكال في عدة مجالات، حيث اضافت بعض الخصائص ذات الاتجاه الموضوعي object-oriented والتي تختلف عن بعض المذاقات الأخرى لأوبجكت باسكال، حتى عن تلك التي في محوّل Borland Pascal with Objects compiler.
الفصل التالي: البرمجة بباسكال
- - - تم التحديث - - -
قبل ان ننتقل الى موضوع كتابة تعليمات لغة باسكال، من المهم أن نلقي الضوء على بعض عناصر نمط كتابة التعليمات بباسكل. المسألة التي أودّ الإشارة اليها هنا كالتالي: بجانب قواعد اللغة، ما هي الكيفية التي يجب عليك اتباعها لكتابة التعليمات. لاتوجد اجابة واحدة على هذا السؤال، حيث ان الأسلوب الشخصي يمكنه ان يقرر عدة انماط. عموما، هناك بعض المبادئ التي تحتاج لمعرفتها فيما يخصّ وضع التعليقات، حالة الأحرف، المسافات و ما يسمّى بالطباعة الأنيقة pretty-printing . كمبدأ عام، الهدف من أي نمط للكتابة هي الوضوح. ان النمط و القالب الذي تختاره هو شكل من اشكال الاختزال، يشير الى الغرض من جزء ما من التعليمات البرمجية. و الأداة الرئيسية للوصول الى الوضوح هي وحدة النسق بغضّ النظر عن النمط الذي تختاره، كن متأكدّا بأنكّ ستتّبع نفس النسق عبر كامل المشروع البرمجي.
التعليقات
في باسكال، يتم ضمّ التعليقات في أقواس braces أو أقواس parentheses متبوعة بنجمة. دلفي تقبل ايضا نمط التعليقات المتبعة في س++ ، والتي يمكنها ان تمتد الى نهاية السطر:
{هذا تعليق}
(* هذا تعليق آخر *)
// هذا تعليق آخر يمتد حتى نهاية السطر
الشكل الأول أقصر و أكثر اتّباعا. الشكل الثاني كان مفضلا أكثر في اوربا بسبب عدم وجود رمز القوس السهمي في لوحات المفاتيح. الشكل الثالث من التعليقات تم استعارته من س++ و متوفر فقط في نسخ 32 بت من دلفي. التعليقات المحدودة بنهاية السطر مفيدة جدا للملاحظات القصيرة و لتلك الخاصة بسطر محدد في التوليف.
خلال سرد الأمثلة في هذا الكتاب سأحاول تعليم التعليقات بأحرف مائلة، (و الكلمات الرئيسية بالتغميق)، لتكون متسقة مع النمط الافتراضي للصياغة في دلفي.
وجود ثلاثة اشكال مختلفة من التعليقات يمكن ان يساعد في بناء تعليقات متداخلة. إذا اردت التعليق على مجموعة أسطر من برنامج من اجل وقفها، وهذه الأسطر تحوي بعض التعليقات السابقة، فإنك لاتستطيع استخدام نفس علامة التعليقات:
{ ... code
{comment, creating problems}
... code }
مع علامة تعليق ثانية، يمكنك كتابة التعليمات الآتية، و التي هي صحيحة:
{ ... code
//this comment is OK
... code }
لاحظ أن القوس المفتوح او القوس_نجمة اذا كان تليه علامة الدولار ($)، فسوف يتحول الى توجيه للمُجمّع compiler directive ، كما في {$X+}.
في الواقع، توجيهات المجمّع تعد تعليقات أيضا. مثال ذلك، {$X+ This is a comment} هي صحيحة. هي كلاهما توجيه و تعليق صحيحين، الا أن المبرمج المتعقل سوف يختار ان يفصل بين التوجيهات والتعليقات.
استخدام الأحرف العالية
مجمّع باسكال (بعكس اللغات الأخرى) يغضّ الطرف عن حالة الأحرف (عالية أو منخفضة). لذلك؛ فإن التعريفات التالية Myname ، MyName، myname، myName، و MYNAME كلها متساوية. بشكل عام، هذا يعدّ أمرا ايجابيا، ففي اللغات الحسّاسة لحالة الأحرف، العديد من الأخطاء اللغوية قد تحدث بسبب الإهمال في مراعاة حالة الأحرف.
ملاحظة: ربما الحالة الإستثناء الوحيدة لقاعدة حساسية الأحرف في باسكال هي: إجراء Register في حزمة المكونات، لابد لها أن تبدأ بحرف R العالي، وذلك للمحافظة على التوافقية مع C++ Builder.
إلا أنه توجد بعض السلبيات. أولا، يجب أن تنتبه لأن تكون هذه التعريفات متساوية بالفعل، لذا يجب أن تتجنب استعمالها كعناصر مختلفة. ثانيا، يجب أن تكون متّسقا قدر الامكان عند استخدامك للأحرف العالية، لتحسين مقروئية برنامجك.
توحيد استخدام حالة الأحرف ليس ملزما من قبل المجمّع، و لكنها عادة حسنة يحبّذ اتّباعها. الاسلوب المتبع هو تكبير الحرف الأول فقط من كل معرّّف identifier. و عندما يكون المعرّف مركّبا من عدة كلمات (لايمكنك حشر فراغ في المعرّف) ، فإن كل أول حرف من كل كلمة يجب أن يكون عاليا:
MyLongIdentifier
MyVeryLongAndAlmostStupidIdentifier
هناك حالات أخرى لايأبه لها المجمّع كالفراغات، و الأسطر الفارغة، و المسافات (tabs) التي تقوم بوضعها في البرنامج. كل هذه الحالات مجتمعة تسمّى بالفراغ الأبيض white space . الفراغات البيضاء تستخدم فقط لتحسين مقروئية البرنامج؛ و لا تؤثر في عملية التتجميع.
بعكس لغة بيسك BASIC ، فإن باسكال تسمح لك بكتابة تعليمة واحدة موزعة على عدة أسطر، فالتعليمة الطويلة يمكن تجزئتها لتكون في سطرين أو أكثر. السلبية الوحيدة (على الأقل بالنسبة لمبرمجى البيسك) لإمكانية أن تكون التعليمات في أكثر من سطر هي أنه عليك أن تتذكّر بأن تضع فاصلة منقوطة آخر كل تعليمة، أو بدقة أكثر، أن تفصل بين التعليمة والتي تليها. لاحظ أن القيد الوحيد هنا ان الجملة النصية الواحدة لايمكن مدّها لعدّة أسطر.
مرّة أخرى، لاتوجد قواعد ثابتة لاتستخدام الفراغات و التعليمات متعددة الأسطر، فقط بعض الأعراف:
محرّر نصوص دلفي له خطا عموديا تستطيع وضعه على بعد 60 أو 70 حرف. إذا استخدمت هذا الخطّ كمؤشر لتجنب تجاوزه، فإن برنامجك سوف يبدو أفضل عندما تقوم بطباعته على الورق. غير هذا فإن الأسطر الطويلة قد يتم تجزئتها من أي موضع حتى من منتصف الكلمة عند طباعة البرنامج.
عندما يكون للوظيفة أو الإجراء عدة محددات parameters ، فإن العادة المتّبعة هنا هي وضع هذه المحدّدات في سطر آخر.
تستطيع ترك سطر بكامله أبيضا (فارغا) قبل وضع أي تعليق أو ملاحظة، أو لتقسيم جزء كبير من التعليمات الى أجزاء أصغر. وحتى هذه الفكرة البسيطة بإمكانها تحسين مقروئية البرنامج، سواء على الشاشة أو عند طباعتها.
استخدم الفراغات لفصل محددات استدعاء وظيفة function call، وربما حتى فراغ قبل فتح الأقواس، ايضا حافظ على فراغات لفصل رموز العمليات في التعابير البرمجية. أنا أعلم أن بعض المبرمجين لن يوافقوا على هذه الفكرة، لكن أنا أصرّ: الفراغات بالمجان؛ لن تدفع شيئا مقابلها .(نعم، أعلم انها تستهلك مكانا للتخزين أو وقتا اضافيا في عملية اتصال الموديم لتحميل أو تنزيل ملف، لكن هذا أصبح لامعنى له في وقتنا الحاضر.)
الطباعة الأنيقة
الاقتراح الأخير فيما يخصّ استخدام الفراغات البيضاء له علاقة بالعرف المتبع لنسق تشكيل لغة باسكال، و الذي يعرف بالطباعة الأنيقة pretty-printing. القاعدة بسيطة: كل مرة تحتاج فيها لكتابة تعليمة مركّبة، قم بوضعها بعد هامش فراغين الى اليمين من باقي التعليمة الحالية. التعليمة المركبة داخل تعليمة أخرى مركبة يتم تهميشها بأربع مسافات، وهكذا:
if ... then
statement;
if ... then
begin
statement1;
statement2;
end;
if ... then
begin
if ... then
statement1;
statement2;
end;
الصياغة السابقة تعتمد نسق الطباعة الأنيقة، لكن المبرمجين لديهم تفسيرات مختلفة لهذه القاعدة العامة. بعض المبرمجين مثلا يقومون بتهميش تعليمات begin و end للمستوى التالي مع نفس التعليمات الداخلية، بعضهم يهمش begin و end ثم يقومون بتهميش التعليمات الداخلية لمستوى اضافي، مبرمجون آخرون يضعون begin في نفس سطر شرط if . هذا في معظمه أمر له علاقة بالذوق الشخصي.
نفس نمط التهميش يتّّبع عادة عند سرد المتغيرات أو أنواع الببيانات، و لمواصلة تعليمة من سطر سابق:
type
Letters = set of Char;
var
Name: string;
begin
{ long comment and long statement, going on in the
following line and indented two spaces }
MessageDlg ('This is a message',
mtInformation, [mbOk], 0);
بالطّبع، أي من هذه القواعد هي مجرّد إقتراح لجعل البرنامج مقروءا بشكل أفضل من قبل المبرمجين الآخرين، و هي تهمل بالكامل من جانب المجمّع. لقد حاولت استخدام هذه القاعدة بصورة متّسقة في كل اجزاء الأمثلة والبرامج في هذا الكتاب. كما يلاحظ أن البرامج، الأدلة، و أمثلة المساعدة التي تأتي مع دلفي كلها تتّبع نفس النسق في الصياغة.
تعليم الألفاظ
لتسهيل قراءة و كتابة توليف code باسكال، يملك محرر دلفي خاصية تسمّى تعليم الألفاظ syntax highlighting . فالكلمات التي تقوم بطباعتها في المحرر، يتم اظهارها باستخدام ألوان مختلفة بحسب معناها في باسكال. عرضا، الكلمات المفتاحية keywords تكون داكنة، النصوص و التعليقات تظهر ملونة (و غالبا مائلة)، وهكذا.
الكلمات المحجوزة، و التعليقات، و النصوص تقريبا هي العناصر الثلاثة الأكثر استفادة من هذه الخاصية. فمن أول نظرة يمكنك ملاحظة كلمة مفتاحية غير صحيحة، أو نصّ غير مقفل بصورة سليمة، أو طول الملاحظة المتعددة الأسطر.
بإمكانك بسهولة تعديل مواصفات تعليم الألفاظ باستخدام صفحة ألوان المحرر Editor page في لوحة خيارات البيئة Environment Options (انظر الشكل 2.1). إذا كنت تعمل بمفردك، يمكنك اختيار الألوان التي تفضل. أما إذا كنت تعمل بالتعاون مع مبرمجين آخرين، فالأفضل أن توافقوا جميعا على نسق ألوان نمطي. لقد وجدت ان العمل على حاسوب به تلوين الفاظ مختلف عمّا تعوّدت عليه أمر صعب بالفعل.
الشكل 2.1: لوحة الحوار المستخدمة لتحديد لون تعليم الألفاظ.
http://www.shabwh.com/up//uploads/images/shabwh3828939a86.gif (http://www.shabwh.com/up//uploads/images/shabwh3828939a86.gif)
استخدام قوالب اللغة
قدّمت دلفي 3 خاصيّة جديدة ذات علاقة بكتابة شفرة البرامج. عند كتابة تعليمات لغة باسكال تجد نفسك عادة ما تعيد كتابة نفس التتابع من الكلمات الرئيسية، لذلك قدمت بورلاند خاصية جديدة تسمّى قوالب اللغة Code Templates . قوالب اللغة هي ببساطة قطعة من توليف مرتبطة بمفاتيح مختصرة. حيث تقوم بكتابة النص المختصر ثم تتبعها بالضغط على Ctrl+j، فيظهر التوليف ذو العلاقة مكتوبا بالكامل. مثلا، اذا قمت بكتابة arrayd ، ثم ضغطت على Ctrl+j ، فان محرر دلفي سوف يوسع من النص المختصر الى التالي:
array [0..] of ;
و حيث ان قوالب التوليف المحددة سلفا عادة ما تأتي بنسخ مختلفة لنفس الاختصار، فان النص المختصر ينتهي عموما بحرف يشير الى النسخة التي قد تهمك. عموما يمكنك كتابة فقط جزء من النص المختصر. مثال ذلك، اذا كتبت ar ثم ضغطت على Ctrl+j ، يظهر المحرر قائمة تظهر الخيارت المتوفرة مع وصف موجز لكل اختصار، مثلما هو واضح في الشكل 2.2 .
الشكل 2.2 اختيار قالب التوليف
http://www.shabwh.com/up//uploads/images/shabwh354c4f6c89.gif (http://www.shabwh.com/up//uploads/images/shabwh354c4f6c89.gif)
تستطيع صياغة قوالب التوليف إما بتعديل الموجود منها، أو ببناء قوالب جديدة خاصة بك. واذا قمت بهذا، تذّكر ان نص قالب التوليف عادة ما يحوي حرف '|' ليشير الى الموقع الذي سيقفز له المؤشر بعد انتهاء العملية، حيث تتابع الكتابة لإكمال نص القالب.
تعليمات اللغة
حالما تقوم بتحديد بعض المعرفات، يمكنك استخدامها في تعليمات او في معادلات هي جزء من بعض التعليمات, تقدم باسكال مجموعة من التعليمات والتعبيرات. دعنا أولا نلقي نظرة على الكلمات المفتاحية، و التعبيرات ، و العاملات.
الكلمات المفتاحية
الكلمات المفتاحية هي كل المعرّفات المحجوزة من قبل اوبجكت باسكال، و التي لها دور في اللغة. دليل دلفي (Help) يميّز بين الكلمات المحجوزة والتوجيهات كالتالي: الكلمات المحجوزة لا يمكن استخدامها كمعرّفات، بينما التوجيهات لا يجب استخدامها لنفس الغرض، حتى لو قبلها المجمّع. عند الممارسة، عليك تجنّب استخدام أية كلمة محجوزة كمعرّف.
في الجدول 2.1 يمكنك رؤية قائمة كاملة بالمعرّفات التي لها دورا خاصا في لغة اوبجكت باسكال (في دلفي 4)، بما في ذلك الكلمات و الكلمات المحجوزة الأخرى.
الجدول 2.1: الكلمات المفتاحية و الكلمات المحجوزة الأخرى في لغة اوبجكت باسكال
http://www.shabwh.com/up//uploads/images/shabwhf3ba040123.gif (http://www.shabwh.com/up//uploads/images/shabwhf3ba040123.gif)
http://www.shabwh.com/up//uploads/images/shabwh4054e62069.gif (http://www.shabwh.com/up//uploads/images/shabwh4054e62069.gif)
http://www.shabwh.com/up//uploads/images/shabwh3bd100dfa4.gif (http://www.shabwh.com/up//uploads/images/shabwh3bd100dfa4.gif)
http://www.shabwh.com/up//uploads/images/shabwhafc33d2978.gif (http://www.shabwh.com/up//uploads/images/shabwhafc33d2978.gif)
التعبيرات والعامِلات
لا توجد قاعدة عامة لبناء التعبيرات expressions ، حيث تعتمد اساسا على العامِلات التي تستخدم، و التي لباسكال العديد منها. هناك المنطقي logical والحسابي arithmetic والبولي Boolean والعلائقي relational ، و عاملات الفئة set، بالاضافة الى عدد آخر. يمكن استعمال التعبيرات لتحديد القيمة التي ستخصص للمتغير، او لحساب المحدد parameter التابع لوظيفة او اجراء، او لاختبار شرط. و قد تتضمن التعبيرات استدعاء وظائف ايضا. في كل مرة تقوم فيها باجراء عملية على قيمة في معرّف، و ليس استعمال المعرف في حد ذاته، فان هذا يعدّ تعبيرا.
تعد التعبيرات امرا شائعا في لغات البرمجة. التعبير هو أي توليفة من الثوابت constants ، المتغيرات، القيم الحرفية literal ، عاملات، و نتائج الوظائف. التعبيرات يمكن ايضا تمريرها الى المحددات القيمية value parameters في الاجراءات و الوظائف، و لكن ليس دائما الى المحددات المرجعية reference parameters (التي تحتاج الى قيمة يمكن تخصيصها).
العامِلات و أسبقيتها
اذا سبق لك و أن كتبت برنامجا في حياتك، فانك تعلم بالفعل ماذا تعني كلمة تعبير expression. هنا سوف ألقي الضوء على عناصر محددة في عاملات باسكال. يمكنك رؤية قائمة بعاملات اللغة، مجمعة حسب الأسبقية، في الجدول 2.1.
على العكس من معظم اللغات الأخرى، فإن عاملات and و or لهما الأسبقية على العاملات العلائقية. لذاك اذا كتبت a < b and c < d، فان المجمّع سيحاول تنفيذ عملية and أولا، منتجا بذلك خطأ تجميع. لهذا السبب عليك وضع كل من تعبير < بين قوسين: (a < b) and (c < d).
بعض العاملات الشائعة لديها معان مختلفة مع انواع بيانات مختلفة. مثال ذلك، العامل + يمكن استخدامه لجمع رقمين، لوصل جملتين، صنع اتحاد بين فئتين، او حتى جمع رصيف offset مع مؤشر Pchar . الا انك لاتستطيع جمع حرفين، كما هو ممكن في لغة c.
عامل آخر غريب وهو div . ففي باسكال، يمكنك تقسيم أي رقمين (حقيقي أو صحيح) بواسطة العامل / ، وسوف تحصل بصورة ثابتة على رقم حقيقي كناتج. اما اذا احتجت الى تقسيم رقمين صحيحين للحصول على ناتج صحيح، استخدم العامل div كبديل.
الجدول 2.2: معاملات لغة باسكال، مجمعة حسب اسبقيتها
http://www.shabwh.com/up//uploads/images/shabwh388c0a8ffb.gif (http://www.shabwh.com/up//uploads/images/shabwh388c0a8ffb.gif)
عامِلات الفئة
عاملات الفئة تتضمن اتحاد union (+)، طرح difference (-)، تقاطع intersection (*)، اختبار عضوية membership (in)، بالإضافة الى مجموعة من العاملات العلائقية. لاضافة عنصر لمجموعة، يمكنك جعل اتحاد فئةة مع آخرى تملك فقط العنصر الذي تحتاجه. فيما يلي مثال بدلفي له علاقة بنمط الخطّ font styles:
Style := Style + [fsBold];
Style := Style + [fsBold, fsItalic] - [fsUnderline];
كبديل يمكنك استخدام الاجرائين الاعتيادين Include و Exclude، وهما أكثر فاعلية (لكنهما لايمكن استعمالهما مع سمات مكوّن التي تكون من نوع set، لأنها تحتاج الى محدد لقيمة l-):
Include (Style, fsBold);
ملخّص
الآن وقد عرفنا الخطوط الأساسية لبرنامج باسكال فنحن جاهزون لفهم معانيها بالتفصيل. سوف نبدأ باستكشاف تعريف أنواع البيانات سابقة التحديد و المحددة بالمستعمل، بعدها سننتقل معها الى استخدام الكلمات المفتاحية لبناء تعليمات برمجية.
الفصل التالي: الأنواع، المتغيرات، و الثوابت
- - - تم التحديث - - -
الفصل 3
الأنواع، المتغيرات، والثوابت
اعتمدت لغة باسكال الأصلية عل بعض المفاهيم البسيطة، والتي اصبحت الآن عامة في لغات البرمجة. المفهوم الأول هو نوع البيانات data type. النوع يحدد القيم التي يمكن للمتغيرات ان تتخذها، والعمليات التي يمكن انجازها عليها. ان مفهوم النوع أقوى في باسكال مقارنة بلغة س، حيث انواع البيانات الحسابية غالبا ما تكون متبدلة، وهي أقوى بكثير من النسخ الأصلية للغة بيسك، حيث لاتملك مثل هذا المفهوم.
المتغيرات
تتطلّب باسكال ان تكون كل المتغيرات معرّفة قبل استخدامها. وحتى في الوقت الذي تعرّف فيه المتغير، يجب أن تحدّد نوع البيانات. ها هنا بعض نماذج تعريف المتغيرات:
var
Value: Integer;
IsCorrect: Boolean;
A, B: Char;
المصطلح var يمكن استخدامه في اماكن مختلفة في الكود، كأن يكون في بداية توليف وظيفة أو اجراء، او ان يتم تعريف المتغيرات محليا local في الروتين ، أو داخل الوحدة لتعريف متغيرات جامعة global. بعد مصطلح var تأتي قائمة اسماء المتغيرات، متبوعة بشارحة واسم نوع البيانات. يمكنك كتابة اكثر من اسم متغير واحد في السطر الواحد، كما هو في آخر تعليمة أعلاه.
حالما تقوم بتحديد متغير من نوع ما، تستطيع ان تقوم فقط بمباشرة العمليات الداعمة لنوع بياناته. على سبيل المثال، يمكنك استعمال القيمة البولية للاختبار و القيمة الصحيحة في التعبير الرقمي. لايمكنك مزج القيم البولية والصحيحة (كما هو الأمر مع لغة س).
باستخدام تخصيصات بسيطة، نستطيع كتابة التوليف التالي:
Value := 10;
IsCorrect := True;
لكن التعليمة التالية ليست صحيحة، لأن المتغيرين يملكان نوع بيانات مختلف:
Value := IsCorrect; // error
اذا حاولت تحويل هذا التوليف، فان دلفي تقوم باصدار خطأ تحويل رفق هذا التوضيح: Incompatible types: 'Integer' and 'Boolean'. عادة، مثل هذه الأخطاء هي أخطاء برمجية، لأنه لامعنى لتخصيص قيمة True أو False لقيم من نوع بيانات صحيح. يجب أن لا تلوم دلفي على مثل هذه الأخطاء. هي فقط تنبهك لوجود خطأ ما في التوليف.
بالطبع، غالبا مايمكن تبديل قيمة متغير من نوع بيانات الى نوع مختلف. في بعض الحالات، هذا التبديل يكون آليا، لكن عادة ما تحتاج الى استدعاء وظائف محددة في النظام لتغيير التمثيل الداخلي للبيانات.
تستطيع في دلفي ان تخصص قيمة تمهيدية لمتغير جامع global variable أثناء تعريفك له. مثلا، تستطيع كتابة:
var
Value: Integer = 10;
Correct: Boolean = True;
تقنية التمهيد initialization هذه تصلح فقط للمتغيرات الجامعة، وليس للمتغيرات المعرفة داخل نطاق اجراء أو مسار.
الثوابت
تسمح باسكال ايضا بتعريف ثوابتا constants لتسمية القيم التي لاتتغير خلال عمل البرنامج. لتعريف ثابت لاتحتاج لتحديد نوع البيانات، فقط تخصيص قيمة ابتدائية. المحوّل سيتفحّص القيمة وآليا يستخدم نوع بياناته المناسب. ها هنا بعض امثلة التعريفات:
const
Thousand = 1000;
Pi = 3.14;
AuthorName = 'Marco Cantù';
يقرر دلفي نوع البانات للثابت بناء على قيمته. في المثال أعلاه، الثابت Thousand يفترض ان يكون من نوع صحيح صغير SmallInt ، اصغر نوع صحيح يمكنه احتواء القيمة. اذا اردت الطلب من دلفي استخدام نوع محدد؛ يمكنك ببساطة اضافة اسم النوع في التعريف، كما هو في:
const
Thousand: Integer = 1000;
عندما تقوم بتعريف ثابت، يستطيع المحوّل أن يختار بين أن يخصص موقعا في الذاكرة للثابت، و يحفظ فيه قيمته، أو أن ينسخ قيمته الحقيقية في كلّ مرة يتم فيها استعمال الثابت. الأسلوب الثاني يبدو معقولا خاصة بالنسبة للثوابت البسيطة.
ملاحظة: نسخ 16-بت من دلفي تسمح لك بتغيير قيمة الثابت محدد النةع في زمن التشغيل، كما لو كان متغيرا. نسخة 32-بت لازالت تسمح بهذا السلوك من اجل التوافقية مع السابق وذلك عندما تقوم بتمكين موجّه المحوّل $J ، او بالتعليم على مؤشر Assignable typed constants في صفحة المحوّل في نافذة خيارات المشروع Project Options . وبالرغم من أن هذا هو التوصيف الافتراضي، فانه ينصح بقوة كفنيّات البرمجة أن لاتستعمل هذه الخدعة. ان تخصيص قيمة جديدة لثابت يمنع كل تشذيبات المحول على الثواب. واذا اضطررت لهذا، ببساطة قم بتعريف متغيرات، كبديل.
ثوابت الجمل الموردية
عندما تحدد ثابت جملة، فبدلا من كتابة:
const
AuthorName = 'Marco Cantù';
يمكنك بدءاً من دلفي 3 أن تكتب التالي:
resourcestring
AuthorName = 'Marco Cantù';
في كلتا الحالتين انت تحدد ثابتا؛ قيمة لاتقم بتغييرها خلال زمن التشغيل. الفرق فقط في كيفية الانجاز. ثابت الجملة المحدد بواسطة الموجّه resourcestring يخزّن ضمن موارد البرنامج resources، في جدول للجمل.
لكي ترى هذه الامكانية فعليا، قم بالاطلاع على مثال ResStr ، والذي له زرّا رفق التوليف التالي:
resourcestring
AuthorName = 'Marco Cantù';
BookName = 'Essential Pascal';
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage (BookName + #13 + AuthorName);
end;
ناتج الجملتين يظهر في سطرين منفصلين لأن الجملتين مفصولتين بالحرف الدّال لسطر جديد newline (مشار اليه بقيمته الرقمية في #13 وهو ثابت نوع حرف).
الجانب المثير في هذا البرنامج هو انك اذا تفحصّته بمستكشف للموارد resource explorer (هناك واحد متوفر في الأمثلة التي تأتي مع دلفي) سوف ترى الجمل الجديدة ضمن الموارد. هذا يعني بأن الجمل ليست جزءا من التوليف المحول ولكنها خزّنت في منطقة منفصلة في الملف التنفيذي (ملف EXE).
ملاحظة: باختصار، مزايا الموارد هي في الكفاءة في مناولة الذاكرة التي تقوم بها ويندوز، وفي امكانية توطين localizingالبرنامج (ترجمة الجمل الى لغات مختلفة) بدون الحاجة الى تعديل توليفها المصدري source code.
أنواع البيانات
في باسكال توجد عدة انواع بيانات سابقة التحديد predefined data types ، والتي يمكن تقسيمها الى ثلاث مجموعات: الانواع التراتبية ordinal types، الأنواع الحقيقية real types و الجمل strings. سوف نناقش الانواع التراتبية في الأقسام التالية، بينما يتم تغطية الجمل لاحقا في هذا الفصل. في هذا القسم سوف أقدم ايضا بعض الأنواع المحددة من قبل مكتبات دلفي (ليست محددة من قبل المحوّل)، والتي يمكن اعتبارها انواع سابقة التحديد predefined types.
تتضمن دلفي ايضا نوع بيانات بدون نوع non-typed ، تسمّى متباين variant ، سيتم مناقشتها في الفصل العاشر من هذا الكتاب. غريب جدا ان يكون المتباين نوعا بدون مايناسبه من تحقق من النوع. لقد تم ادخال هذا النوع في دلفي 2 لمناولة آليات او ال اي OLE Automation.
الأنواع التراتبية
الأنواع التراتبية Ordinal types مبنية على مفهم الترتيب أو التوالي و التتابع. ليس بامكانك فقط مقارنة قيمتين لمعرفة أيهما الأكبر، ولكن يمكنك أيضا معرفة القيمة التي تلي او تسبق قيمة أخرى، أو تقوم بحساب أدني أو أعلى قيمة محتملة.
أكثر ثلاث أنواع تراتبية سابقة التحديد هي الصحيح Integer، البولي Boolean، و الحرف Char. عموما، هناك عددا من الأنواع الأخرى ذات العلاقة والتي لها معنى مشابها ولكن لها تمثيلا ومدى قيم مختلفين. جدول 3.1 التالي يعرض انواع البيانات التراتبية المستخدمة لتمثيل الأرقام.
جدول 3.1: أنواع البيانات التراتبية للأرقام
http://www.shabwh.com/up//uploads/images/shabwh7479408598.gif (http://www.shabwh.com/up//uploads/images/shabwh7479408598.gif)
كما ترى، هذه الأنواع لها علاقة بالتمثيلات المختلفة للأرقام، حسب عدد الجزئيات bits المستخدمة للتعبير عن القيمة، وحسب وجود أو غياب جزئية العلامة. القيم المعلّمة signed values يمكنها أن تكون موجبة أو سالبة، لكن لها مدى أصغر من القيم، وذلك لأن المتاح من الجزئيات للقيمة نفسها قد نقصت بواحدة. تستطيع أن ترجع الى مثال المدى الذي سيناقش في القسم التالي، من أجل معرفة المدى الفعلي لقيم كل نوع.
المجموعة الأخيرة (والمشارة ب 16/32) تشير الى القيم التي لها تمثيلا مختلفا في نسخ 16-بت و 32-بت من دلفي. الصحيح Integer و الرئيسي Cardinal يستعملان بكثرة، لأنهما يطابقان التمثيل الفطري للأرقام في المعالج الحسابي CPU.
الأنواع الصحيحة في دلفي 4
في دلفي 3، الأرقام ذات 32 بت غير المعّلمة والمشار اليها بنوع رئيسي cardinal كانت سابقا قيم 31 بت، بمدي يبلغ حتى 2 قيقابايت. قدمت دلفي 4 نوع جديد رقمي غير معلّم، LongWord ، والذي يستخدم فعليا قيمة 32 بت تبلغ حتى 4 قيقابايت. وأصبح نوع كاردينال الآن اسما مرادفا لنوع لونغوورد الجديد. لونغوورد يسمح ب 2GB اكثر اضافية من البيانات يمكن عنونتها من قبل رقم غير معّلم، كما أشير اليه سابقا. أكثر من هذا، فإنه يماشي التمثيل الفطري للأرقام في المعالج الحسابي.
نوع آخر جديد تم ادخاله في دلفي 4 و نوع int64 ، والذي يمثل أعدادا صحيحة تبلغ 18 رقم. هذا النوع الجديد مدعوم بالكامل من قبل بعض اجرائيات routines الأنواع التراتبية (مثل High و Low)، والإجرائيات الرقمية (مثل Inc و Dec)، وإجرائيات تبديل الجمل string-conversion (مثل IntToStr). ومن أجل التبديل العكسي، من جملة ألى رقم، هناك وظيفتين جديدتين: StrToInt64 و StrToInt64Def.
البولي
القيم البولية غير النوع البولي نادرة الاستعمال. بعض القيم البولية لديها تمثيل خاص وذلك لمتطلبات وظائف ويندوز Windows API functions. الأنواع هي ByteBool، WordBoolو LongBool.
في دلفي 3 ومن أجل التوافق مع فيجوال بيسك و آليات OLE، فان انواع البيانات ByteBool، WordBool، و LongBool تم تعديلهم لتمثيل القيم True بـ -1، بينما القيمة False لازالت 0. نوع البيانات Boolean ظلّت كما هي (True هي 1، , False هي 0). إذا قمت باستعمال سبك نوع typecast صريح في برنامج بدلفي 2، فإن نقل البرنامج الى نُسخ لاحقة من دلفي قد ينتج عنه بعض الأخطاء.
الأحرف
أخيرا هناك تمثيلين مختلفين للأحرف: ANSIChar و WideChar. النوع الأول يمثل أحرفا ذات جزئيات ثمان 8-bit، تتماشى مع مجموعة أحرف انسي ANSI والمستخدمة تقليديا من قبل ويندوز؛ التمثيل الثاني الأحرف 16-جزئية ، وتتماشى مع أحرف يونيكود الجديدة Unicode والمدعومة بالكامل من قبل ويندوز ن ت، وجزئيا من قبل ويندوز 95 و 98. معظم الوقت سوف تستعمل ببساطة نوع حرف Char ، والذي في دلفي 3 تطابق ANSIChar. ليكن معلوما، على أي حال، ان أول 256 من حروف يونيكود توافق تماما حروف انسي ANSI.
أحرف الثوابت يمكن تمثيلها بمجموعة رموزها، كما في 'k'، او بمجموعة أرقامها، كما في #78. الأخيرة يمكن التعبير عنها ايضا ياستخدام الوظيفية Chr ، كما في Chr (78). التبديل المعاكس يمكن اجراؤه بواسطة الوظيفة Ord.
بصفة عامة يكون من الأحسن استخدام مجموعة الرموز عند الإشارة الى الأحرف، والأرقام، والعلامات. عند الإشارة الى أحرف خاصة، ستستخدم مجموعة الأرقام عموما بدلا من ذلك. القائمة التالية تتضمن بعض أكثر الأحرف الخاصة استعمالا:
#9 tabulator جدولة
#10 newline سطر جديد
#13 carriage return (enter key) مفتاح الإدخال
مثال Range
لإعطائك فكرة عن الاختلاف من مدى لآخر في بعض الأنواع التراتبية، قمت بكتابة برنامج دلفي بسيط أسميته Range. بعض النتائج تظهر في الشكل 3.1.
الشكل 3.1: مثال Range يظهر بعض المعلومات حول انواع البيانات التراتبية (الأرقام الصحيحة في هذه الحالة).
http://www.shabwh.com/up//uploads/images/shabwh192e7f5d1f.gif (http://www.shabwh.com/up//uploads/images/shabwh192e7f5d1f.gif)
برنامج Range مبني على نموذج form بسيط، به ستة أزرار buttons (كلّ مسمّاة حسب نوع البيانات التراتبية) وبعض الملصقات labels لمختلف المعلومات، كما هو مبيّن في الصورة 3.1. أستخدمت بعض الملصقات لتحوي نصّا ثابتا، الأخرى لعرض المعلومات عن النوع في كلّ مرّة يُضغط فيها على زرّ.
في كلّ مرّة تضغط فيها على الأزرار، يقوم البرنامج بتحديث الملصقات بحسب الناتج. ملصقات مختلفة تعرض نوع البيانات، عدد البايت المستعملة، و أقصى وأدني قيمة يمكن للنوع أن يخزّنها. كل زرّ يملك مايخصّه من مسار method تجاوب الحدث OnClick لأن التوليف المستخدم لحساب القيم الثلاث يختلف قليلا من زرّ لآخر. مثلا، هاهنا التوليف المصدري لحدث OnClick للزرّ الخاص بنوع الصحيح (BtInteger):
procedure TFormRange.BtnIntegerClick(Sender: TObject);
begin
LabelType.Caption := 'Integer';
LabelSize.Caption := IntToStr (SizeOf (Integer));
LabelMax.Caption := IntToStr (High (Integer));
LabelMin.Caption := IntToStr (Low (Integer));
end;
إذا كنت تملك بعض الخبرة في البرمجة بدلفي، يمكنك تفحّص التوليف لفهم كيفية عمله. بالنسبة للمبتدئين، يكفي ملاحظة الإستخدام للوظائف الثلاثة: SizeOf وHigh و Low. نواتج الوظيفتين الأخيرتين هما تراتبيات من نفس النوع (في هذا الحالة، أعداد صحيحة)، وناتج وظيفة SizeOf هي دائما عدد صحيح. القيمة المرتجعة من هذه الوظائف الثلاث تترجم أولا إلى جُمل بإستخدام وظيفة IntToStr، ثم تُنسخ في لافتات captions الملصقات الثلاث.
المسارات المرتبطة بالأزرار الأخرى تشبه كثيرا المسار المذكور أعلاه. الإختلاف الفعلي الوحيد هو نوع البيانات الذي تم تمريره كمحدد لمختلف الوظائف. الصورة 3.2 تعرض ناتج تنفيذ البرنامج تحت ويندوز 95 بعد أن تم إعادة تحويله recompile بواسطة نسخة 16-بت من دلفي. بمقارنة الشكل 3.1 و الشكل 3.2، يمكنك رؤية الإختلاف بين نوع البيانات الصحيح ذو 16-بت وذلك ذو 32-بت.
الشكل 3.2: ناتج نسخة 16-بت من مثال Range، يعرض مرّة أخرى معلومات عن العدد الصحيح.
http://www.shabwh.com/up//uploads/images/shabwh03fbf072e0.gif (http://www.shabwh.com/up//uploads/images/shabwh03fbf072e0.gif)
حجم نوع الصحيح Integer يتباين بحسب المعالج الحسابي ونظام التشغيل المستخدم. في ويندوز 16-بت، المتغير الصحيح يسع 2 بايت. بينما في ويندوز 32، سعة الصحيح 4 بايت. لهذا السبب، عندما تعيد تحويل مثال Range، ستحصل على نتائج مختلفة.
التمثيلين المختلفين لنوع الصحيح ليست بمشكلة، طالما أن برنامجك لايضع أية إفتراضات عن حجم الصحيح. إذا ما حدث وقمت بحفظ عدد صحيح في ملف بإستخدام نسخة ثم حاولت استرجاعه بنسخة أخرى، فسوف تواجه بعض المتاعب. في هذه الحالة، يجب أن تختار نوع بيانات مستقل عن بيئة التشغيل (مثل LongInt أو SmallInt). لأغراض الحسابات الرياضية أو توليف عام، أفضل مراهنة لديك هو أن تلتزم تمثيل الصحيح النمطي لبيئة التشغيل المعينة-- هذا يعني، ان تستخدم نوع الصحيح-- لأنه المفضّل لدى المعالج الحسابي. نوع الصحيح Integer يجب أن يكون خيارك الأول عندما تعالج أعدادا صحيحة. و لا تستخدم تمثيلا مختلفا إلا إذا وجدت سببا قاهرا لذلك.
إجرائات الأنواع التراتبية
بعض إجرائيات النظام system (إجرائيات محددة في لغة باسكال وفي وحدة النظام في دلفي system unit)يمكنها تتعامل مع الأنواع التراتبية ordinal types. هي معروضة في الجدول 3.2. المبرمجون بلغة س++ سوف يلاحظون بأن النسختين من إجرائية Inc، مع محدد أو اثنين، يطابقان معاملات ++ و += (نفس الأمر مع إجرائية Dec).
الجدول 3.2: إجرائيات نظام للأنواع التراتبية
http://www.shabwh.com/up//uploads/images/shabwh5afcd96e3f.gif (http://www.shabwh.com/up//uploads/images/shabwh5afcd96e3f.gif)
لاحظ ان بعض هذه الإجرائيات، عندما يتم تطبيقها على الثوابت constants، فإن المحوّل يقوم بتقييمها آليا واستبدالها بقيمتها. مثلا اذا قمت باستدعاء High(X) حيث X معرّفة كصحيح، فالمحوّل يستطيع ببساطة تبديل التعبير بآخر يمثل أعلى قيمة محتملة لنوع بيانات الصحيح.
الأنواع الحقيقية
تقوم الأنواع الحقيقية بتمثيل أرقام النقطة العائمة بعدة أشكال. أصغر حجم تخزين تمثلها الأرقام الوحيدة Single ، والتي تنفذ بقيمة ذات 4-بايت. ثم هناك الأرقام النقطة العائمة المضاعفة Double، المنفذة بعدد 8 بايت، والأرقام الممتدّة Extended ، والمنجزة بعدد 10 بايت. كل هذه أنواع بيانات نقطة عائمة مع اختلاف في الضبط والدقة precision.
في دلفي 2 ودلفي 3 نوع الحقيقي Real له نفس التعريف الذي في نسخة 16-بت؛ لقد كانت بنوع 48-بت. لكن تم تخفيض استخدامه من قبل بورلاند، والتي اقترحت بأن تقوم باستعمال أنواع الوحيد والمضاعف والممتد بدلا منه. سبب اقتراحهم هذا هو ان الشكل القديم ذو 6-بايت ليس مدعوما من قبل معالجات انتل Intl كما انه ليس معروضا ضمن القائمة الرسمية للأنواع الحقيقية والتي اصدرتها IEEE. ولكي يتم تلافي المشكلة تماما، قامت دلفي 4 بتعديل التعريف الخاص بنوع الحقيقي حتى يمثل الشكل القياسي لرقم عائم النقطة ذو 8 بايت (64-بت).
بالإضافة إلى ميزة استخدام تعريفا قياسيا متفق عليه، هذا التغيير يسمح للمكونات components باصدار سمات properties مبنية عل نوع حقيقي، الشيء الذي لم يكن دلفي 3 يسمح به. أما العيوب فقد تبرز مشاكل التوافقية. في حالة الضرورة، وعند الاصرار على طريقة دلفي 2 و 3 في تعريف النوع، يمكنك تجاوز احتمال انعدام التوافقية؛ وذلك باستخدام خيار المجمّع التالي:
{$REALCOMPATIBILITY ON}
هناك أيضا نوعان غريبان من أنواع البيانات: Comp ويصف رقم صحيح كبير جدا باستخدام 8 بايت (والذي يمكنه احتواء ارقام ذات 18 خانة عشرية)؛ و Currency عملة (ليست متوفرة في دلفي 16-بت) وهي تشير الى قيمة بنقطة عشرية ثابتة مع اربع خانات عشرية، و بنفس تمثيل 64-بت كما في نوع Comp. كما يوحي الإسم، نوع بيانات عملة Currency أضيف لمناولة القيم النقدية شديدة الدقة، مع أربع خانات عشرية.
لا نستطيع بناء برنامج يشبه مثال Range بتطبيق انواع بيانات حقيقية، لأننا لايمكننا استخدام وظائف High و Low أو Ord مع متغيرات نوع حقيقي. الأنواع الحقيقية تمثل (نظريا) مجموعة لانهائية من الأرقام، بينما الأنواع التراتبية تمثل مجموعة ثابتة من القيم.
ملاحظة: دعوني أشرح ذلك بطريقة أفضل. عندما يكون لديك الرقم الصحيح 23، يمكنك أن تقرّر ماهي القيمة التي تليه. الأرقام الصحيحة نهائية (لديها مدى محدد ولديها ترتيب). الأرقام عائمة النقطة هي غير نهائية حتى ضمن المدى القصير، وليس لديها ترتيب: في الواقع، كم توجد قيمة بين 23 و 24 ؟ و ما هو الرقم الذي يلي 23.46 ؟ هل هو 23.47، 23.461، أو 34.4601 ؟ هذا الأمر يصعب معرفته بالفعل.
لهذا السب، يبدو الأمر معقولا حين نسأل عن ترتيب موضع حرف w ضمن مدى نوع بيانات حرف char، و لكن ليس من المعقول ابدا أن نسأل نفس السؤال عن الرقم 7143.1562 ضمن مدى نوع بيانات النقطة العائمة. بالرغم انه بالتأكيد تستطيع معرفة ما إذا كان ;رقم حقيقي ما لديه قيمه أعلى من قيمة رقم آخر، فإنه من غير المنطقي أن نسأل عن عدد الأرقام الحقيقية الموجودة قبل رقم ما (هذا معني وظيفة Ord).
الأنواع الحقيقية لديها دورا محدودا في ذلك الجزء من التوليف البرمجي الخاص بواجهة المستخدم user interface (الجانب الخاص بويندوز)، لكنها مدعومة بالكامل من قبل دلفي، بما في ذلك جانب قواعد البيانات. ان دعم مواصفات IEEE القياسية لأنواع النقطة العائمة تجعل من لغة اوبجكت باسكال مناسبة تماما لنطاق واسع من البرامج التي تتطلب حسابات رقمية. إذا كنت مهتما بهذا الجانب، يمكنك إلقاء نظرة على الوظائف الرياضية المقدمة من دلفي وذلك في ملف وحدة system (انظر Delphi Help من أجل تفاصيل أكثر).
ملاحظة: لدلفي ايضا ملف وحدة Math التي تحدد إجرائيات رياضية أكثر تقدما، تغطي وظائف حساب المثلثات (مثل وظيفة ArcCosh)، مالية (مثل وظيفة InterestPayment)، و إحصائية (مثل إجرائية MeanAndStdDev). هناك العديد من هذه الإجرائيات، بعضها تبدو غريبة بالفعل بالنسبة لي، مثل إجرائية MomentSkewKurtosis (سأدع هذا الأمر لك لمعرفته) .
التاريخ والوقت
تستخدم دلفي أيضا أنواعا حقيقية real types لمناولة معلومات التاريخ والوقت. وليكون الأمر أكثر دقّة حدّدت دلفي نوع بيانات TDateTime. وهو نوع نقطة عائمة، لأن النوع يجب أن يكون واسعا بما يكفي لإحتواء السنوات، الأشهر، الأيام، الساعات، الدقائق، والثواني، نزولا إلى دقة تبلغ جزء من ألف من الثانية، كلّ ذلك في متغير واحد. التواريخ تخزّن كإجمالي عدد الأيام منذ 12/30/1899 (مع قيم سالبة تشير إلى التواريخ ما قبل 1899) في الجزء الصحيح integer من قيمة TDateTime.
نوع TDateTime ليس نوعا مسبق التحديد بحيث يفهمه المحوّل، لكن قد تمّ تعريفه في ملف وحدة system كالتالي:
type
TDateTime = type Double;
إستخدام TDateTime يعدّ بسيط، لأن دلفي تحوي عددا من الوظائف التي تتعامل مع هذا النوع. يمكنك أن تجد قائمة بهذه الوظائف في الجول 3.3.
الجدول 3.3: إجرائيات نظام لنوع TDateTime
http://www.shabwh.com/up//uploads/images/shabwh94c4f5036f.gif (http://www.shabwh.com/up//uploads/images/shabwh94c4f5036f.gif)
من أجل أن ترى كيف يتم استعمال نوع البيانات هذا و بعض الإجرائيات الخاصة به، قمت ببناء برنامج بسيط، أسميته TimeNow. النموذج الرئيسي في هذا المثال به زرّ Button و قائمة ListBox. عندما يبدأ البرنامج يقوم آليا بحساب وعرض الوقت والتاريخ الحالي. في كلّ مرّة يتم فيها الضغط على الزرّ، يقوم البرنامج بعرض الزمن المنقضي منذ بدء البرنامج.
فيما يلي التوليف الموصول بحدث OnCreate الخاص بالنموذج:
procedure TFormTimeNow.FormCreate(Sender: TObject);
begin
StartTime := Now;
ListBox1.Items.Add (TimeToStr (StartTime));
ListBox1.Items.Add (DateToStr (StartTime));
ListBox1.Items.Add ('Press button for elapsed time');
end;
التعليمة الأولى تنادي وظيفة Now ، التي تسترجع التاريخ و الوقت الحاليين. القيمة المسترجعة تُخزّن في متغيّر StartTime ، والذي تم تعريفه كمتغير خارجي global كالتالي:
var
FormTimeNow: TFormTimeNow;
StartTime: TDateTime;
لقد أضفت فقط التعريف الثاني، حيث أن دلفي تقوم بتوفير الأول. حيث يكون مبدئيا كالتالي:
var
Form1: TForm1;
عند تغير اسم النموذج form، يتم تحديث هذا التصريح آليا. ان استخدام متغيرات جامعة global لا يعدّ حقيقة أفضل الطرق: سيكون من الأفضل لو تم استخدام حقل خاص private field تابع لطبقة النموذج form class، موضوع له علاقة ببرمجة التوجّه الكائني object-oriented programming تم مناقشته في كتاب التحكم بدلفي 4 Mastering Delphi .
التعليمات الثلاث التالية تضيف ثلاثة عناصر الى مكوّن القائمة يمين النموذج، مع النتائج التي تراها في الشكل 3.3. السطر الأول يحتوي على الجزء الخاص بالوقت في قيمة TDateTime محوّلا الى جملة، الثاني يحتوي جزء التاريخ من نفس القيمة. في نهاية التوليف أضيف تذكير بسيط.
الشكل 3.3: ناتج مثال TimeNow عند البدء.
http://www.shabwh.com/up//uploads/images/shabwh0c2dbd6dc1.gif (http://www.shabwh.com/up//uploads/images/shabwh0c2dbd6dc1.gif)
الجملة الثالثة يستبدلها البرنامج عندما يضغط المستعمل على زرّ Elapsed "المنقضى":
procedure TFormTimeNow.ButtonElapsedClick(Sender: TObject);
var
StopTime: TDateTime;
begin
StopTime := Now;
ListBox1.Items [2] := FormatDateTime ('hh:nn:ss',
StopTime - StartTime);
end;
التوليف يسترجع الوقت الجديد ويحسب الفرق بينه وبين قيمة الوقت المخزّن عند ابتداء البرنامج. ولأننا نحتاج الى استخدام القيمة التي سبق حسابها في سياق حدث مختلق، كان علينا أن نخزّنها في متغير جامع. في الواقع توجد بدائل أفضل، مبنية على مفهوم الطبقات classes.
ملاحظة: التوليف الذي يقوم باستبدال القيمة الحالية في الجملة الثالثة يستعمل دليل index 2. السبب في ذلك ان بنود القائمة مبنية على الصفر are zero-based: البند الأول رقمه 0، الثاني رقم 1، و الثالث رقم 3. سنرى المزيد من ذلك عندما نناقش المصفوفات.
بجانب استدعاء DateToStr و TimeToStr يمكنك استعمال وظيفة FormatDateTime الأكثر قوة، كما فعلت في المسار method الأخير أعلاه (انظر ملف مساعدة دلفي من أجل تفاصيل محددات الصياغة). لاحظ أيضا أن قيم الوقت والتاريخ تُبدّلان إلى جُمل بحسب توصيف الدوليّات international في ويندوز. دلفي يقرأ هذه القيم من النظام، و يوزعها في عدد من الثوابت الجامعة global constants المُعرّفة في ملف وحدة SysUtils. نذكر منها:
DateSeparator: Char;
ShortDateFormat: string;
LongDateFormat: string;
TimeSeparator: Char;
TimeAMString: string;
TimePMString: string;
ShortTimeFormat: string;
LongTimeFormat: string;
ShortMonthNames: array [1..12] of string;
LongMonthNames: array [1..12] of string;
ShortDayNames: array [1..7] of string;
LongDayNames: array [1..7] of string;
يوجد المزيد من الثوابت الجامعة تتعلق بالعُملة و صياغة رقم النقطة العائمة. يمكنك الحصول على قائمة كاملة بها من ملف مساعدة دلفي تحت العنوان Currency and date/time formatting variables.
انواع ويندوز الخاصة
أنواع البيانات السابقة التحديد والتي سبق أن استعرضناها حتى الآن هي جزء من لغة باسكال. تتضمن دلفي أنواع بيانات أخري مجددة من قبل ويندوز. أنواع البيانات هذه ليست جزءاً مكمّلا في اللغة، ولكنها جزءا من مكتبات libraries ويندوز. أنواع ويندوز تتضمن أنواع ابتدائية جديدة (مثل DWORD و UINT)، و العديد من التسجيلات records (أو بنيات structues)، و عددا من الأنواع المؤشّرة pointer، وغيرها.
من بين أنواع بيانات ويندوز، فإن النوع الأكثر أهمية تمثله المماسك handles، الفصل 9 يناقش ذلك.
تلبيس النوع و تحويلات النوع
كما رأينا، لا يمكنك تخصيص متغير لآخر من نوع مختلف. إذا أردت ذلك، يوجد خياران. الخيار الأول هو تلبيس النوع typecasting ، والذي يستخدم رمز وظائفي بسيط ، باسم نوع البيانات المطلوب:
var
N: Integer;
C: Char;
B: Boolean;
begin
N := Integer ('X');
C := Char (N);
B := Boolean (0);
يمكنك التلبيس بين أنواع البيانات ذات نفس الحجم. عادة مايكون الأمر مأمونا عند التلبيس بين الأنواع التراتبية، أو بين الأنواع الحقيقية، ولكن يمكنك التلبيس بين أنواع مؤشّرة pointer (وأيضا الكينونات objects) طالما تكون مدركا لما تفعله.
التلبيس، بصفة عامة، عادة برمجية خطيرة، لأنه يسمح لك بالوصول إلى قيمة كما لو أنها ممثلة بشكل آخر. و طالما ان التمثيلات الداخلية لأنواع البيانات عموما غير متجانسة، فأنت تخاطر بالتسبب بأخطاء صعبة التتبع. لهذا السبب، يجب عليك عموما تجنب عمليات تلبيس النوع.
الخيار الثاني هو استخدام إجرائيات تحويل النوع. الإجرائيات الخاصة بمختلف أنواع التحويلات تم تلخيصها في الجدول 3.4. بعض هذه الإجرائيات تعمل مع أنواع بيانات سيجري الحديث عنها في الأقسام التالية. لاحظ ان الجدول لا يحوي الإجرائيات الخاصة بالأنواع الخاصة (مثل TDateTime أو المتبياين variant) أو الإجرائيات الموجّه خصّيصا للتشكيل والصياغة formating، مثل الإجرائيات الفعّالة Format و FormatFloat.
جدول 3.4: إجرائيات النظام الخاصة بتحويل البيانات
http://www.shabwh.com/up//uploads/images/shabwh383381d592.gif (http://www.shabwh.com/up//uploads/images/shabwh383381d592.gif)
ملخّص
في هذا الفصل استكشفنا المفهوم الأساسي للنوع في باسكال. لكن اللغة لديها ميزة أخرى مهمة جدا: انها تسمح للمبرمجين بتعريف أنواع بيانات جديدة خاصة، تدعى بأنواع البيانات المحددة بالمستعمل user-defined data types. هذا هو موضوع الفصل التالي.
الفصل التالي: أنواع البيانات المحدّدة بالمستعمل.....
انتظرو الفصل القادم قريبا الأمثلة المذكورة في الدروس موجود عنها نسخ في المرفقات ارجوا ان اكون اوفيت الشرح انتظرو بقية الفصول
قريباً
اخواتي هذه مجموعة دروس في تعلم لغة الباسكال...
الفصل 1
تاريخ باسكال
لغة اوبجيكت باسكال (Opject Pascal) التي نستخدمها في دلفي لم يتم اختراعها في 1995 مع ظهور بيئة البرمجة المرئية لبورلاند. هي ببساطة امتداد للغة اوبجيكت باسكال التى كانت موجودة في منتجات باسكال السابقة لبورلاند. الا ان بورلاند لم تقم بابتكار باسكال، ولكنها فقط ساعدت على جعلها اكثر شعبية كما طورتها قليلا..
هذا الفصل سوف يحوي خلفية تاريخية عن لغة باسكال وتطورها. في الوقت الحالي سيتضمن فقط نُبذ قصيرة جدا.
باسكال ويرذ
تم تصميم لغة باسكال في الأصل سنة 1971 من قبل نيكلوس ويرذ (Niklaus Wirth)، البروفيسور في معهد زيوريخ التقني بسويسرا. وصممت باسكال بحيث تكون نسخة مبسطة لأغراض تعليمية من لغة أخرى هي الكول Algol ، التي يرجع تاريخها الى 1960.
عندما تم تصميم باسكال، كانت توجد العديد من لغات البرمجة الأخرى، لكن القليل منها الذي انتشر استعماله: فورتران، س، اسيمبلر، كوبول. الفكرة الرئيسية في اللغة الجديدة كانت التنظيم. أي أن تكون لغة منظمة من خلال مفهوم قوي لأنواع البيانات، و الزام وجود تعريفات مسبقة، وتحكمات هيكلية للبرنامج. كما تم تصميم اللغة ايضا لتكون اداة تعليمية للطلبة في فصول البرمجة.
تربو باسكال
محول باسكال الأكثر شهرة عالميا من بورلاند ، يدعى تربو باسكال Turbo Pascal ، تم تقديمه في 1983، مراعيا فيه تنفيذ كتاب "دليل المستخدم والتقارير لباسكال" لكل من جينسن و ويرذ،. وقد اصبح محول تربو باسكال احد اكثر المحولات مبيعا، واكسب اللغة شعبية خاصة بيئات الحواسيب الشخصية، ويرجع الفضل في ذلك الى الموائمة بين البساطة والقوة.
قدم تربو باسكال بيئة تطوير متكاملة (IDE) حيث يمكنك كتابة البرنامج (في محرر نصوص متوافق مع وورد ستار) ، ثم تقوم بتشغيل المحوّل، تتطّلع عل الاخطاء، تقفز مباشرة للعودة لأسطر البرنامج التي تحوي هذه الأخطاء. قد يبدو هذا شيئا عاديا الآن، لكن في السابق كان عليك ان تغلق محر النصوص الذي فيه برنامجك، تعود الى دوس؛ تقوم بتشغيل المحول ذو الأوامر السطرية، تكتب الأخطاء التي تظهر في ورقة خارجية، تعود لفتح محرر النصوص من جديد لتبحث فيه.
أكثر من هذا؛ قامت بورلاند ببيع تربو باسكال بسعر 49 دولار، في الوقت التي كانت فيه ميكروسفت تبيع محول الباسكال الخاص بها ببضع مئات. وقد كان لنجاح تربو باسكال على مدى سنوات الأثر في قرار ميكروسفت بوقف انتاجها لمحول باسكال الخاص بها.
باسكال دلفي
بعد 9 اصدارات من محولات تربو وبورلاند باسكال، والتي من خلالها تطورت اللغة تدريجيا، اصدرت بورلاند دلفي في 1995، ناقلة بذلك باسكال الى لغة برمجة مرئية.
دلفي مدّت في لغة باسكال في عدة مجالات، حيث اضافت بعض الخصائص ذات الاتجاه الموضوعي object-oriented والتي تختلف عن بعض المذاقات الأخرى لأوبجكت باسكال، حتى عن تلك التي في محوّل Borland Pascal with Objects compiler.
الفصل التالي: البرمجة بباسكال
- - - تم التحديث - - -
قبل ان ننتقل الى موضوع كتابة تعليمات لغة باسكال، من المهم أن نلقي الضوء على بعض عناصر نمط كتابة التعليمات بباسكل. المسألة التي أودّ الإشارة اليها هنا كالتالي: بجانب قواعد اللغة، ما هي الكيفية التي يجب عليك اتباعها لكتابة التعليمات. لاتوجد اجابة واحدة على هذا السؤال، حيث ان الأسلوب الشخصي يمكنه ان يقرر عدة انماط. عموما، هناك بعض المبادئ التي تحتاج لمعرفتها فيما يخصّ وضع التعليقات، حالة الأحرف، المسافات و ما يسمّى بالطباعة الأنيقة pretty-printing . كمبدأ عام، الهدف من أي نمط للكتابة هي الوضوح. ان النمط و القالب الذي تختاره هو شكل من اشكال الاختزال، يشير الى الغرض من جزء ما من التعليمات البرمجية. و الأداة الرئيسية للوصول الى الوضوح هي وحدة النسق بغضّ النظر عن النمط الذي تختاره، كن متأكدّا بأنكّ ستتّبع نفس النسق عبر كامل المشروع البرمجي.
التعليقات
في باسكال، يتم ضمّ التعليقات في أقواس braces أو أقواس parentheses متبوعة بنجمة. دلفي تقبل ايضا نمط التعليقات المتبعة في س++ ، والتي يمكنها ان تمتد الى نهاية السطر:
{هذا تعليق}
(* هذا تعليق آخر *)
// هذا تعليق آخر يمتد حتى نهاية السطر
الشكل الأول أقصر و أكثر اتّباعا. الشكل الثاني كان مفضلا أكثر في اوربا بسبب عدم وجود رمز القوس السهمي في لوحات المفاتيح. الشكل الثالث من التعليقات تم استعارته من س++ و متوفر فقط في نسخ 32 بت من دلفي. التعليقات المحدودة بنهاية السطر مفيدة جدا للملاحظات القصيرة و لتلك الخاصة بسطر محدد في التوليف.
خلال سرد الأمثلة في هذا الكتاب سأحاول تعليم التعليقات بأحرف مائلة، (و الكلمات الرئيسية بالتغميق)، لتكون متسقة مع النمط الافتراضي للصياغة في دلفي.
وجود ثلاثة اشكال مختلفة من التعليقات يمكن ان يساعد في بناء تعليقات متداخلة. إذا اردت التعليق على مجموعة أسطر من برنامج من اجل وقفها، وهذه الأسطر تحوي بعض التعليقات السابقة، فإنك لاتستطيع استخدام نفس علامة التعليقات:
{ ... code
{comment, creating problems}
... code }
مع علامة تعليق ثانية، يمكنك كتابة التعليمات الآتية، و التي هي صحيحة:
{ ... code
//this comment is OK
... code }
لاحظ أن القوس المفتوح او القوس_نجمة اذا كان تليه علامة الدولار ($)، فسوف يتحول الى توجيه للمُجمّع compiler directive ، كما في {$X+}.
في الواقع، توجيهات المجمّع تعد تعليقات أيضا. مثال ذلك، {$X+ This is a comment} هي صحيحة. هي كلاهما توجيه و تعليق صحيحين، الا أن المبرمج المتعقل سوف يختار ان يفصل بين التوجيهات والتعليقات.
استخدام الأحرف العالية
مجمّع باسكال (بعكس اللغات الأخرى) يغضّ الطرف عن حالة الأحرف (عالية أو منخفضة). لذلك؛ فإن التعريفات التالية Myname ، MyName، myname، myName، و MYNAME كلها متساوية. بشكل عام، هذا يعدّ أمرا ايجابيا، ففي اللغات الحسّاسة لحالة الأحرف، العديد من الأخطاء اللغوية قد تحدث بسبب الإهمال في مراعاة حالة الأحرف.
ملاحظة: ربما الحالة الإستثناء الوحيدة لقاعدة حساسية الأحرف في باسكال هي: إجراء Register في حزمة المكونات، لابد لها أن تبدأ بحرف R العالي، وذلك للمحافظة على التوافقية مع C++ Builder.
إلا أنه توجد بعض السلبيات. أولا، يجب أن تنتبه لأن تكون هذه التعريفات متساوية بالفعل، لذا يجب أن تتجنب استعمالها كعناصر مختلفة. ثانيا، يجب أن تكون متّسقا قدر الامكان عند استخدامك للأحرف العالية، لتحسين مقروئية برنامجك.
توحيد استخدام حالة الأحرف ليس ملزما من قبل المجمّع، و لكنها عادة حسنة يحبّذ اتّباعها. الاسلوب المتبع هو تكبير الحرف الأول فقط من كل معرّّف identifier. و عندما يكون المعرّف مركّبا من عدة كلمات (لايمكنك حشر فراغ في المعرّف) ، فإن كل أول حرف من كل كلمة يجب أن يكون عاليا:
MyLongIdentifier
MyVeryLongAndAlmostStupidIdentifier
هناك حالات أخرى لايأبه لها المجمّع كالفراغات، و الأسطر الفارغة، و المسافات (tabs) التي تقوم بوضعها في البرنامج. كل هذه الحالات مجتمعة تسمّى بالفراغ الأبيض white space . الفراغات البيضاء تستخدم فقط لتحسين مقروئية البرنامج؛ و لا تؤثر في عملية التتجميع.
بعكس لغة بيسك BASIC ، فإن باسكال تسمح لك بكتابة تعليمة واحدة موزعة على عدة أسطر، فالتعليمة الطويلة يمكن تجزئتها لتكون في سطرين أو أكثر. السلبية الوحيدة (على الأقل بالنسبة لمبرمجى البيسك) لإمكانية أن تكون التعليمات في أكثر من سطر هي أنه عليك أن تتذكّر بأن تضع فاصلة منقوطة آخر كل تعليمة، أو بدقة أكثر، أن تفصل بين التعليمة والتي تليها. لاحظ أن القيد الوحيد هنا ان الجملة النصية الواحدة لايمكن مدّها لعدّة أسطر.
مرّة أخرى، لاتوجد قواعد ثابتة لاتستخدام الفراغات و التعليمات متعددة الأسطر، فقط بعض الأعراف:
محرّر نصوص دلفي له خطا عموديا تستطيع وضعه على بعد 60 أو 70 حرف. إذا استخدمت هذا الخطّ كمؤشر لتجنب تجاوزه، فإن برنامجك سوف يبدو أفضل عندما تقوم بطباعته على الورق. غير هذا فإن الأسطر الطويلة قد يتم تجزئتها من أي موضع حتى من منتصف الكلمة عند طباعة البرنامج.
عندما يكون للوظيفة أو الإجراء عدة محددات parameters ، فإن العادة المتّبعة هنا هي وضع هذه المحدّدات في سطر آخر.
تستطيع ترك سطر بكامله أبيضا (فارغا) قبل وضع أي تعليق أو ملاحظة، أو لتقسيم جزء كبير من التعليمات الى أجزاء أصغر. وحتى هذه الفكرة البسيطة بإمكانها تحسين مقروئية البرنامج، سواء على الشاشة أو عند طباعتها.
استخدم الفراغات لفصل محددات استدعاء وظيفة function call، وربما حتى فراغ قبل فتح الأقواس، ايضا حافظ على فراغات لفصل رموز العمليات في التعابير البرمجية. أنا أعلم أن بعض المبرمجين لن يوافقوا على هذه الفكرة، لكن أنا أصرّ: الفراغات بالمجان؛ لن تدفع شيئا مقابلها .(نعم، أعلم انها تستهلك مكانا للتخزين أو وقتا اضافيا في عملية اتصال الموديم لتحميل أو تنزيل ملف، لكن هذا أصبح لامعنى له في وقتنا الحاضر.)
الطباعة الأنيقة
الاقتراح الأخير فيما يخصّ استخدام الفراغات البيضاء له علاقة بالعرف المتبع لنسق تشكيل لغة باسكال، و الذي يعرف بالطباعة الأنيقة pretty-printing. القاعدة بسيطة: كل مرة تحتاج فيها لكتابة تعليمة مركّبة، قم بوضعها بعد هامش فراغين الى اليمين من باقي التعليمة الحالية. التعليمة المركبة داخل تعليمة أخرى مركبة يتم تهميشها بأربع مسافات، وهكذا:
if ... then
statement;
if ... then
begin
statement1;
statement2;
end;
if ... then
begin
if ... then
statement1;
statement2;
end;
الصياغة السابقة تعتمد نسق الطباعة الأنيقة، لكن المبرمجين لديهم تفسيرات مختلفة لهذه القاعدة العامة. بعض المبرمجين مثلا يقومون بتهميش تعليمات begin و end للمستوى التالي مع نفس التعليمات الداخلية، بعضهم يهمش begin و end ثم يقومون بتهميش التعليمات الداخلية لمستوى اضافي، مبرمجون آخرون يضعون begin في نفس سطر شرط if . هذا في معظمه أمر له علاقة بالذوق الشخصي.
نفس نمط التهميش يتّّبع عادة عند سرد المتغيرات أو أنواع الببيانات، و لمواصلة تعليمة من سطر سابق:
type
Letters = set of Char;
var
Name: string;
begin
{ long comment and long statement, going on in the
following line and indented two spaces }
MessageDlg ('This is a message',
mtInformation, [mbOk], 0);
بالطّبع، أي من هذه القواعد هي مجرّد إقتراح لجعل البرنامج مقروءا بشكل أفضل من قبل المبرمجين الآخرين، و هي تهمل بالكامل من جانب المجمّع. لقد حاولت استخدام هذه القاعدة بصورة متّسقة في كل اجزاء الأمثلة والبرامج في هذا الكتاب. كما يلاحظ أن البرامج، الأدلة، و أمثلة المساعدة التي تأتي مع دلفي كلها تتّبع نفس النسق في الصياغة.
تعليم الألفاظ
لتسهيل قراءة و كتابة توليف code باسكال، يملك محرر دلفي خاصية تسمّى تعليم الألفاظ syntax highlighting . فالكلمات التي تقوم بطباعتها في المحرر، يتم اظهارها باستخدام ألوان مختلفة بحسب معناها في باسكال. عرضا، الكلمات المفتاحية keywords تكون داكنة، النصوص و التعليقات تظهر ملونة (و غالبا مائلة)، وهكذا.
الكلمات المحجوزة، و التعليقات، و النصوص تقريبا هي العناصر الثلاثة الأكثر استفادة من هذه الخاصية. فمن أول نظرة يمكنك ملاحظة كلمة مفتاحية غير صحيحة، أو نصّ غير مقفل بصورة سليمة، أو طول الملاحظة المتعددة الأسطر.
بإمكانك بسهولة تعديل مواصفات تعليم الألفاظ باستخدام صفحة ألوان المحرر Editor page في لوحة خيارات البيئة Environment Options (انظر الشكل 2.1). إذا كنت تعمل بمفردك، يمكنك اختيار الألوان التي تفضل. أما إذا كنت تعمل بالتعاون مع مبرمجين آخرين، فالأفضل أن توافقوا جميعا على نسق ألوان نمطي. لقد وجدت ان العمل على حاسوب به تلوين الفاظ مختلف عمّا تعوّدت عليه أمر صعب بالفعل.
الشكل 2.1: لوحة الحوار المستخدمة لتحديد لون تعليم الألفاظ.
http://www.shabwh.com/up//uploads/images/shabwh3828939a86.gif (http://www.shabwh.com/up//uploads/images/shabwh3828939a86.gif)
استخدام قوالب اللغة
قدّمت دلفي 3 خاصيّة جديدة ذات علاقة بكتابة شفرة البرامج. عند كتابة تعليمات لغة باسكال تجد نفسك عادة ما تعيد كتابة نفس التتابع من الكلمات الرئيسية، لذلك قدمت بورلاند خاصية جديدة تسمّى قوالب اللغة Code Templates . قوالب اللغة هي ببساطة قطعة من توليف مرتبطة بمفاتيح مختصرة. حيث تقوم بكتابة النص المختصر ثم تتبعها بالضغط على Ctrl+j، فيظهر التوليف ذو العلاقة مكتوبا بالكامل. مثلا، اذا قمت بكتابة arrayd ، ثم ضغطت على Ctrl+j ، فان محرر دلفي سوف يوسع من النص المختصر الى التالي:
array [0..] of ;
و حيث ان قوالب التوليف المحددة سلفا عادة ما تأتي بنسخ مختلفة لنفس الاختصار، فان النص المختصر ينتهي عموما بحرف يشير الى النسخة التي قد تهمك. عموما يمكنك كتابة فقط جزء من النص المختصر. مثال ذلك، اذا كتبت ar ثم ضغطت على Ctrl+j ، يظهر المحرر قائمة تظهر الخيارت المتوفرة مع وصف موجز لكل اختصار، مثلما هو واضح في الشكل 2.2 .
الشكل 2.2 اختيار قالب التوليف
http://www.shabwh.com/up//uploads/images/shabwh354c4f6c89.gif (http://www.shabwh.com/up//uploads/images/shabwh354c4f6c89.gif)
تستطيع صياغة قوالب التوليف إما بتعديل الموجود منها، أو ببناء قوالب جديدة خاصة بك. واذا قمت بهذا، تذّكر ان نص قالب التوليف عادة ما يحوي حرف '|' ليشير الى الموقع الذي سيقفز له المؤشر بعد انتهاء العملية، حيث تتابع الكتابة لإكمال نص القالب.
تعليمات اللغة
حالما تقوم بتحديد بعض المعرفات، يمكنك استخدامها في تعليمات او في معادلات هي جزء من بعض التعليمات, تقدم باسكال مجموعة من التعليمات والتعبيرات. دعنا أولا نلقي نظرة على الكلمات المفتاحية، و التعبيرات ، و العاملات.
الكلمات المفتاحية
الكلمات المفتاحية هي كل المعرّفات المحجوزة من قبل اوبجكت باسكال، و التي لها دور في اللغة. دليل دلفي (Help) يميّز بين الكلمات المحجوزة والتوجيهات كالتالي: الكلمات المحجوزة لا يمكن استخدامها كمعرّفات، بينما التوجيهات لا يجب استخدامها لنفس الغرض، حتى لو قبلها المجمّع. عند الممارسة، عليك تجنّب استخدام أية كلمة محجوزة كمعرّف.
في الجدول 2.1 يمكنك رؤية قائمة كاملة بالمعرّفات التي لها دورا خاصا في لغة اوبجكت باسكال (في دلفي 4)، بما في ذلك الكلمات و الكلمات المحجوزة الأخرى.
الجدول 2.1: الكلمات المفتاحية و الكلمات المحجوزة الأخرى في لغة اوبجكت باسكال
http://www.shabwh.com/up//uploads/images/shabwhf3ba040123.gif (http://www.shabwh.com/up//uploads/images/shabwhf3ba040123.gif)
http://www.shabwh.com/up//uploads/images/shabwh4054e62069.gif (http://www.shabwh.com/up//uploads/images/shabwh4054e62069.gif)
http://www.shabwh.com/up//uploads/images/shabwh3bd100dfa4.gif (http://www.shabwh.com/up//uploads/images/shabwh3bd100dfa4.gif)
http://www.shabwh.com/up//uploads/images/shabwhafc33d2978.gif (http://www.shabwh.com/up//uploads/images/shabwhafc33d2978.gif)
التعبيرات والعامِلات
لا توجد قاعدة عامة لبناء التعبيرات expressions ، حيث تعتمد اساسا على العامِلات التي تستخدم، و التي لباسكال العديد منها. هناك المنطقي logical والحسابي arithmetic والبولي Boolean والعلائقي relational ، و عاملات الفئة set، بالاضافة الى عدد آخر. يمكن استعمال التعبيرات لتحديد القيمة التي ستخصص للمتغير، او لحساب المحدد parameter التابع لوظيفة او اجراء، او لاختبار شرط. و قد تتضمن التعبيرات استدعاء وظائف ايضا. في كل مرة تقوم فيها باجراء عملية على قيمة في معرّف، و ليس استعمال المعرف في حد ذاته، فان هذا يعدّ تعبيرا.
تعد التعبيرات امرا شائعا في لغات البرمجة. التعبير هو أي توليفة من الثوابت constants ، المتغيرات، القيم الحرفية literal ، عاملات، و نتائج الوظائف. التعبيرات يمكن ايضا تمريرها الى المحددات القيمية value parameters في الاجراءات و الوظائف، و لكن ليس دائما الى المحددات المرجعية reference parameters (التي تحتاج الى قيمة يمكن تخصيصها).
العامِلات و أسبقيتها
اذا سبق لك و أن كتبت برنامجا في حياتك، فانك تعلم بالفعل ماذا تعني كلمة تعبير expression. هنا سوف ألقي الضوء على عناصر محددة في عاملات باسكال. يمكنك رؤية قائمة بعاملات اللغة، مجمعة حسب الأسبقية، في الجدول 2.1.
على العكس من معظم اللغات الأخرى، فإن عاملات and و or لهما الأسبقية على العاملات العلائقية. لذاك اذا كتبت a < b and c < d، فان المجمّع سيحاول تنفيذ عملية and أولا، منتجا بذلك خطأ تجميع. لهذا السبب عليك وضع كل من تعبير < بين قوسين: (a < b) and (c < d).
بعض العاملات الشائعة لديها معان مختلفة مع انواع بيانات مختلفة. مثال ذلك، العامل + يمكن استخدامه لجمع رقمين، لوصل جملتين، صنع اتحاد بين فئتين، او حتى جمع رصيف offset مع مؤشر Pchar . الا انك لاتستطيع جمع حرفين، كما هو ممكن في لغة c.
عامل آخر غريب وهو div . ففي باسكال، يمكنك تقسيم أي رقمين (حقيقي أو صحيح) بواسطة العامل / ، وسوف تحصل بصورة ثابتة على رقم حقيقي كناتج. اما اذا احتجت الى تقسيم رقمين صحيحين للحصول على ناتج صحيح، استخدم العامل div كبديل.
الجدول 2.2: معاملات لغة باسكال، مجمعة حسب اسبقيتها
http://www.shabwh.com/up//uploads/images/shabwh388c0a8ffb.gif (http://www.shabwh.com/up//uploads/images/shabwh388c0a8ffb.gif)
عامِلات الفئة
عاملات الفئة تتضمن اتحاد union (+)، طرح difference (-)، تقاطع intersection (*)، اختبار عضوية membership (in)، بالإضافة الى مجموعة من العاملات العلائقية. لاضافة عنصر لمجموعة، يمكنك جعل اتحاد فئةة مع آخرى تملك فقط العنصر الذي تحتاجه. فيما يلي مثال بدلفي له علاقة بنمط الخطّ font styles:
Style := Style + [fsBold];
Style := Style + [fsBold, fsItalic] - [fsUnderline];
كبديل يمكنك استخدام الاجرائين الاعتيادين Include و Exclude، وهما أكثر فاعلية (لكنهما لايمكن استعمالهما مع سمات مكوّن التي تكون من نوع set، لأنها تحتاج الى محدد لقيمة l-):
Include (Style, fsBold);
ملخّص
الآن وقد عرفنا الخطوط الأساسية لبرنامج باسكال فنحن جاهزون لفهم معانيها بالتفصيل. سوف نبدأ باستكشاف تعريف أنواع البيانات سابقة التحديد و المحددة بالمستعمل، بعدها سننتقل معها الى استخدام الكلمات المفتاحية لبناء تعليمات برمجية.
الفصل التالي: الأنواع، المتغيرات، و الثوابت
- - - تم التحديث - - -
الفصل 3
الأنواع، المتغيرات، والثوابت
اعتمدت لغة باسكال الأصلية عل بعض المفاهيم البسيطة، والتي اصبحت الآن عامة في لغات البرمجة. المفهوم الأول هو نوع البيانات data type. النوع يحدد القيم التي يمكن للمتغيرات ان تتخذها، والعمليات التي يمكن انجازها عليها. ان مفهوم النوع أقوى في باسكال مقارنة بلغة س، حيث انواع البيانات الحسابية غالبا ما تكون متبدلة، وهي أقوى بكثير من النسخ الأصلية للغة بيسك، حيث لاتملك مثل هذا المفهوم.
المتغيرات
تتطلّب باسكال ان تكون كل المتغيرات معرّفة قبل استخدامها. وحتى في الوقت الذي تعرّف فيه المتغير، يجب أن تحدّد نوع البيانات. ها هنا بعض نماذج تعريف المتغيرات:
var
Value: Integer;
IsCorrect: Boolean;
A, B: Char;
المصطلح var يمكن استخدامه في اماكن مختلفة في الكود، كأن يكون في بداية توليف وظيفة أو اجراء، او ان يتم تعريف المتغيرات محليا local في الروتين ، أو داخل الوحدة لتعريف متغيرات جامعة global. بعد مصطلح var تأتي قائمة اسماء المتغيرات، متبوعة بشارحة واسم نوع البيانات. يمكنك كتابة اكثر من اسم متغير واحد في السطر الواحد، كما هو في آخر تعليمة أعلاه.
حالما تقوم بتحديد متغير من نوع ما، تستطيع ان تقوم فقط بمباشرة العمليات الداعمة لنوع بياناته. على سبيل المثال، يمكنك استعمال القيمة البولية للاختبار و القيمة الصحيحة في التعبير الرقمي. لايمكنك مزج القيم البولية والصحيحة (كما هو الأمر مع لغة س).
باستخدام تخصيصات بسيطة، نستطيع كتابة التوليف التالي:
Value := 10;
IsCorrect := True;
لكن التعليمة التالية ليست صحيحة، لأن المتغيرين يملكان نوع بيانات مختلف:
Value := IsCorrect; // error
اذا حاولت تحويل هذا التوليف، فان دلفي تقوم باصدار خطأ تحويل رفق هذا التوضيح: Incompatible types: 'Integer' and 'Boolean'. عادة، مثل هذه الأخطاء هي أخطاء برمجية، لأنه لامعنى لتخصيص قيمة True أو False لقيم من نوع بيانات صحيح. يجب أن لا تلوم دلفي على مثل هذه الأخطاء. هي فقط تنبهك لوجود خطأ ما في التوليف.
بالطبع، غالبا مايمكن تبديل قيمة متغير من نوع بيانات الى نوع مختلف. في بعض الحالات، هذا التبديل يكون آليا، لكن عادة ما تحتاج الى استدعاء وظائف محددة في النظام لتغيير التمثيل الداخلي للبيانات.
تستطيع في دلفي ان تخصص قيمة تمهيدية لمتغير جامع global variable أثناء تعريفك له. مثلا، تستطيع كتابة:
var
Value: Integer = 10;
Correct: Boolean = True;
تقنية التمهيد initialization هذه تصلح فقط للمتغيرات الجامعة، وليس للمتغيرات المعرفة داخل نطاق اجراء أو مسار.
الثوابت
تسمح باسكال ايضا بتعريف ثوابتا constants لتسمية القيم التي لاتتغير خلال عمل البرنامج. لتعريف ثابت لاتحتاج لتحديد نوع البيانات، فقط تخصيص قيمة ابتدائية. المحوّل سيتفحّص القيمة وآليا يستخدم نوع بياناته المناسب. ها هنا بعض امثلة التعريفات:
const
Thousand = 1000;
Pi = 3.14;
AuthorName = 'Marco Cantù';
يقرر دلفي نوع البانات للثابت بناء على قيمته. في المثال أعلاه، الثابت Thousand يفترض ان يكون من نوع صحيح صغير SmallInt ، اصغر نوع صحيح يمكنه احتواء القيمة. اذا اردت الطلب من دلفي استخدام نوع محدد؛ يمكنك ببساطة اضافة اسم النوع في التعريف، كما هو في:
const
Thousand: Integer = 1000;
عندما تقوم بتعريف ثابت، يستطيع المحوّل أن يختار بين أن يخصص موقعا في الذاكرة للثابت، و يحفظ فيه قيمته، أو أن ينسخ قيمته الحقيقية في كلّ مرة يتم فيها استعمال الثابت. الأسلوب الثاني يبدو معقولا خاصة بالنسبة للثوابت البسيطة.
ملاحظة: نسخ 16-بت من دلفي تسمح لك بتغيير قيمة الثابت محدد النةع في زمن التشغيل، كما لو كان متغيرا. نسخة 32-بت لازالت تسمح بهذا السلوك من اجل التوافقية مع السابق وذلك عندما تقوم بتمكين موجّه المحوّل $J ، او بالتعليم على مؤشر Assignable typed constants في صفحة المحوّل في نافذة خيارات المشروع Project Options . وبالرغم من أن هذا هو التوصيف الافتراضي، فانه ينصح بقوة كفنيّات البرمجة أن لاتستعمل هذه الخدعة. ان تخصيص قيمة جديدة لثابت يمنع كل تشذيبات المحول على الثواب. واذا اضطررت لهذا، ببساطة قم بتعريف متغيرات، كبديل.
ثوابت الجمل الموردية
عندما تحدد ثابت جملة، فبدلا من كتابة:
const
AuthorName = 'Marco Cantù';
يمكنك بدءاً من دلفي 3 أن تكتب التالي:
resourcestring
AuthorName = 'Marco Cantù';
في كلتا الحالتين انت تحدد ثابتا؛ قيمة لاتقم بتغييرها خلال زمن التشغيل. الفرق فقط في كيفية الانجاز. ثابت الجملة المحدد بواسطة الموجّه resourcestring يخزّن ضمن موارد البرنامج resources، في جدول للجمل.
لكي ترى هذه الامكانية فعليا، قم بالاطلاع على مثال ResStr ، والذي له زرّا رفق التوليف التالي:
resourcestring
AuthorName = 'Marco Cantù';
BookName = 'Essential Pascal';
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage (BookName + #13 + AuthorName);
end;
ناتج الجملتين يظهر في سطرين منفصلين لأن الجملتين مفصولتين بالحرف الدّال لسطر جديد newline (مشار اليه بقيمته الرقمية في #13 وهو ثابت نوع حرف).
الجانب المثير في هذا البرنامج هو انك اذا تفحصّته بمستكشف للموارد resource explorer (هناك واحد متوفر في الأمثلة التي تأتي مع دلفي) سوف ترى الجمل الجديدة ضمن الموارد. هذا يعني بأن الجمل ليست جزءا من التوليف المحول ولكنها خزّنت في منطقة منفصلة في الملف التنفيذي (ملف EXE).
ملاحظة: باختصار، مزايا الموارد هي في الكفاءة في مناولة الذاكرة التي تقوم بها ويندوز، وفي امكانية توطين localizingالبرنامج (ترجمة الجمل الى لغات مختلفة) بدون الحاجة الى تعديل توليفها المصدري source code.
أنواع البيانات
في باسكال توجد عدة انواع بيانات سابقة التحديد predefined data types ، والتي يمكن تقسيمها الى ثلاث مجموعات: الانواع التراتبية ordinal types، الأنواع الحقيقية real types و الجمل strings. سوف نناقش الانواع التراتبية في الأقسام التالية، بينما يتم تغطية الجمل لاحقا في هذا الفصل. في هذا القسم سوف أقدم ايضا بعض الأنواع المحددة من قبل مكتبات دلفي (ليست محددة من قبل المحوّل)، والتي يمكن اعتبارها انواع سابقة التحديد predefined types.
تتضمن دلفي ايضا نوع بيانات بدون نوع non-typed ، تسمّى متباين variant ، سيتم مناقشتها في الفصل العاشر من هذا الكتاب. غريب جدا ان يكون المتباين نوعا بدون مايناسبه من تحقق من النوع. لقد تم ادخال هذا النوع في دلفي 2 لمناولة آليات او ال اي OLE Automation.
الأنواع التراتبية
الأنواع التراتبية Ordinal types مبنية على مفهم الترتيب أو التوالي و التتابع. ليس بامكانك فقط مقارنة قيمتين لمعرفة أيهما الأكبر، ولكن يمكنك أيضا معرفة القيمة التي تلي او تسبق قيمة أخرى، أو تقوم بحساب أدني أو أعلى قيمة محتملة.
أكثر ثلاث أنواع تراتبية سابقة التحديد هي الصحيح Integer، البولي Boolean، و الحرف Char. عموما، هناك عددا من الأنواع الأخرى ذات العلاقة والتي لها معنى مشابها ولكن لها تمثيلا ومدى قيم مختلفين. جدول 3.1 التالي يعرض انواع البيانات التراتبية المستخدمة لتمثيل الأرقام.
جدول 3.1: أنواع البيانات التراتبية للأرقام
http://www.shabwh.com/up//uploads/images/shabwh7479408598.gif (http://www.shabwh.com/up//uploads/images/shabwh7479408598.gif)
كما ترى، هذه الأنواع لها علاقة بالتمثيلات المختلفة للأرقام، حسب عدد الجزئيات bits المستخدمة للتعبير عن القيمة، وحسب وجود أو غياب جزئية العلامة. القيم المعلّمة signed values يمكنها أن تكون موجبة أو سالبة، لكن لها مدى أصغر من القيم، وذلك لأن المتاح من الجزئيات للقيمة نفسها قد نقصت بواحدة. تستطيع أن ترجع الى مثال المدى الذي سيناقش في القسم التالي، من أجل معرفة المدى الفعلي لقيم كل نوع.
المجموعة الأخيرة (والمشارة ب 16/32) تشير الى القيم التي لها تمثيلا مختلفا في نسخ 16-بت و 32-بت من دلفي. الصحيح Integer و الرئيسي Cardinal يستعملان بكثرة، لأنهما يطابقان التمثيل الفطري للأرقام في المعالج الحسابي CPU.
الأنواع الصحيحة في دلفي 4
في دلفي 3، الأرقام ذات 32 بت غير المعّلمة والمشار اليها بنوع رئيسي cardinal كانت سابقا قيم 31 بت، بمدي يبلغ حتى 2 قيقابايت. قدمت دلفي 4 نوع جديد رقمي غير معلّم، LongWord ، والذي يستخدم فعليا قيمة 32 بت تبلغ حتى 4 قيقابايت. وأصبح نوع كاردينال الآن اسما مرادفا لنوع لونغوورد الجديد. لونغوورد يسمح ب 2GB اكثر اضافية من البيانات يمكن عنونتها من قبل رقم غير معّلم، كما أشير اليه سابقا. أكثر من هذا، فإنه يماشي التمثيل الفطري للأرقام في المعالج الحسابي.
نوع آخر جديد تم ادخاله في دلفي 4 و نوع int64 ، والذي يمثل أعدادا صحيحة تبلغ 18 رقم. هذا النوع الجديد مدعوم بالكامل من قبل بعض اجرائيات routines الأنواع التراتبية (مثل High و Low)، والإجرائيات الرقمية (مثل Inc و Dec)، وإجرائيات تبديل الجمل string-conversion (مثل IntToStr). ومن أجل التبديل العكسي، من جملة ألى رقم، هناك وظيفتين جديدتين: StrToInt64 و StrToInt64Def.
البولي
القيم البولية غير النوع البولي نادرة الاستعمال. بعض القيم البولية لديها تمثيل خاص وذلك لمتطلبات وظائف ويندوز Windows API functions. الأنواع هي ByteBool، WordBoolو LongBool.
في دلفي 3 ومن أجل التوافق مع فيجوال بيسك و آليات OLE، فان انواع البيانات ByteBool، WordBool، و LongBool تم تعديلهم لتمثيل القيم True بـ -1، بينما القيمة False لازالت 0. نوع البيانات Boolean ظلّت كما هي (True هي 1، , False هي 0). إذا قمت باستعمال سبك نوع typecast صريح في برنامج بدلفي 2، فإن نقل البرنامج الى نُسخ لاحقة من دلفي قد ينتج عنه بعض الأخطاء.
الأحرف
أخيرا هناك تمثيلين مختلفين للأحرف: ANSIChar و WideChar. النوع الأول يمثل أحرفا ذات جزئيات ثمان 8-bit، تتماشى مع مجموعة أحرف انسي ANSI والمستخدمة تقليديا من قبل ويندوز؛ التمثيل الثاني الأحرف 16-جزئية ، وتتماشى مع أحرف يونيكود الجديدة Unicode والمدعومة بالكامل من قبل ويندوز ن ت، وجزئيا من قبل ويندوز 95 و 98. معظم الوقت سوف تستعمل ببساطة نوع حرف Char ، والذي في دلفي 3 تطابق ANSIChar. ليكن معلوما، على أي حال، ان أول 256 من حروف يونيكود توافق تماما حروف انسي ANSI.
أحرف الثوابت يمكن تمثيلها بمجموعة رموزها، كما في 'k'، او بمجموعة أرقامها، كما في #78. الأخيرة يمكن التعبير عنها ايضا ياستخدام الوظيفية Chr ، كما في Chr (78). التبديل المعاكس يمكن اجراؤه بواسطة الوظيفة Ord.
بصفة عامة يكون من الأحسن استخدام مجموعة الرموز عند الإشارة الى الأحرف، والأرقام، والعلامات. عند الإشارة الى أحرف خاصة، ستستخدم مجموعة الأرقام عموما بدلا من ذلك. القائمة التالية تتضمن بعض أكثر الأحرف الخاصة استعمالا:
#9 tabulator جدولة
#10 newline سطر جديد
#13 carriage return (enter key) مفتاح الإدخال
مثال Range
لإعطائك فكرة عن الاختلاف من مدى لآخر في بعض الأنواع التراتبية، قمت بكتابة برنامج دلفي بسيط أسميته Range. بعض النتائج تظهر في الشكل 3.1.
الشكل 3.1: مثال Range يظهر بعض المعلومات حول انواع البيانات التراتبية (الأرقام الصحيحة في هذه الحالة).
http://www.shabwh.com/up//uploads/images/shabwh192e7f5d1f.gif (http://www.shabwh.com/up//uploads/images/shabwh192e7f5d1f.gif)
برنامج Range مبني على نموذج form بسيط، به ستة أزرار buttons (كلّ مسمّاة حسب نوع البيانات التراتبية) وبعض الملصقات labels لمختلف المعلومات، كما هو مبيّن في الصورة 3.1. أستخدمت بعض الملصقات لتحوي نصّا ثابتا، الأخرى لعرض المعلومات عن النوع في كلّ مرّة يُضغط فيها على زرّ.
في كلّ مرّة تضغط فيها على الأزرار، يقوم البرنامج بتحديث الملصقات بحسب الناتج. ملصقات مختلفة تعرض نوع البيانات، عدد البايت المستعملة، و أقصى وأدني قيمة يمكن للنوع أن يخزّنها. كل زرّ يملك مايخصّه من مسار method تجاوب الحدث OnClick لأن التوليف المستخدم لحساب القيم الثلاث يختلف قليلا من زرّ لآخر. مثلا، هاهنا التوليف المصدري لحدث OnClick للزرّ الخاص بنوع الصحيح (BtInteger):
procedure TFormRange.BtnIntegerClick(Sender: TObject);
begin
LabelType.Caption := 'Integer';
LabelSize.Caption := IntToStr (SizeOf (Integer));
LabelMax.Caption := IntToStr (High (Integer));
LabelMin.Caption := IntToStr (Low (Integer));
end;
إذا كنت تملك بعض الخبرة في البرمجة بدلفي، يمكنك تفحّص التوليف لفهم كيفية عمله. بالنسبة للمبتدئين، يكفي ملاحظة الإستخدام للوظائف الثلاثة: SizeOf وHigh و Low. نواتج الوظيفتين الأخيرتين هما تراتبيات من نفس النوع (في هذا الحالة، أعداد صحيحة)، وناتج وظيفة SizeOf هي دائما عدد صحيح. القيمة المرتجعة من هذه الوظائف الثلاث تترجم أولا إلى جُمل بإستخدام وظيفة IntToStr، ثم تُنسخ في لافتات captions الملصقات الثلاث.
المسارات المرتبطة بالأزرار الأخرى تشبه كثيرا المسار المذكور أعلاه. الإختلاف الفعلي الوحيد هو نوع البيانات الذي تم تمريره كمحدد لمختلف الوظائف. الصورة 3.2 تعرض ناتج تنفيذ البرنامج تحت ويندوز 95 بعد أن تم إعادة تحويله recompile بواسطة نسخة 16-بت من دلفي. بمقارنة الشكل 3.1 و الشكل 3.2، يمكنك رؤية الإختلاف بين نوع البيانات الصحيح ذو 16-بت وذلك ذو 32-بت.
الشكل 3.2: ناتج نسخة 16-بت من مثال Range، يعرض مرّة أخرى معلومات عن العدد الصحيح.
http://www.shabwh.com/up//uploads/images/shabwh03fbf072e0.gif (http://www.shabwh.com/up//uploads/images/shabwh03fbf072e0.gif)
حجم نوع الصحيح Integer يتباين بحسب المعالج الحسابي ونظام التشغيل المستخدم. في ويندوز 16-بت، المتغير الصحيح يسع 2 بايت. بينما في ويندوز 32، سعة الصحيح 4 بايت. لهذا السبب، عندما تعيد تحويل مثال Range، ستحصل على نتائج مختلفة.
التمثيلين المختلفين لنوع الصحيح ليست بمشكلة، طالما أن برنامجك لايضع أية إفتراضات عن حجم الصحيح. إذا ما حدث وقمت بحفظ عدد صحيح في ملف بإستخدام نسخة ثم حاولت استرجاعه بنسخة أخرى، فسوف تواجه بعض المتاعب. في هذه الحالة، يجب أن تختار نوع بيانات مستقل عن بيئة التشغيل (مثل LongInt أو SmallInt). لأغراض الحسابات الرياضية أو توليف عام، أفضل مراهنة لديك هو أن تلتزم تمثيل الصحيح النمطي لبيئة التشغيل المعينة-- هذا يعني، ان تستخدم نوع الصحيح-- لأنه المفضّل لدى المعالج الحسابي. نوع الصحيح Integer يجب أن يكون خيارك الأول عندما تعالج أعدادا صحيحة. و لا تستخدم تمثيلا مختلفا إلا إذا وجدت سببا قاهرا لذلك.
إجرائات الأنواع التراتبية
بعض إجرائيات النظام system (إجرائيات محددة في لغة باسكال وفي وحدة النظام في دلفي system unit)يمكنها تتعامل مع الأنواع التراتبية ordinal types. هي معروضة في الجدول 3.2. المبرمجون بلغة س++ سوف يلاحظون بأن النسختين من إجرائية Inc، مع محدد أو اثنين، يطابقان معاملات ++ و += (نفس الأمر مع إجرائية Dec).
الجدول 3.2: إجرائيات نظام للأنواع التراتبية
http://www.shabwh.com/up//uploads/images/shabwh5afcd96e3f.gif (http://www.shabwh.com/up//uploads/images/shabwh5afcd96e3f.gif)
لاحظ ان بعض هذه الإجرائيات، عندما يتم تطبيقها على الثوابت constants، فإن المحوّل يقوم بتقييمها آليا واستبدالها بقيمتها. مثلا اذا قمت باستدعاء High(X) حيث X معرّفة كصحيح، فالمحوّل يستطيع ببساطة تبديل التعبير بآخر يمثل أعلى قيمة محتملة لنوع بيانات الصحيح.
الأنواع الحقيقية
تقوم الأنواع الحقيقية بتمثيل أرقام النقطة العائمة بعدة أشكال. أصغر حجم تخزين تمثلها الأرقام الوحيدة Single ، والتي تنفذ بقيمة ذات 4-بايت. ثم هناك الأرقام النقطة العائمة المضاعفة Double، المنفذة بعدد 8 بايت، والأرقام الممتدّة Extended ، والمنجزة بعدد 10 بايت. كل هذه أنواع بيانات نقطة عائمة مع اختلاف في الضبط والدقة precision.
في دلفي 2 ودلفي 3 نوع الحقيقي Real له نفس التعريف الذي في نسخة 16-بت؛ لقد كانت بنوع 48-بت. لكن تم تخفيض استخدامه من قبل بورلاند، والتي اقترحت بأن تقوم باستعمال أنواع الوحيد والمضاعف والممتد بدلا منه. سبب اقتراحهم هذا هو ان الشكل القديم ذو 6-بايت ليس مدعوما من قبل معالجات انتل Intl كما انه ليس معروضا ضمن القائمة الرسمية للأنواع الحقيقية والتي اصدرتها IEEE. ولكي يتم تلافي المشكلة تماما، قامت دلفي 4 بتعديل التعريف الخاص بنوع الحقيقي حتى يمثل الشكل القياسي لرقم عائم النقطة ذو 8 بايت (64-بت).
بالإضافة إلى ميزة استخدام تعريفا قياسيا متفق عليه، هذا التغيير يسمح للمكونات components باصدار سمات properties مبنية عل نوع حقيقي، الشيء الذي لم يكن دلفي 3 يسمح به. أما العيوب فقد تبرز مشاكل التوافقية. في حالة الضرورة، وعند الاصرار على طريقة دلفي 2 و 3 في تعريف النوع، يمكنك تجاوز احتمال انعدام التوافقية؛ وذلك باستخدام خيار المجمّع التالي:
{$REALCOMPATIBILITY ON}
هناك أيضا نوعان غريبان من أنواع البيانات: Comp ويصف رقم صحيح كبير جدا باستخدام 8 بايت (والذي يمكنه احتواء ارقام ذات 18 خانة عشرية)؛ و Currency عملة (ليست متوفرة في دلفي 16-بت) وهي تشير الى قيمة بنقطة عشرية ثابتة مع اربع خانات عشرية، و بنفس تمثيل 64-بت كما في نوع Comp. كما يوحي الإسم، نوع بيانات عملة Currency أضيف لمناولة القيم النقدية شديدة الدقة، مع أربع خانات عشرية.
لا نستطيع بناء برنامج يشبه مثال Range بتطبيق انواع بيانات حقيقية، لأننا لايمكننا استخدام وظائف High و Low أو Ord مع متغيرات نوع حقيقي. الأنواع الحقيقية تمثل (نظريا) مجموعة لانهائية من الأرقام، بينما الأنواع التراتبية تمثل مجموعة ثابتة من القيم.
ملاحظة: دعوني أشرح ذلك بطريقة أفضل. عندما يكون لديك الرقم الصحيح 23، يمكنك أن تقرّر ماهي القيمة التي تليه. الأرقام الصحيحة نهائية (لديها مدى محدد ولديها ترتيب). الأرقام عائمة النقطة هي غير نهائية حتى ضمن المدى القصير، وليس لديها ترتيب: في الواقع، كم توجد قيمة بين 23 و 24 ؟ و ما هو الرقم الذي يلي 23.46 ؟ هل هو 23.47، 23.461، أو 34.4601 ؟ هذا الأمر يصعب معرفته بالفعل.
لهذا السب، يبدو الأمر معقولا حين نسأل عن ترتيب موضع حرف w ضمن مدى نوع بيانات حرف char، و لكن ليس من المعقول ابدا أن نسأل نفس السؤال عن الرقم 7143.1562 ضمن مدى نوع بيانات النقطة العائمة. بالرغم انه بالتأكيد تستطيع معرفة ما إذا كان ;رقم حقيقي ما لديه قيمه أعلى من قيمة رقم آخر، فإنه من غير المنطقي أن نسأل عن عدد الأرقام الحقيقية الموجودة قبل رقم ما (هذا معني وظيفة Ord).
الأنواع الحقيقية لديها دورا محدودا في ذلك الجزء من التوليف البرمجي الخاص بواجهة المستخدم user interface (الجانب الخاص بويندوز)، لكنها مدعومة بالكامل من قبل دلفي، بما في ذلك جانب قواعد البيانات. ان دعم مواصفات IEEE القياسية لأنواع النقطة العائمة تجعل من لغة اوبجكت باسكال مناسبة تماما لنطاق واسع من البرامج التي تتطلب حسابات رقمية. إذا كنت مهتما بهذا الجانب، يمكنك إلقاء نظرة على الوظائف الرياضية المقدمة من دلفي وذلك في ملف وحدة system (انظر Delphi Help من أجل تفاصيل أكثر).
ملاحظة: لدلفي ايضا ملف وحدة Math التي تحدد إجرائيات رياضية أكثر تقدما، تغطي وظائف حساب المثلثات (مثل وظيفة ArcCosh)، مالية (مثل وظيفة InterestPayment)، و إحصائية (مثل إجرائية MeanAndStdDev). هناك العديد من هذه الإجرائيات، بعضها تبدو غريبة بالفعل بالنسبة لي، مثل إجرائية MomentSkewKurtosis (سأدع هذا الأمر لك لمعرفته) .
التاريخ والوقت
تستخدم دلفي أيضا أنواعا حقيقية real types لمناولة معلومات التاريخ والوقت. وليكون الأمر أكثر دقّة حدّدت دلفي نوع بيانات TDateTime. وهو نوع نقطة عائمة، لأن النوع يجب أن يكون واسعا بما يكفي لإحتواء السنوات، الأشهر، الأيام، الساعات، الدقائق، والثواني، نزولا إلى دقة تبلغ جزء من ألف من الثانية، كلّ ذلك في متغير واحد. التواريخ تخزّن كإجمالي عدد الأيام منذ 12/30/1899 (مع قيم سالبة تشير إلى التواريخ ما قبل 1899) في الجزء الصحيح integer من قيمة TDateTime.
نوع TDateTime ليس نوعا مسبق التحديد بحيث يفهمه المحوّل، لكن قد تمّ تعريفه في ملف وحدة system كالتالي:
type
TDateTime = type Double;
إستخدام TDateTime يعدّ بسيط، لأن دلفي تحوي عددا من الوظائف التي تتعامل مع هذا النوع. يمكنك أن تجد قائمة بهذه الوظائف في الجول 3.3.
الجدول 3.3: إجرائيات نظام لنوع TDateTime
http://www.shabwh.com/up//uploads/images/shabwh94c4f5036f.gif (http://www.shabwh.com/up//uploads/images/shabwh94c4f5036f.gif)
من أجل أن ترى كيف يتم استعمال نوع البيانات هذا و بعض الإجرائيات الخاصة به، قمت ببناء برنامج بسيط، أسميته TimeNow. النموذج الرئيسي في هذا المثال به زرّ Button و قائمة ListBox. عندما يبدأ البرنامج يقوم آليا بحساب وعرض الوقت والتاريخ الحالي. في كلّ مرّة يتم فيها الضغط على الزرّ، يقوم البرنامج بعرض الزمن المنقضي منذ بدء البرنامج.
فيما يلي التوليف الموصول بحدث OnCreate الخاص بالنموذج:
procedure TFormTimeNow.FormCreate(Sender: TObject);
begin
StartTime := Now;
ListBox1.Items.Add (TimeToStr (StartTime));
ListBox1.Items.Add (DateToStr (StartTime));
ListBox1.Items.Add ('Press button for elapsed time');
end;
التعليمة الأولى تنادي وظيفة Now ، التي تسترجع التاريخ و الوقت الحاليين. القيمة المسترجعة تُخزّن في متغيّر StartTime ، والذي تم تعريفه كمتغير خارجي global كالتالي:
var
FormTimeNow: TFormTimeNow;
StartTime: TDateTime;
لقد أضفت فقط التعريف الثاني، حيث أن دلفي تقوم بتوفير الأول. حيث يكون مبدئيا كالتالي:
var
Form1: TForm1;
عند تغير اسم النموذج form، يتم تحديث هذا التصريح آليا. ان استخدام متغيرات جامعة global لا يعدّ حقيقة أفضل الطرق: سيكون من الأفضل لو تم استخدام حقل خاص private field تابع لطبقة النموذج form class، موضوع له علاقة ببرمجة التوجّه الكائني object-oriented programming تم مناقشته في كتاب التحكم بدلفي 4 Mastering Delphi .
التعليمات الثلاث التالية تضيف ثلاثة عناصر الى مكوّن القائمة يمين النموذج، مع النتائج التي تراها في الشكل 3.3. السطر الأول يحتوي على الجزء الخاص بالوقت في قيمة TDateTime محوّلا الى جملة، الثاني يحتوي جزء التاريخ من نفس القيمة. في نهاية التوليف أضيف تذكير بسيط.
الشكل 3.3: ناتج مثال TimeNow عند البدء.
http://www.shabwh.com/up//uploads/images/shabwh0c2dbd6dc1.gif (http://www.shabwh.com/up//uploads/images/shabwh0c2dbd6dc1.gif)
الجملة الثالثة يستبدلها البرنامج عندما يضغط المستعمل على زرّ Elapsed "المنقضى":
procedure TFormTimeNow.ButtonElapsedClick(Sender: TObject);
var
StopTime: TDateTime;
begin
StopTime := Now;
ListBox1.Items [2] := FormatDateTime ('hh:nn:ss',
StopTime - StartTime);
end;
التوليف يسترجع الوقت الجديد ويحسب الفرق بينه وبين قيمة الوقت المخزّن عند ابتداء البرنامج. ولأننا نحتاج الى استخدام القيمة التي سبق حسابها في سياق حدث مختلق، كان علينا أن نخزّنها في متغير جامع. في الواقع توجد بدائل أفضل، مبنية على مفهوم الطبقات classes.
ملاحظة: التوليف الذي يقوم باستبدال القيمة الحالية في الجملة الثالثة يستعمل دليل index 2. السبب في ذلك ان بنود القائمة مبنية على الصفر are zero-based: البند الأول رقمه 0، الثاني رقم 1، و الثالث رقم 3. سنرى المزيد من ذلك عندما نناقش المصفوفات.
بجانب استدعاء DateToStr و TimeToStr يمكنك استعمال وظيفة FormatDateTime الأكثر قوة، كما فعلت في المسار method الأخير أعلاه (انظر ملف مساعدة دلفي من أجل تفاصيل محددات الصياغة). لاحظ أيضا أن قيم الوقت والتاريخ تُبدّلان إلى جُمل بحسب توصيف الدوليّات international في ويندوز. دلفي يقرأ هذه القيم من النظام، و يوزعها في عدد من الثوابت الجامعة global constants المُعرّفة في ملف وحدة SysUtils. نذكر منها:
DateSeparator: Char;
ShortDateFormat: string;
LongDateFormat: string;
TimeSeparator: Char;
TimeAMString: string;
TimePMString: string;
ShortTimeFormat: string;
LongTimeFormat: string;
ShortMonthNames: array [1..12] of string;
LongMonthNames: array [1..12] of string;
ShortDayNames: array [1..7] of string;
LongDayNames: array [1..7] of string;
يوجد المزيد من الثوابت الجامعة تتعلق بالعُملة و صياغة رقم النقطة العائمة. يمكنك الحصول على قائمة كاملة بها من ملف مساعدة دلفي تحت العنوان Currency and date/time formatting variables.
انواع ويندوز الخاصة
أنواع البيانات السابقة التحديد والتي سبق أن استعرضناها حتى الآن هي جزء من لغة باسكال. تتضمن دلفي أنواع بيانات أخري مجددة من قبل ويندوز. أنواع البيانات هذه ليست جزءاً مكمّلا في اللغة، ولكنها جزءا من مكتبات libraries ويندوز. أنواع ويندوز تتضمن أنواع ابتدائية جديدة (مثل DWORD و UINT)، و العديد من التسجيلات records (أو بنيات structues)، و عددا من الأنواع المؤشّرة pointer، وغيرها.
من بين أنواع بيانات ويندوز، فإن النوع الأكثر أهمية تمثله المماسك handles، الفصل 9 يناقش ذلك.
تلبيس النوع و تحويلات النوع
كما رأينا، لا يمكنك تخصيص متغير لآخر من نوع مختلف. إذا أردت ذلك، يوجد خياران. الخيار الأول هو تلبيس النوع typecasting ، والذي يستخدم رمز وظائفي بسيط ، باسم نوع البيانات المطلوب:
var
N: Integer;
C: Char;
B: Boolean;
begin
N := Integer ('X');
C := Char (N);
B := Boolean (0);
يمكنك التلبيس بين أنواع البيانات ذات نفس الحجم. عادة مايكون الأمر مأمونا عند التلبيس بين الأنواع التراتبية، أو بين الأنواع الحقيقية، ولكن يمكنك التلبيس بين أنواع مؤشّرة pointer (وأيضا الكينونات objects) طالما تكون مدركا لما تفعله.
التلبيس، بصفة عامة، عادة برمجية خطيرة، لأنه يسمح لك بالوصول إلى قيمة كما لو أنها ممثلة بشكل آخر. و طالما ان التمثيلات الداخلية لأنواع البيانات عموما غير متجانسة، فأنت تخاطر بالتسبب بأخطاء صعبة التتبع. لهذا السبب، يجب عليك عموما تجنب عمليات تلبيس النوع.
الخيار الثاني هو استخدام إجرائيات تحويل النوع. الإجرائيات الخاصة بمختلف أنواع التحويلات تم تلخيصها في الجدول 3.4. بعض هذه الإجرائيات تعمل مع أنواع بيانات سيجري الحديث عنها في الأقسام التالية. لاحظ ان الجدول لا يحوي الإجرائيات الخاصة بالأنواع الخاصة (مثل TDateTime أو المتبياين variant) أو الإجرائيات الموجّه خصّيصا للتشكيل والصياغة formating، مثل الإجرائيات الفعّالة Format و FormatFloat.
جدول 3.4: إجرائيات النظام الخاصة بتحويل البيانات
http://www.shabwh.com/up//uploads/images/shabwh383381d592.gif (http://www.shabwh.com/up//uploads/images/shabwh383381d592.gif)
ملخّص
في هذا الفصل استكشفنا المفهوم الأساسي للنوع في باسكال. لكن اللغة لديها ميزة أخرى مهمة جدا: انها تسمح للمبرمجين بتعريف أنواع بيانات جديدة خاصة، تدعى بأنواع البيانات المحددة بالمستعمل user-defined data types. هذا هو موضوع الفصل التالي.
الفصل التالي: أنواع البيانات المحدّدة بالمستعمل.....
انتظرو الفصل القادم قريبا الأمثلة المذكورة في الدروس موجود عنها نسخ في المرفقات ارجوا ان اكون اوفيت الشرح انتظرو بقية الفصول
قريباً