المتغير (لغة برمجة عالية المستوى)
في بعض لغات البرمجة عالية المستوى ، يُعرَّف المتغير بأنه موقع تخزين أو توجيه غير مباشر مُقترن باسم رمزي ، ويحتوي على كمية معروفة أو غير معروفة من البيانات أو الكائنات تُسمى قيمة ؛ أو بعبارة أبسط، المتغير هو حاوية مُسماة لمجموعة مُحددة من البتات أو نوع مُعين من البيانات (مثل عدد صحيح ، عدد عشري ، سلسلة نصية ، إلخ...) أو قيمة غير مُعرَّفة . [ 1 ] في بعض اللغات الأخرى مثل BASIC وPython وRuby، يُوصف المتغير بدقة أكبر بأنه اسم مُرتبط بقيمة، حيث تتم إدارة تخصيص الذاكرة بشفافية بواسطة المُفسِّر أو وقت التشغيل. يُمكن ربط المتغير بعنوان ذاكرة أو تحديده من خلاله . يُعد اسم المتغير الطريقة المُعتادة للإشارة إلى القيمة المُخزَّنة، بالإضافة إلى الإشارة إلى المتغير نفسه، وذلك حسب السياق. يسمح هذا الفصل بين الاسم والمحتوى باستخدام الاسم بشكل مُستقل عن المعلومات التي يُمثلها. يُمكن ربط المُعرِّف في شفرة المصدر الحاسوبية بقيمة أثناء وقت التشغيل ، وبالتالي قد تتغير قيمة المتغير أثناء تنفيذ البرنامج . [ 2 ] [ 3 ] [ 4 ] [ 5 ]
قد لا تتطابق المتغيرات في البرمجة بشكل مباشر مع مفهوم المتغيرات في الرياضيات . فالأخير مفهوم مجرد ، لا يرتبط بأي شيء مادي كموقع تخزين. كما أن قيمة المتغير في البرمجة ليست بالضرورة جزءًا من معادلة أو صيغة رياضية . علاوة على ذلك، يمكن أن تكون المتغيرات ثوابت إذا تم تعريف قيمتها بشكل ثابت. غالبًا ما تُعطى المتغيرات في البرمجة أسماءً طويلة لتسهيل وصف استخدامها، بينما في الرياضيات، غالبًا ما تكون أسماء المتغيرات مختصرة، من حرف أو حرفين، لتسهيل كتابتها ومعالجتها.
يمكن الإشارة إلى موقع تخزين المتغير بواسطة عدة معرّفات مختلفة، وهي حالة تُعرف باسم "الأسماء المستعارة" . سيؤدي تعيين قيمة للمتغير باستخدام أحد هذه المعرّفات إلى تغيير القيمة التي يمكن الوصول إليها من خلال المعرّفات الأخرى.
يتعين على المترجمات استبدال الأسماء الرمزية للمتغيرات بالمواقع الفعلية للبيانات. وبينما يظل اسم المتغير ونوعه وموقعه ثابتًا في الغالب، فإن البيانات المخزنة في ذلك الموقع قد تتغير أثناء تنفيذ البرنامج.
الإجراءات على متغير
في لغات البرمجة الإجرائية ، يمكن الوصول إلى القيم أو تغييرها في أي وقت. أما في لغات البرمجة الوظيفية والمنطقية البحتة ، فترتبط المتغيرات بتعبيرات وتحتفظ بقيمة واحدة طوال فترة وجودها ، وذلك لمتطلبات الشفافية المرجعية . وفي اللغات الإجرائية، يُلاحظ السلوك نفسه في الثوابت (المسماة) (الثوابت الرمزية)، والتي تُقارن عادةً بالمتغيرات (العادية).
بحسب نظام أنواع البيانات في لغة البرمجة، قد تقتصر المتغيرات على تخزين نوع بيانات محدد (مثل عدد صحيح أو سلسلة نصية ). أو قد يرتبط نوع البيانات بالقيمة الحالية فقط، مما يسمح لمتغير واحد بتخزين أي نوع بيانات تدعمه لغة البرمجة. المتغيرات هي حاويات لتخزين القيم.
المتغيرات والنطاق:
- المتغيرات التلقائية : كل متغير محلي في دالة ما لا يظهر إلا عند استدعاء الدالة ، ويختفي عند الخروج منها. تُعرف هذه المتغيرات بالمتغيرات التلقائية.
- المتغيرات الخارجية: هي متغيرات خارجة عن نطاق الدالة، ويمكن الوصول إليها بالاسم من أي دالة. تبقى هذه المتغيرات موجودة بشكل دائم؛ فبدلاً من أن تظهر وتختفي عند استدعاء الدوال والخروج منها، فإنها تحتفظ بقيمها حتى بعد انتهاء الدوال التي قامت بتعيينها.
المعرفات التي تشير إلى متغير
يمكن استخدام معرف يشير إلى متغير للوصول إلى المتغير من أجل قراءة القيمة، أو تغيير القيمة، أو تحرير سمات أخرى للمتغير، مثل إذن الوصول، والأقفال ، والإشارات ، وما إلى ذلك.
على سبيل المثال، قد تتم الإشارة إلى متغير بواسطة المعرف " total_count" ويمكن أن يحتوي المتغير على الرقم 1956. إذا تمت الإشارة إلى نفس المتغير بواسطة المعرف " r" أيضًا، وإذا تم استخدام هذا المعرف " r"، وتم تغيير قيمة المتغير إلى 2009، فإن قراءة القيمة باستخدام المعرف " total_count" ستعطي نتيجة 2009 وليس 1956.
إذا تمت الإشارة إلى متغير بمعرف واحد فقط، فيمكن تسمية هذا المعرف ببساطة باسم المتغير ؛ وإلا، فيمكننا الإشارة إليه كأحد أسماء المتغير . على سبيل المثال، في المثال السابق، المعرف " total_count" هو اسم المتغير المعني، و " r" هو اسم آخر لنفس المتغير.
النطاق والمدى
يُحدد نطاق المتغير موضع استخدامه في نص البرنامج، بينما يُحدد مداه (أو عمره ) متى يكون للمتغير قيمة (ذات معنى) أثناء تنفيذ البرنامج. ويؤثر نطاق المتغير على مداه. في الواقع، يُعد نطاق المتغير خاصيةً لاسمه، بينما يُعد مداه خاصيةً لموقع تخزينه. يجب عدم الخلط بين هذين الخاصيتين والسياق (أو البيئة )، الذي يُعد خاصيةً للبرنامج، ويتغير باختلاف موضعه في نص البرنامج أو أثناء تنفيذه - انظر: النطاق: نظرة عامة . علاوة على ذلك، قد يتزامن عمر الكائن مع عمر المتغير، ولكنه في كثير من الحالات لا يرتبط به.
يُعدّ النطاق جزءًا أساسيًا من عملية تحديد اسم المتغير. تُحدد معظم لغات البرمجة نطاقًا خاصًا لكل متغير (وكذلك أي كيان مُسمى آخر)، وقد يختلف هذا النطاق داخل البرنامج الواحد. نطاق المتغير هو جزء نص البرنامج الذي يكون لاسم المتغير فيه معنى، والذي يُقال فيه إن المتغير "مرئي". يبدأ عمر المتغير عادةً عند دخوله هذا النطاق (عند دخوله في سياق البرنامج)، وينتهي عند خروجه منه (عند خروجه من سياق البرنامج). على سبيل المثال، يكون للمتغير ذي " النطاق المعجمي " معنى فقط داخل دالة/ إجراء فرعي مُحدد ، أو بشكل أدق داخل كتلة من التعبيرات/العبارات (وفقًا لنطاق الدالة أو نطاق الكتلة )؛ وهذا ما يُعرف بالتحديد الثابت، والذي يُمكن تنفيذه أثناء التحليل أو الترجمة. في المقابل، يتم تحديد المتغير ذي النطاق الديناميكي أثناء التشغيل، بناءً على مكدس ربط عام يعتمد على مسار التحكم المُحدد . تُسمى المتغيرات التي لا يُمكن الوصول إليها إلا داخل دوال مُحددة " متغيرات محلية ". يمكن الإشارة إلى " المتغير العام "، أو المتغير ذي النطاق غير المحدد، في أي مكان في البرنامج.
أما النطاق ، فهو جانب ديناميكي (يحدث أثناء التشغيل ) للمتغير. لكل ربط لمتغير بقيمة نطاقه الخاص أثناء التشغيل. نطاق الربط هو الجزء من وقت تنفيذ البرنامج الذي يستمر فيه المتغير بالإشارة إلى نفس القيمة أو موقع الذاكرة. قد يدخل البرنامج قيد التشغيل ويخرج من نطاق معين عدة مرات، كما هو الحال في الإغلاق .
ما لم تدعم لغة البرمجة خاصية جمع البيانات المهملة ، فإن المتغير الذي يتجاوز نطاقه بشكل دائم قد يؤدي إلى تسرب الذاكرة ، حيث لا يمكن تحرير الذاكرة المخصصة للمتغير لأن المتغير الذي كان سيُستخدم للإشارة إليه لأغراض التحرير لم يعد متاحًا. مع ذلك، قد يكون من المسموح به أن يمتد ربط المتغير إلى ما بعد نطاقه، كما هو الحال في دوال الإغلاق في لغة ليسب والمتغيرات المحلية الثابتة في لغة سي ؛ فعندما يعود التنفيذ إلى نطاق المتغير، يمكن استخدامه مرة أخرى. يُقال إن المتغير الذي يبدأ نطاقه قبل امتداده غير مُهيأ ، وغالبًا ما تكون له قيمة غير مُحددة وعشوائية عند الوصول إليه (انظر المؤشر الجامح )، لأنه لم تُعطَ له قيمة مُحددة بشكل صريح. قد يصبح المتغير الذي ينتهي امتداده قبل نطاقه مؤشرًا معلقًا ويُعتبر غير مُهيأ مرة أخرى لأن قيمته قد فُقدت. يمكن القول إن المتغيرات الموصوفة في الحالتين السابقتين خارج النطاق أو غير مُرتبطة . في العديد من اللغات، يُعد استخدام قيمة متغير خارج النطاق خطأً. في لغات أخرى، قد يؤدي ذلك إلى نتائج غير متوقعة . ومع ذلك، يمكن إسناد قيمة جديدة إلى هذا المتغير، مما يمنحه نطاقًا جديدًا.
لتحقيق كفاءة استخدام المساحة، قد يتم تخصيص مساحة الذاكرة اللازمة لمتغير ما فقط عند استخدامه لأول مرة، ثم تحريرها عند انتهاء الحاجة إليها. لا يُحتاج إلى المتغير إلا عندما يكون ضمن نطاق التعريف، لذا فإن بدء دورة حياة كل متغير عند دخوله نطاق التعريف قد يتيح مساحة للمتغيرات غير المستخدمة. ولتجنب إهدار هذه المساحة، غالبًا ما تُنبه المترجمات المبرمجين في حال تم تعريف متغير دون استخدامه.
يُعتبر من الممارسات البرمجية الجيدة تضييق نطاق المتغيرات قدر الإمكان، وذلك لمنع أجزاء البرنامج المختلفة من التفاعل غير المقصود مع بعضها البعض عن طريق تعديل متغيرات بعضها. كما يمنع ذلك أيضًا التأثير عن بُعد . ومن التقنيات الشائعة لتحقيق ذلك استخدام مساحات أسماء مختلفة لأقسام البرنامج المختلفة ، أو جعل المتغيرات الفردية "خاصة" من خلال نطاق المتغيرات الديناميكي أو نطاق المتغيرات المعجمي .
تستخدم العديد من لغات البرمجة قيمة محجوزة (غالباً ما تسمى null أو nil ) للإشارة إلى متغير غير صالح أو غير مهيأ.
الكتابة
في اللغات ذات الكتابة الثابتة مثل C و C++ و Java و C# ، يكون للمتغير نوع ، مما يعني أنه لا يمكن تخزين سوى أنواع معينة من القيم فيه. على سبيل المثال، يُمنع تخزين القيم النصية في متغير من نوع " عدد صحيح ". [ 6 ]
في لغات البرمجة الديناميكية مثل بايثون ، يُستنتج نوع المتغير من قيمته، ويمكن أن يتغير تبعًا لقيمته. أما في لغة كومون ليسب ، فيوجد كلا الأمرين معًا: يُعطى المتغير نوعًا (إذا لم يُصرّح عنه، يُفترض أنه النوعT العام ) وهو نوع موجود وقت الترجمة. كما أن للقيم أنواعًا أيضًا، يمكن التحقق منها والاستعلام عنها وقت التشغيل.
يُتيح تحديد أنواع المتغيرات أيضًا حلّ تعدد الأشكال في وقت الترجمة. مع ذلك، يختلف هذا عن تعدد الأشكال المستخدم في استدعاءات الدوال الموجهة للكائنات (المعروفة بالدوال الافتراضية في لغة C++ )، حيث يتم حلّ الاستدعاء بناءً على نوع القيمة وليس على الأنواع الأصلية المسموح بها للمتغير.
تُستخدم المتغيرات عادةً لتخزين بيانات بسيطة، مثل الأعداد الصحيحة والسلاسل النصية، ولكن بعض لغات البرمجة تسمح للمتغيرات بتخزين قيم من أنواع بيانات أخرى أيضًا. كما تُمكّن هذه اللغات الدوال من أن تكون متعددة الأشكال ذات المعاملات . تعمل هذه الدوال كمتغيرات لتمثيل بيانات من أنواع متعددة. على سبيل المثال، قد تُحدد دالةٌ lengthما طول قائمة. lengthيمكن أن تكون هذه الدالة متعددة الأشكال ذات المعاملات من خلال تضمين متغير نوع في تعريف نوعها ، لأن عدد العناصر في القائمة مستقل عن أنواع هذه العناصر.
حدود
تُعرف المعاملات الرسمية (أو الوسائط الرسمية) للدوال أيضًا بالمتغيرات. على سبيل المثال، في مقطع كود بايثون هذا ،
دالة جمع اثنين ( س : عدد صحيح ) -> عدد صحيح : إرجاع س + 2print ( add_two ( 5 )) # عدد مرات الطباعة: 7المتغير المسمى xهو مُعامل لأنه يُعطى قيمة عند استدعاء الدالة. العدد الصحيح 5 هو الوسيط الذي يُعطيه xقيمته. في معظم لغات البرمجة، يكون نطاق مُعاملات الدوال محليًا. xلا يُمكن الإشارة إلى هذا المتغير المسمى إلا داخل add_twoالدالة (مع العلم أن الدوال الأخرى قد تحتوي أيضًا على متغيرات تحمل الاسم نفسه x).
تخصيص الذاكرة
تختلف تفاصيل تخصيص المتغيرات وتمثيل قيمها اختلافًا كبيرًا، سواء بين لغات البرمجة أو بين تطبيقات اللغة الواحدة. تُخصص العديد من تطبيقات اللغات مساحة للمتغيرات المحلية ، التي يستمر نطاقها لمدة استدعاء دالة واحدة على مكدس الاستدعاءات ، ويتم استعادة ذاكرتها تلقائيًا عند انتهاء الدالة. وبشكل عام، في ربط الأسماء ، يُربط اسم المتغير بعنوان كتلة معينة (تسلسل متجاور) من البايتات في الذاكرة، وتُجري العمليات على المتغير تعديلات على تلك الكتلة. أما الإشارة فهي أكثر شيوعًا للمتغيرات التي تكون قيمها ذات أحجام كبيرة أو غير معروفة عند ترجمة الكود. تشير هذه المتغيرات إلى موقع القيمة بدلًا من تخزين القيمة نفسها، والتي يتم تخصيصها من مجمع ذاكرة يُسمى الكومة .
للمتغيرات المقيدة قيم. مع ذلك، تُعدّ القيمة مفهومًا مجردًا، فكرة؛ وفي التطبيق، تُمثَّل القيمة بكائن بيانات يُخزَّن في مكان ما في ذاكرة الحاسوب. يجب على البرنامج، أو بيئة التشغيل ، تخصيص مساحة في الذاكرة لكل كائن بيانات، وبما أن الذاكرة محدودة، يجب ضمان إتاحة هذه المساحة لإعادة استخدامها عندما لا يعود الكائن مطلوبًا لتمثيل قيمة المتغير.
يجب استعادة الكائنات المُخصصة من الذاكرة الديناميكية (heap )، خاصةً عندما لا تعود هناك حاجة إليها. في اللغات التي تعتمد على جمع البيانات المهملة (مثل C# و Java و Python و Golang و Lisp )، تستعيد بيئة التشغيل الكائنات تلقائيًا عندما لا تستطيع المتغيرات الموجودة الإشارة إليها. أما في اللغات التي لا تعتمد على جمع البيانات المهملة، مثل C ، فيجب على البرنامج (والمبرمج) تخصيص الذاكرة بشكل صريح، ثم تحريرها لاحقًا، لاستعادة الذاكرة. يؤدي عدم القيام بذلك إلى تسرب الذاكرة ، حيث تُستنفد الذاكرة الديناميكية أثناء تشغيل البرنامج، مما يُعرّضه لخطر الفشل في نهاية المطاف نتيجة استنفاد الذاكرة المتاحة.
عندما يشير متغير إلى بنية بيانات مُنشأة ديناميكيًا، قد لا يُمكن الوصول إلى بعض مكوناتها إلا بشكل غير مباشر من خلال هذا المتغير. في مثل هذه الحالات، يتعين على جامعات البيانات المهملة (أو ميزات برمجية مماثلة في اللغات التي تفتقر إليها) التعامل مع حالة لا تتطلب استعادة سوى جزء من الذاكرة التي يُمكن الوصول إليها من المتغير.
اصطلاحات التسمية
على عكس نظيراتها الرياضية، تأخذ متغيرات وثوابت البرمجة عادةً أسماءً متعددة الأحرف، مثل `x` COSTأو total`y`. أما الأسماء المكونة من حرف واحد فتُستخدم في الغالب فقط للمتغيرات المساعدة؛ على سبيل المثال، i`x` jو`y` kلمتغيرات فهرسة المصفوفة .
تُفرض بعض قواعد التسمية على مستوى اللغة كجزء من قواعدها النحوية، والتي تتضمن تنسيق المعرّفات الصحيحة. في معظم اللغات، لا يمكن أن تبدأ أسماء المتغيرات برقم (من 0 إلى 9) ولا يمكن أن تحتوي على مسافات بيضاء. يختلف السماح باستخدام علامات الترقيم في أسماء المتغيرات من لغة إلى أخرى؛ فالعديد من اللغات تسمح فقط باستخدام الشرطة السفلية ("_") في أسماء المتغيرات وتمنع جميع علامات الترقيم الأخرى. في بعض لغات البرمجة، تُضاف رموز (أو علامات ترقيم) إلى معرّفات المتغيرات للإشارة إلى نوع بيانات المتغير أو نطاقه.
تختلف حساسية أسماء المتغيرات لحالة الأحرف بين اللغات، وتتطلب بعض اللغات استخدام حالة أحرف معينة في تسمية بعض الكيانات؛ [ ملاحظة 1 ] معظم اللغات الحديثة حساسة لحالة الأحرف، بينما لا تُراعيها بعض اللغات القديمة. تحتفظ بعض اللغات بأشكال معينة من أسماء المتغيرات لاستخدامها الداخلي؛ وفي كثير من اللغات، تندرج الأسماء التي تبدأ بشرطتين سفليتين ("__") ضمن هذه الفئة.
مع ذلك، وبغض النظر عن القيود الأساسية التي تفرضها لغة البرمجة، فإن تسمية المتغيرات مسألة أسلوبية في المقام الأول. فعلى مستوى لغة الآلة ، لا تُستخدم أسماء المتغيرات، لذا فإن الأسماء المختارة لا تهم الحاسوب. وبالتالي، فإن أسماء المتغيرات تُعرّفها، أما فيما عدا ذلك، فهي مجرد أداة للمبرمجين لتسهيل كتابة البرامج وفهمها. وقد يؤدي استخدام أسماء متغيرات غير مناسبة إلى صعوبة مراجعة الكود مقارنةً بالأسماء غير الواضحة، لذا يُنصح عادةً باستخدام أسماء واضحة. [ 7 ] [ 8 ]
كثيرًا ما يضع المبرمجون إرشاداتٍ لأسلوب كتابة الكود ويلتزمون بها، وهي إرشاداتٌ تُقدّم توجيهاتٍ حول تسمية المتغيرات أو تفرض نظام تسميةٍ دقيقًا. الأسماء القصيرة أسرع في الكتابة، لكنها أقل وضوحًا؛ أما الأسماء الطويلة فتجعل البرامج أسهل قراءةً، وتُسهّل فهم الغرض من المتغيرات. مع ذلك، قد يؤدي الإسهاب المفرط في أسماء المتغيرات إلى كودٍ أقل قابليةً للفهم.
أنواع المتغيرات (بناءً على مدة الحياة)
يمكننا تصنيف المتغيرات بناءً على دورة حياتها. أنواع المتغيرات هي: المتغيرات الثابتة، والمتغيرات الديناميكية المكدسية، والمتغيرات الديناميكية المكدسية الصريحة، والمتغيرات الديناميكية المكدسية الضمنية. يُعرف المتغير الثابت أيضًا بالمتغير العام، وهو مرتبط بخلية ذاكرة قبل بدء التنفيذ ويبقى فيها حتى انتهاء العملية. ومن الأمثلة الشائعة على ذلك المتغيرات الثابتة في لغتي C وC++. أما المتغير الديناميكي المكدسي فيُعرف بالمتغير المحلي، وهو مرتبط عند تنفيذ عبارة التصريح عنه، ويتم تحريره عند انتهاء العملية. ومن الأمثلة الرئيسية على ذلك المتغيرات المحلية في البرامج الفرعية بلغة C وطرق Java. المتغيرات الديناميكية المكدسية الصريحة هي خلايا ذاكرة مجردة (بدون اسم) يتم تخصيصها وتحريرها بواسطة تعليمات وقت التشغيل الصريحة التي يحددها المبرمج. ومن الأمثلة الرئيسية على ذلك الكائنات الديناميكية في لغة C++ (عبر new وdelete) وجميع الكائنات في Java. أما المتغيرات الديناميكية المكدسية الضمنية، فهي مرتبطة بمساحة التخزين المكدسية فقط عند إسناد قيم لها. ويحدث التخصيص والتحرير عند إعادة إسناد القيم إلى المتغيرات. ونتيجة لذلك، تتمتع المتغيرات الديناميكية الضمنية في الذاكرة الديناميكية بأعلى درجة من المرونة. ومن الأمثلة الرئيسية على ذلك بعض المتغيرات في جافا سكريبت وبي إتش بي، وجميع المتغيرات في لغة APL.
انظر أيضاً
ملحوظات
- ↑ على سبيل المثال، تتطلب لغة هاسكل أن تبدأ أسماء الأنواع بحرف كبير.
مراجع
- ↑ Brookshear 2019 ، ص 249 ، "المتغيرات وأنواع البيانات"، "تسمح لغات البرمجة عالية المستوى بالإشارة إلى المواقع في الذاكرة الرئيسية بواسطة أسماء وصفية بدلاً من العناوين الرقمية".
- ↑ أهو، ألفريد ف.؛ سيثي، رافي؛ أولمان، جيفري د. (1986)، المترجمات: المبادئ والتقنيات والأدوات ، ص 26-28 ، Bibcode : 1986cptt.book.....A
- ↑ كنوت، دونالد (1997). فن برمجة الحاسوب . المجلد 1 ( الطبعة الثالثة). ريدينغ، ماساتشوستس: أديسون-ويسلي. الصفحات 3-4 . ISBN 0-201-89683-4.
- ↑ "البرمجة باستخدام المتغيرات" . أكاديمية خان . تم الاطلاع عليه بتاريخ 23 مارس 2020 .
- ↑ "سكراتش للمبرمجين الناشئين" . جامعة هارفارد. مؤرشف من الأصل في 23 مارس 2020. تم الاطلاع عليه في 23 مارس 2020 .
- ↑ "الكتابة الثابتة - مسرد مصطلحات MDN Web Docs: تعريفات المصطلحات المتعلقة بالويب | MDN" . developer.mozilla.org . 2023-06-08 . تم الاطلاع عليه بتاريخ 2024-05-06 .
- ↑ كيفية تجنب اختيار المتغيرات ( مؤرشف بتاريخ 21-12-2016 في Wayback Machine ، تم الاطلاع عليه بتاريخ 11 يوليو 2012) [رابط معطل]
- ↑ إدسكار ديكسترا ، تباً لـ "المعرفات ذات المعنى"!
المراجع
- بروكشير، ج. جلين (2019). "علوم الحاسوب: نظرة عامة" (ملف PDF) . تم الاطلاع عليه بتاريخ 1 أبريل 2024 .
- متغير (علوم الحاسوب)
- مفاهيم لغة البرمجة
- أنواع البيانات
- نظرية الأنواع
