المصفوفات (الدرس الثاني)

    • المصفوفات (الدرس الثاني)

      [TABLE='width:70%;'][CELL='filter:;']
      محتوى الدرس:

      كيفية تعريف مصفوفة ذات حجم متغير Dynamic Array.
      حفظ محتويات الـDynamic Arrays عند إعادة تعريفيها.
      جملة ReDim.


      المصفوفات متغيرة الحجم Dynamic Array:

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

      ولصناعة Dynamic Array نتبع التالي:

      نعلن عنها بأحد أوامر الإعلان الموضحة في الدرس السابق (Public or Private or Dim or Static) ونجعلها ديناميكية بعدم أي رقم في الأقواس كما يوضح المثال التالي:

      Dim AnyArray( )

      نعيد الإعلان عنها مع تحديد عدد العناصر باستخدام جملة ReDim كما في المثال التالي:

      ReDim AnyArray( x+1 )

      ملاحظات:

      يمكن لجملة ReDim الظهور فقط في الـProcedure. وبعكس جملتي Dim, & Static فإن جملة ReDim قابلة للتنفيذ Executable.
      تستخدم جملة ReDim نفس الصيغة Syntax المستخدم مع مصفوفات الحجم الثابت Fixed Array.
      كل جملة من جمل ReDim يمكنها تغيير عدد العناصر بالإضافة إلى الحد الأعلى والحد الأدنى لكل بعد للمصفوفة، ومع ذلك فإن عدد الأبعاد في المصفوفة لا يمكن تغييره.
      مثال:

      لصناعة مصفوفة M كمصفوفة متغيرة الحجم، نعلن عنها أولاً في الـModule على النحو التالي:

      Dim M( ) As Integer

      ثم نعيد الإعلان عنها داخل الـProcedure على النحو التالي:

      Sub ANY_NAME()



      ReDim M(9, 15)

      End Sub



      حفظ محتويات المصفوفة متغيرة الحجم عند إعادة تعريفها:

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

      Empty Value في حالة الــــ Variant Array
      Zero في حالة الــــ Numeric Array
      Zero-Length String في حالة الــــ String Array
      Nothing في حالة الــــ Array of objects

      وهذا مفيد عندما نريد تجهيز المصفوفة لبيانات جديدة أو عندما نريد اختزال حجم المصفوفة لتأخذ أقل مساحة ممكنة في الذاكرة. ولكن أحياناً نريد تغيير حجم المصفوفة دون فقد بياناتها!
      يمكننا فعل ذلك باستخدام جملة ReDim مع كلمة Preserve وتعني "احفظ".

      مثال:

      الكود التالي يستخدم جملة ReDim لتخصيص، ثم إعادة تخصيص مساحة تخزينية لمصفوفة متغيرة الحجم، مع افتراض أن الـOption Base يساوي 1:

      Dim MyArray ( ) As Integer 'declare Dynamic Array

      ReDim MyArray( 5 ) 'allocate 5 elements
      For I = 0 To 5 'loop 5 times
      MyArray(I) = I 'initialize array elements
      Next I

      ReDim MyArray( 10 ) 'allocate 10 elements
      For I = 0 To 10 'loop 10 times
      MyArray(I) = I 'initialize array elements
      Next I

      الجملة التالية تغير حجم المصفوفة ولكنها لا تمحو العناصر الموجودة بها:

      ReDim Preserve MyArray( 10 )

      والآن يمكننا كتابة ملخص متكامل لجملة ReDim.



      جملة ReDim:

      تستخدم في مستوى الـProcedure لإعادة تخصيص allocates مساحة تخزينية storage space لمصفوفة متغيرة الحجم Dynamic array.

      صيغتها Syntax:

      ReDim [Preserve] varname(subscripts) [As type] [, varname (subscripts) [As type]]

      حيث أن:

      Preserve اختيارية، وتستخدم لحفظ البيانات الموجودة في المصفوفة عند تغيير حجم آخر بعد فيها.
      varname اسم المتغير (اسم المصفوفة).
      subscripts أبعاد المصفوفة (عددهم على الأكثر 60) وتستخدم الشكل التالي:
      [lower To] upper [, [lower To] upper]

      والقيمة الأدنى تحددها جملة Option Base وإذا لم توجد، يكون الحد الأدنى هو الافتراضي (صفر).

      type اختيارية، وتحدد نوع بيان عناصر المصفوفة. وقد تكون أي من الأنواع التالية:
      Byte, Boolean, Integer, Long, Single, Double, Currency, Decimal, Date, Object, String, Variant, User-defined.

      [, varname (subscripts) [As type]] اختيارية، لإعادة تحجيم مصفوفة أخرى.

      ملاحظات هامة:

      جميع ما ذكر في الصيغة داخل قوسين مربعين [] يعتبر اختياري يمكن الاستغناء عنه حين عدم الحاجة إليه.
      تستخدم جملة ReDim لتحجيم أو إعادة تحجيم مصفوفة متغيرة الحجم Dynamic Array والتي بالفعل قد أعلن عنها مسبقاً باستخدام أي من الجمل Dim, Private, Public مع أقواس فارغة (أي بدون ذكر الأبعاد).
      يمكن تكرار استخدام جملة ReDim لتغيير عدد العناصر والأبعاد لمصفوفة، ومع ذلك لا يمكن الإعلان عن مصفوفة بنوع معين من البيانات ثم إعادة تعريفها لاحقاً مع تغيير نوع البيان لنوع آخر إلا إذا كانت المصفوفة محتواه في variant.
      إذا كانت المصفوفة محتواه في variant فإن نوع بيان العناصر يمكن أن يتغير باستخدام المقطع As Type إلا إذا استخدمنا كلمة Preserve ففي هذه الحالة لا يسمح بتغييرات.
      إذا استخدمنا كلمة Preserve يمكن فقط تحجيم البعد الأخير للمصفوفة ولا يمكن تغيير عدد الأبعاد على الإطلاق.
      إذا كان للمصفوفة بعد واحد فيمكن إعادة تحجيم هذا البعد لأنه البعد الأخير والوحيد بالمصفوفة.
      وإذا كان للمصفوفة بعدين أو أكثر فيمكن فقط تغيير حجم البعد الأخير مع الاحتفاظ بمحتويات المصفوفة.
      عندما نستخدم Preserve يمكن تغيير حجم المصفوفة بتغيير الحد الأعلى بينما ينتج لدينا خطأ حين تغيير الحد الأدنى.
      إذا صنعنا مصفوفة أصغر مما كانت فإن بيانات العناصر المخزنة سوف تفقد.
      إذا مررنا pass مصفوفة إلى Procedure بالـRefrence فإنه لا يمكن تغيير أبعادها من داخل الـProcedure.
      تحذير:

      جملة ReDim ستعمل وكأنها جملة إعلان إذا كان المتغير (المصفوفة) التي تعلن عنه غير موجود على مستوى الـProcedure أو الـModule. وإذا كان هناك متغير آخر بنفس الاسم قد أنشئ بعد ذلك وحتى لو كان في النطاق ككل Scope؛ فإن ReDim سوف ترجع للمتغير الأخير ولن يتسبب عن ذلك خطأ في الترجمة Compilation error حتى ولو كانت جملة Option Explicit فعّالة. وبذلك لن يدرك المبرمج أنه هناك خطأ بالشيفرة code.
      ولتفادي هذا التعارض لا ينبغي استخدام جملة ReDim كجملة إعلان بدلاً من Dim مثلاً، ولكن نستخدمها فقط لإعادة تعريف حجم المصفوفة.



      مثال(1):

      يبين المثال التالي كيف يمكن زيادة حجم البعد الأخير للمصفوفة متغيرة الحجم بدون محو البيانات الموجودة فيها:

      ReDim X(10,10,10)
      ReDim Preserve X(10,10,15)

      مثال(2):

      لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code) ويسأل عن عددها عند تشغيل الـcode:

      Dim X() As Integer
      N = InputBox("أدخل عدد العناصر من فضلك")
      ReDim X(N)
      For I = 1 To N
      X(I) = InputBox("أدخل عنصر من القائمة")
      Next I

      مثال(3):

      لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code)، ولا يسأل عن عددها عند تشغيل الـcode ولكن يقوم المستخدم بإدخال صفر (أو أي قيمة متقف عليها) عند الانتهاء من ادخال عناصر المصفوفة:

      Dim X()
      Do
      prompt=" أدخل عنصراً من القائمة وفي النهاية أدخل صفر"
      DummyVariable = InputBox(prompt)
      IF DummyVariable <> 0 Then
      UpperLimit = UpperLimit + 1
      ReDim Preserve X(UpperLimit)
      X(UpperLimit) = DummyVariable
      Else
      Exit Do
      End IF
      Loop




      وإلى هنا نكون قد انتهينا من دروس المصفوفات وجميع ما يتعلق بها في الفيجيوال بيسك، أرجو من الله أخي الكريم أن تفيدك :)



      منقول للأهمية

      أم حيدر علي
      [/CELL][/TABLE]
    • شكرا أختي على هذا المجهود وننتظر المزيد ..

      ولا يمكنك العمل على أي لغة بدون إستخدام المصفوفات (Arrays) في معظم التطبيقات ..



      تحياتي


      ¨°o.O ( على كف القدر نمشي ولا ندري عن المكتوب ) O.o°¨
      ---
      أتمنى لكم إقامة طيبة في الساحة العمانية

      وأدعوكم للإستفادة بمقالات متقدمة في مجال التقنية والأمن الإلكتروني
      رابط مباشر للمقالات هنا. ومن لديه الرغبة بتعلم البرمجة بلغات مختلفة أعرض لكم بعض
      المشاريع التي برمجتها مفتوحة المصدر ومجانا للجميع من هنا. تجدون أيضا بعض البرامج المجانية التي قمت بتطويرها بذات الموقع ..
      والكثير من أسرار التقنية في عالمي الثاني
      Eagle Eye Digital Solutions
    • حتى على السي بلس من الممكن إعادة تحجيم المصفوفة ... و بالتحديد باستخدام طبقات
      مكتبة MFC..وعادتا ما نحتاج لهذه العملية بتحجيم المصفوفة أثناء الدوران وإستخلاص
      النتائج لتسجيلها في عناصر المصفوفة أوالعمليات الطويلة والتي من الصعب تحديد نتائجها
      أو أن يكون عدد هذه النتائج مجهول و غير محدد...شرح جميل وراقي جدا جزيل الشكر
      على هذا الموضوع الرائع حقا ... في أمان الله .