بيان الإرجاع
في برمجة الحاسوب ، تتسبب عبارة الإرجاع في خروج التنفيذ من الروتين الفرعي الحالي واستئنافه من النقطة في الكود التي تلي مباشرةً التعليمة التي استدعت الروتين الفرعي، والمعروفة بعنوان الإرجاع . يحفظ الروتين المُستدعي عنوان الإرجاع، وعادةً ما يكون ذلك في مكدس استدعاءات العملية أو في سجل . تسمح عبارات الإرجاع في العديد من لغات البرمجة للدالة بتحديد قيمة إرجاع تُعاد إلى الكود الذي استدعى الدالة.
ملخص
في لغتي C و C++ ، تُعدّ عبارة `return` (حيث `a` تعبيرًا ) عبارةً تُخبر الدالةَ بإعادة تنفيذ البرنامج إلى الدالة المُستدعِية، مع الإبلاغ عن قيمة `a` . إذا كان نوع الإرجاع للدالة ` void` ، فيمكن استخدام عبارة `return` بدون قيمة، وفي هذه الحالة، يخرج البرنامج من الدالة الحالية ويعود إلى الدالة المُستدعِية. [ 1 ] [ 2 ] يُستخدم بناء جملة مشابه في لغات أخرى، بما في ذلك Modula-2 [ 3 ] و Python . [ 4 ]return exp;expexp
في لغة باسكال، لا توجد عبارة إرجاع. تُنهي الدوال والإجراءات عملها تلقائيًا عند الوصول إلى آخر عبارة فيها. تُحدد قيمة الإرجاع من الدالة داخلها عن طريق إسنادها إلى مُعرِّف يحمل نفس اسم الدالة. [ 5 ] مع ذلك، توفر بعض إصدارات باسكال دالةً خاصةً يمكن استخدامها لإرجاع قيمة مباشرةً من دالة، أو، بدون مُعاملات، للإرجاع مباشرةً من إجراء. [ 6 ]Exit(exp);
على غرار لغة باسكال، تحدد لغات فورتران 2 وفورتران 66 وفورتران 77 والإصدارات اللاحقة منها قيم الإرجاع من خلال إسنادها إلى اسم الدالة، ولكنها تحتوي أيضًا على عبارة إرجاع؛ لا تحدد هذه العبارة قيمة إرجاع، وبالنسبة للدالة، فإنها تتسبب في إرجاع القيمة المُسندة إلى اسم الدالة. [ 5 ] [ 7 ] [ 8 ]
في بعض اللغات الأخرى، يتم استخدام مُعامل إخراج مُحدد من قِبل المستخدم بدلاً من مُعرّف الدالة. [ 9 ]
يحتوي أوبرون ( أوبرون-07 ) على عبارة إرجاع بدلاً من عبارة إرجاع. توضع عبارة الإرجاع بعد آخر عبارة في جسم الإجراء. [ 10 ]
تسمح بعض لغات البرمجة الموجهة نحو التعبيرات ، مثل ليسب وبيرل وروبي ، للمبرمج بحذف عبارة الإرجاع الصريحة، مع تحديد أن آخر تعبير تم تقييمه هو قيمة الإرجاع للدالة الفرعية. في حالات أخرى، تُرجع قيمة فارغة (Null) إذا لم تكن هناك عبارة إرجاع صريحة: في بايثون ، تُرجع القيمة عند حذف عبارة الإرجاع، [ 4 ] بينما في جافا سكريبت تُرجع القيمة .Noneundefined
في Windows PowerShell، يتم إرجاع جميع التعبيرات التي تم تقييمها والتي لم يتم التقاطها (على سبيل المثال، تم تعيينها لمتغير، أو تحويلها إلى void أو تمريرها إلى $null ) من الروتين الفرعي كعناصر في مصفوفة، أو ككائن واحد في حالة عدم التقاط كائن واحد فقط.
في لغة بيرل، قد تعتمد القيمة أو القيم المُعادة من روتين فرعي على السياق الذي تم استدعاؤه فيه. يتمثل التمييز الأساسي في سياق عددي (scalar context) حيث يتوقع الكود المُستدعي قيمة واحدة، وسياق قائمة (list context) حيث يتوقع الكود المُستدعي قائمة من القيم، وسياق فارغ (void context) حيث لا يتوقع الكود المُستدعي أي قيمة مُعادة على الإطلاق. يمكن للروتين الفرعي التحقق من السياق باستخدام الدالة wantarray. تُستخدم صيغة خاصة للإرجاع بدون وسائط (return without arguments) لإعادة قيمة غير مُعرّفة في السياق العددي وقائمة فارغة في سياق القائمة. يمكن تقسيم السياق العددي إلى سياقات منطقية (Boolean )، ورقمية (number)، ونصية (string )، وأنواع مرجعية مختلفة . كما يمكن إرجاع كائن حساس للسياق باستخدام تسلسل إرجاع سياقي، مع تقييم كسول للقيم العددية.
تسمح العديد من أنظمة التشغيل للبرنامج بإرجاع نتيجة (منفصلة عن المخرجات العادية ) عند انتهاء عمليته؛ وتُعرف هذه القيم بحالات الخروج . كمية المعلومات التي يمكن تمريرها بهذه الطريقة محدودة للغاية، وغالبًا ما تقتصر عمليًا على الإشارة إلى النجاح أو الفشل. من داخل البرنامج، يتم عادةً إرجاع هذه النتيجة عن طريق استدعاء دالة الخروج (استدعاء النظام) (وهو أمر شائع حتى في لغة C، حيث تتوفر آلية بديلة للعودة من الدالة الرئيسية ).
بناء الجملة
تأتي عبارات الإرجاع بأشكال عديدة. فيما يلي أكثر الصيغ شيوعًا:
| لغة | بيان الإرجاع | إذا تم حذف القيمة، فسيتم إرجاعها |
|---|---|---|
| أدا ، بورن شيل ، سي ، سي++ ، سي# ، دي ، جافا ، جافا سكريبت ، بي إتش بي ، رست | القيمة المُعادة ؛ | في Bourne shell، قيمة الخروج للأمر الأخير الذي تم تنفيذه في الدالة في لغتي C [ 1 ] و C++ [ 2 ] ، يكون السلوك غير محدد إذا كانت الدالة تُرجع قيمة. في لغة PHP، تُرجع [ 12 ] في لغة جافا سكريبت، تُعيد [ 13 ] القيمة في لغتي جافا وسي شارب، لا يُسمح بذلك إذا كانت الدالة تُرجع قيمة. |
| أساسي | يعود | |
| التلعثم | ( القيمة المُعادة ) | قيمة البيان الأخير |
| بيرل ، روبي | إرجاع @values ؛ إرجاع $value ؛ إرجاع ؛أو تسلسل إرجاع سياقي | قيمة البيان الأخير |
| PL/I | أعد (التعبير)؛ يعود؛ | سلوك غير محدد إذا تم تعريف الإجراء على أنه يُرجع قيمة |
| بايثون | القيمة المُعادة | None[ 4 ] |
| أحاديث قصيرة | ^ القيمة | |
| تي سي إل | return return $value return - code error "رسالة الخطأ"أو مجموعة خيارات أكثر تعقيدًا | قيمة البيان الأخير |
| فيجوال بيسك دوت نت | القيمة المُعادة | |
| ويندوز باور شيل | القيمة المُعادة ؛ | هدف |
| تجميع x86 | ريت | محتويات سجل eax (حسب الاصطلاحات) |
في بعض لغات التجميع ، على سبيل المثال تلك الخاصة بـ MOS Technology 6502 ، يتم استخدام الاختصار "RTS" (العودة من الروتين الفرعي).
عبارات إرجاع متعددة
تتيح اللغات التي تحتوي على عبارة إرجاع صريحة إمكانية وجود عبارات إرجاع متعددة في نفس الدالة. ويُعدّ هذا الأمر مثيرًا للجدل من عدمه.
يحرص المؤيدون المتحمسون للبرمجة الهيكلية على أن يكون لكل دالة مدخل واحد ومخرج واحد (SESE). ولذلك، يُجادل [ 14 ] بأنه ينبغي تجنب استخدام عبارة الإرجاع الصريحة إلا في نهاية البرنامج الفرعي، نظرًا لأن استخدامها "للخروج المبكر" قد يُسبب نفس المشاكل التي تظهر مع عبارة GOTO . في المقابل، يُمكن القول إن استخدام عبارة الإرجاع مُجدٍ عندما يكون البديل شيفرة أكثر تعقيدًا، مثل التداخل العميق، مما يُؤثر سلبًا على سهولة القراءة.
في كتابه الدراسي الصادر عام ٢٠٠٤، يذكر ديفيد وات أن "تدفقات التحكم ذات المدخل الواحد والمخارج المتعددة مرغوبة في كثير من الأحيان". وباستخدام مفهوم " المُسلسل" الذي وضعه تيننت ، يصف وات بشكل موحد بنيات تدفق التحكم الموجودة في لغات البرمجة المعاصرة، ويحاول شرح سبب تفضيل أنواع معينة من المُسلسلات على غيرها في سياق تدفقات التحكم متعددة المخارج. ويشير وات إلى أن عبارات "goto" غير المقيدة (مُسلسلات القفز) غير مرغوبة لأن وجهة القفزة لا تكون واضحة لقارئ البرنامج حتى يعثر على العنوان أو التسمية الفعلية التي تمثل هدف القفزة ويفحصها. في المقابل، يرى وات أن الغرض المفاهيمي من مُسلسل الإرجاع واضح من سياقه، دون الحاجة إلى فحص وجهته. علاوة على ذلك، يذكر وات أن فئة من المُسلسلات تُعرف باسم مُسلسلات الهروب ، والتي تُعرَّف بأنها "مُسلسل يُنهي تنفيذ أمر أو إجراء مُحاط بنص"، تشمل كلاً من الخروج من الحلقات (بما في ذلك الخروج متعدد المستويات) وعبارات الإرجاع. يشير وات أيضًا إلى أنه على الرغم من أن تسلسلات القفز (goto) قد تم تقييدها إلى حد ما في لغات مثل C، حيث يجب أن يكون الهدف داخل الكتلة المحلية أو كتلة خارجية شاملة، إلا أن هذا التقييد وحده لا يكفي لجعل الغرض من goto في C واضحًا بذاته، وبالتالي لا يزال من الممكن أن ينتج عنه " كود سباغيتي ". كما يتناول وات كيفية اختلاف تسلسلات الاستثناءات عن تسلسلات الهروب والقفز؛ لمزيد من التفاصيل حول هذا الموضوع، انظر المقالة المتعلقة بالبرمجة الهيكلية. [ 15 ]
بحسب دراسات تجريبية استشهد بها إريك س. روبرتس ، واجه طلاب البرمجة صعوبة في صياغة حلول صحيحة لعدة مسائل بسيطة بلغة مثل باسكال، التي لا تسمح بنقاط خروج متعددة. فعلى سبيل المثال، في مسألة كتابة دالة للبحث الخطي عن عنصر في مصفوفة، وجدت دراسة أجراها هنري شابيرو عام 1980 (استشهد بها روبرتس) أنه باستخدام هياكل التحكم التي توفرها باسكال فقط، لم يقدم الحل الصحيح سوى 20% من المشاركين، بينما لم يكتب أي مشارك رمزًا برمجيًا خاطئًا لهذه المسألة إذا سُمح له بكتابة أمر إرجاع من منتصف حلقة تكرارية. [ 16 ]
ويرى آخرون، بمن فيهم كينت بيك ومارتن فاولر، أن استخدام شرط أو أكثر من شروط الحماية - وهي عبارات إرجاع مشروطة "للخروج المبكر" قرب بداية الدالة - غالباً ما يجعل قراءة الدالة أسهل من البديل. [ 17 ] [ 18 ] [ 19 ] [ 20 ]
تتمثل المشكلة الأكثر شيوعًا في الخروج المبكر في عدم تنفيذ عبارات التنظيف أو العبارات النهائية، على سبيل المثال، عدم تحرير الذاكرة المخصصة، أو عدم إغلاق الملفات المفتوحة، مما يؤدي إلى تسرب الذاكرة. يجب تنفيذ هذه العمليات عند كل نقطة عودة، وهو أمر هشّ وقد يؤدي بسهولة إلى ظهور أخطاء برمجية. على سبيل المثال، في مراحل التطوير اللاحقة، قد يتجاهل المطور عبارة العودة، وقد لا يتم تنفيذ إجراء يفترض تنفيذه في نهاية روتين فرعي (مثل عبارة التتبع ) في جميع الحالات. لا تعاني اللغات التي لا تحتوي على عبارة عودة، مثل لغة باسكال القياسية، من هذه المشكلة. تستخدم بعض اللغات، مثل C++ وبايثون، مفاهيم تسمح بتنفيذ الإجراءات تلقائيًا عند العودة (أو عند حدوث استثناء)، مما يخفف من بعض هذه المشكلات، وتُعرف هذه المفاهيم غالبًا باسم "try/finally" أو ما شابه. يمكن تنفيذ وظائف مثل عبارات "finally" هذه باستخدام عبارة goto للوصول إلى نقطة العودة الوحيدة للروتين الفرعي. يتمثل الحل البديل في استخدام عملية فك المكدس العادية (إلغاء تخصيص المتغيرات) عند الخروج من الدالة لإلغاء تخصيص الموارد، مثل استخدام المدمرات على المتغيرات المحلية، أو آليات مماثلة مثل عبارة "with" في بايثون.
قامت بعض التطبيقات المبكرة للغات مثل باسكال الأصلية ولغة سي بتقييد الأنواع التي يمكن إرجاعها بواسطة دالة (على سبيل المثال عدم دعم أنواع السجلات أو الهياكل ) لتبسيط مترجماتها .
في لغة جافا - واللغات المشابهة لها، مثل جافا سكريبت - يُمكن تنفيذ التعليمات البرمجية حتى بعد عبارة الإرجاع، لأن كتلة finally في بنية try-catch تُنفَّذ دائمًا. لذا، إذا وُضِعت عبارة الإرجاع داخل كتل try أو catch، فسيتم تنفيذ التعليمات البرمجية الموجودة داخل finally (إن وُضِعت). بل يُمكن أيضًا تغيير القيمة المُعادة من نوع غير بدائي (خاصية لكائن مُعاد بالفعل) لأن الخروج يحدث بعد ذلك أيضًا. [ 21 ]
بيانات العائد
تُعدّ عبارات yield شبيهة بعبارات return: فبينما تُنهي عبارة return روتينًا فرعيًا ، تُعلّق عبارة yield روتينًا فرعيًا . سيستأنف الروتين الفرعي عمله لاحقًا من حيث توقف إذا تم استدعاؤه مرة أخرى. تُعدّ الروتينات الفرعية أكثر تعقيدًا في التنفيذ من الروتينات الفرعية، ولذلك فإن عبارات yield أقل شيوعًا من عبارات return، ولكنها موجودة في عدد من لغات البرمجة.
تسلسلات الاستدعاء/الإرجاع
توجد عدة تسلسلات استدعاء/إرجاع ممكنة اعتمادًا على مجموعة تعليمات الأجهزة، مثل ما يلي:
- تقوم هذه
CALLالتعليمة بدفع عنوان التعليمة التالية إلى المكدس، ثم تنتقل إلى العنوان المحدد. بعد ذلك،RETURNتسحب التعليمة عنوان العودة من المكدس إلى مؤشر التعليمة، ويستأنف التنفيذ من ذلك العنوان. (أمثلة: x86 ، PDP-11 ). في معمارية مثل موتورولا 96000 ، قد تُخصص مساحة المكدس في حيز عناوين منفصل يُعرف باسم حيز ذاكرة المكدس ، [ 22 ] وهو يختلف عن حيز عناوين الذاكرة الرئيسية. [ 23 ] كما يتميز معالج NEC μPD7720 بمكدس ذي حيز عناوين منفصل خاص به. [ 24 ] - تضع هذه
CALLالتعليمة عنوان التعليمة التالية في سجل، ثم تنتقل إلى العنوان المحدد.RETURNيضع تسلسل التعليمات عنوان العودة من السجل في مؤشر التعليمات، ويستأنف التنفيذ من ذلك العنوان. (أمثلة: IBM System/360 وما تلاه حتى z/Architecture ، ومعظم معمارية RISC ) - تضع هذه
CALLالتعليمة عنوان التعليمة التالية (أو الحالية ) في موقع التخزين عند عنوان الاستدعاء، ثم تنتقل إلى العنوان المحدد + 1.RETURNينتقل تسلسل التعليمة إلى عنوان العودة عبر قفزة غير مباشرة إلى أول تعليمة في الروتين الفرعي. (أمثلة: IBM 1130 ، SDS 9XX ، PDP-8 )
انظر أيضاً
ملحوظات
مراجع
- 1 2 "عبارة الإرجاع (ج)" . وثائق مايكروسوفت . 25 يناير 2023.
- 1 2 "عبارة الإرجاع (C++)" . وثائق مايكروسوفت . 3 أغسطس 2021.
- ↑ غليفز، ر. (2012). مودولا-2 لمبرمجي باسكال . سبرينغر. ص 71. ISBN 9781461385318.
- 1 2 3 مارتيلي، أليكس (2006). بايثون باختصار: مرجع سريع لسطح المكتب ( الطبعة الثانية). أورايلي ميديا. ص 73. ISBN 9781449379100.
- 1 2 سكوت، مايكل ل. (2006). براغماتية لغات البرمجة . مورغان كوفمان. ص 432. ISBN 9780126339512.
- ↑ فلاندرز، هارلي (2012). باسكال العلمي . سبرينغر. ص 35. ISBN 9781461224280.
- ↑ معيار ANSI x3.9-1966. معيار الولايات المتحدة الأمريكية للغة فورتران (ملف PDF) . المعهد الوطني الأمريكي للمعايير. صفحة 14. مؤرشف من الأصل (ملف PDF) بتاريخ 15 مايو 2011. تم الاطلاع عليه بتاريخ 5 مايو 2010 .
{{cite book}}: صيانة CS1: الأسماء الرقمية: قائمة المؤلفين ( رابط ) - ↑ ANSI x3.9-1978. المعيار الوطني الأمريكي - لغة البرمجة فورتران . المعهد الوطني الأمريكي للمعايير. 15.8 عبارة RETURN. مؤرشف من الأصل في 29 أكتوبر 2013. تم الاطلاع عليه في 11 ديسمبر 2007 .
{{cite book}}: صيانة CS1: الأسماء الرقمية: قائمة المؤلفين ( رابط ) - ↑ ساكينين، ماركو (مارس 1989). "أفضل طريقة لإرجاع قيمة دالة" . إشعارات ACM SIGPLAN . 24 (3). رابطة آلات الحوسبة: 55-56 . doi : 10.1145/66083.66087 .
- ↑ ويرث، نيكلاوس (3 مايو 2016). "10. تعريفات الإجراءات". لغة البرمجة أوبرون (ملف PDF) (تقرير). ص 11.
- ↑ "العودة - العودة من دالة أو نص برمجي نقطي" . مواصفات يونكس الفردية .
- ↑ "PHP: return - Manual" . دليل PHP . مجموعة PHP . تم الاطلاع عليه بتاريخ 26 مارس 2013 .
- ↑ "إرجاع - جافا سكريبت" . مرجع جافا سكريبت MDN . شبكة مطوري موزيلا . تم الاطلاع عليه بتاريخ 27 مارس 2013 .
- ↑ شوارتز، فريد. "ملاحظات حول لغة C++: عبارة إرجاع الدالة" . مؤرشف من الأصل في 3 يناير 2007.
- ↑ وات، ديفيد أنتوني؛ فيندلاي، ويليام (2004). مفاهيم تصميم لغات البرمجة . جون وايلي وأولاده. الصفحات 215-221 . ISBN 978-0-470-85320-7.
- ↑ روبرتس، إي. (مارس 1995). "مخارج الحلقات والبرمجة الهيكلية: إعادة فتح النقاش" . نشرة ACM SIGCSE . 27 (1): 268-272 . doi : 10.1145/199691.199815 .
- ↑ مارتن فاولر؛ كينت بيك؛ جون برانت؛ ويليام أوبدايك؛ دون روبرتس (2012). إعادة هيكلة الكود: تحسين تصميم الكود الحالي (كتاب إلكتروني من جوجل) . أديسون-ويسلي. الصفحات 237، 250. ISBN 9780133065268...
عقلية نقطة الخروج الواحدة ... أنا لا أتبع قاعدة نقطة الخروج الواحدة من الدالة.
- ↑ كينت بيك (2007). "7: السلوك". أنماط التنفيذ . بيرسون للتعليم. قسم "بند الحماية". ISBN 9780132702553.
- ↑ "عبارات الإرجاع المتعددة" . ممارسات جافا .
- ↑ فريد شوارتز. "بيانات العائد ووهم المخرج الواحد" . مؤرشف من الأصل بتاريخ 23 فبراير 2020.
- ↑ "كتلة finally" . دروس جافا التعليمية .
- ↑ "دليل مستخدم معالج الإشارات الرقمية DSP96002 ذو 32 بت" ( ملف PDF) . الصفحات 3-4 . تاريخ الاطلاع: 24-12-2023 .
- ↑ "دليل مستخدم معالج الإشارات الرقمية DSP96002 ذو 32 بت" ( ملف PDF) . الصفحات 4-11 . تاريخ الاطلاع: 24-12-2023 .
- ↑ "معالج الإشارات الرقمية μPD77C20A، 7720A، 77P20" . ص 3أ - 4. تاريخ الاسترجاع: 25-12-2023 .
- أوامر BASIC
- البرامج الفرعية
