المعلمة (برمجة الحاسوب)
في برمجة الحاسوب ، يُعرف المُعامل ، أو الوسيط الرسمي ، بأنه متغير يُمثل وسيطًا لاستدعاء دالة . [ 1 ] [ 2 ] [ 3 ] [ 4 ] يُحدد توقيع الدالة مُعاملاتها. يتضمن استدعاء الدالة تقييم كل تعبير وسيط في الاستدعاء وربط النتيجة بالمُعامل المُناسب.
على سبيل المثال، لنأخذ دالة بايثون كمثال
دالة الجمع ( x : عدد صحيح ، y : عدد صحيح ) -> عدد صحيح : تُرجع x + yالمتغيرات xو yهي معاملات، كل منها من النوع int. بالنسبة للاستدعاء add(2, 3)، فإن التعبيرين 2و 3هما وسيطات. بالنسبة للاستدعاء add(a + 1, b + 2)، فإن الوسيطات هي a + 1و b+2.
يُحدد تمرير المعاملات بواسطة لغة البرمجة. وتُحدد استراتيجية التقييم دلالات كيفية تعريف المعاملات وكيفية تمرير الوسائط إلى الدالة. عمومًا، في حالة الاستدعاء بالقيمة ، يعمل المعامل كمتغير محلي جديد مُهيأ بقيمة الوسيط. إذا كان الوسيط متغيرًا، فلا يمكن للدالة تعديل حالته لأن المعامل نسخة منه. أما في حالة الاستدعاء بالمرجع ، الذي يتطلب أن يكون الوسيط متغيرًا، فيُعتبر المعامل اسمًا بديلًا للوسيط.
مثال
يُعرّف كود C المصدر التالي دالةً باسم مع مُعامل واحد باسم ؛ كل من الدالة والمُعامل من نوع . عند استدعاء ، يتم تمرير الوسيط إلى الدالة كقيمة عشرية 10 ويتم تعيينه لمتغير المُعامل ، وتُرجع الدالة القيمة 0.5.salesTaxpricedoublesalesTax(10.00)10.00price
double salesTax ( double price ) { return 0.05 * price ; }المعلمات والوسائط
قد يختلف معنى مصطلحي "المعامل" و "الوسيط" باختلاف لغات البرمجة. أحيانًا يُستخدمان بشكل متبادل، ويُستعان بالسياق لتمييز المعنى. يُستخدم مصطلح " المعامل" (ويُسمى أحيانًا " المعامل الرسمي ") غالبًا للإشارة إلى المتغير الموجود في تعريف الدالة ، بينما يُشير مصطلح "الوسيط" (ويُسمى أحيانًا " المعامل الفعلي ") إلى المُدخل الفعلي المُقدم عند استدعاء الدالة. على سبيل المثال، إذا عُرّفت دالة باسم `f` def f(x): ...، فإن x`f` هو المعامل، وإذا استُدعيت الدالة باستخدام ` f`، a = ...; f(a)فإن a`f` هو الوسيط. المعامل هو متغير (غير مُرتبط)، بينما يمكن أن يكون الوسيط قيمة حرفية أو متغيرًا أو تعبيرًا أكثر تعقيدًا يتضمن قيمًا حرفية ومتغيرات. في حالة الاستدعاء بالقيمة، ما يُمرر إلى الدالة هو قيمة الوسيط - على سبيل المثال، `f` f(2)و` a = 2; f(a)f` استدعاءان متكافئان - بينما في حالة الاستدعاء بالمرجع، مع متغير كوسيط، ما يُمرر هو مرجع إلى ذلك المتغير - حتى لو ظل بناء جملة استدعاء الدالة كما هو. [ 5 ] يتم تحديد نوع الاستدعاء (بالقيمة أو بالمرجع) في تعريف الدالة أو تعريفها.
تظهر المعاملات في تعريفات الإجراءات، بينما تظهر الوسائط في استدعاءات الإجراءات. في تعريف الدالة، يُعد f(x) = x * xالمتغير xمعاملاً، وفي استدعاء الدالة، f(2)تُمثل القيمة 2 وسيط الدالة. وبشكل عام، يُعتبر المعامل نوعًا، بينما يُعتبر الوسيط نسخةً منه.
المعامل هو خاصية جوهرية للإجراء، مُضمنة في تعريفه. على سبيل المثال، في العديد من لغات البرمجة، يحتاج إجراء جمع عددين صحيحين مُدخلين وحساب المجموع إلى معاملين، واحد لكل عدد. عمومًا، يمكن تعريف الإجراء بأي عدد من المعاملات، أو بدون أي معاملات على الإطلاق. إذا كان للإجراء معاملات، يُسمى الجزء من تعريفه الذي يُحدد هذه المعاملات بقائمة المعاملات .
على النقيض من ذلك، فإن الوسائط هي التعبيرات [ 6 ] المُقدمة إلى الإجراء عند استدعائه، وعادةً ما يكون تعبير واحد مطابقًا لأحد المعاملات. على عكس المعاملات، التي تُشكل جزءًا ثابتًا من تعريف الإجراء، قد تختلف الوسائط من استدعاء لآخر. في كل مرة يُستدعى فيها إجراء، يُطلق على جزء استدعاء الإجراء الذي يُحدد الوسائط اسم قائمة الوسائط .
على الرغم من أن المعاملات تُعرف أيضًا باسم الوسائط، إلا أنه يُنظر إلى الوسائط أحيانًا على أنها القيم الفعلية أو المراجع المُخصصة لمتغيرات المعاملات عند استدعاء الدالة أثناء التشغيل . عند مناقشة الكود الذي يستدعي دالة، فإن أي قيم أو مراجع تُمرر إلى الدالة تُعتبر وسائط، والمكان في الكود الذي تُعطى فيه هذه القيم أو المراجع يُسمى قائمة المعاملات . عند مناقشة الكود داخل تعريف الدالة، فإن المتغيرات الموجودة في قائمة معاملات الدالة هي المعاملات، بينما قيم المعاملات أثناء التشغيل هي الوسائط.
لنفترض دالة C التالية ، sum، والتي تحتوي على وسيطين، aو b. تقوم هذه الدالة بجمع القيم التي تم تمريرها إلى الوسيطين، وتعيد النتيجة إلى مستدعي الدالة.
دالة المجموع ( عدد صحيح أ ، عدد صحيح ب ) { إرجاع أ + ب ؛ }فيما يلي مثال على استدعاء الدالة . يتم تهيئة sumالمتغيرين xو ثم تمريرهما إلى الدالة كوسيطات. أثناء التشغيل، تُمرر القيم المُسندة إلى هذين المتغيرين إلى الدالة . في الدالة ، يتم تقييم المعاملين و ، مما ينتج عنه الوسيطين و ، على التوالي. تُجمع قيم الوسيطين، وتُعاد النتيجة إلى الدالة المستدعِية، حيث تُسند إلى المتغير .ysumsumsumab402result
int x = 40 ; int y = 2 ; int result = sum ( x , y );بسبب الفرق بين المعاملات والوسائط، من الممكن تمرير وسائط غير مناسبة إلى الإجراء. قد يُمرر الاستدعاء عددًا كبيرًا جدًا أو قليلًا جدًا من الوسائط، أو قد يكون أحد الوسائط أو أكثر من نوع خاطئ، أو قد تُمرر الوسائط بترتيب خاطئ. أي من هذه الحالات يُسبب عدم تطابق بين قوائم المعاملات والوسائط، وغالبًا ما يُعيد الإجراء إجابة غير متوقعة أو يُولد خطأً أثناء التشغيل .
اتفاقية بديلة في إيفل
في منهجية ولغة تطوير البرمجيات إيفل ، يُستخدم مصطلحا "الوسيط" و "المعامل" استخداماتٍ متميزة وفقًا للعرف. يُستخدم مصطلح "الوسيط " حصريًا للإشارة إلى مُدخلات الروتين، [ 7 ] بينما يُستخدم مصطلح "المعامل" حصريًا في تحديد أنواع المعاملات للفئات العامة . [ 8 ]
ضع في اعتبارك تعريف الروتين التالي:
مجموع ( أ : عدد صحيح ؛ ب : عدد صحيح ): عدد صحيح do النتيجة := أ + ب نهايةتأخذ الدالة sumوسيطين a، و ، يُطلق عليهما الوسيطان الرسميانb للدالة . ويحدد استدعاء الدالة الوسائط الفعلية ، كما هو موضح أدناه باستخدام و .sumxy
النتيجة : عدد صحيح x : عدد صحيح = 40 y : عدد صحيح = 2 … النتيجة := مجموع ( x ، y )تُصنف المعاملات أيضًا إلى معاملات رسمية ومعاملات فعلية . تُستخدم المعاملات العامة الرسمية في تعريف الفئات العامة. في المثال أدناه، HASH_TABLE تم تعريف الفئة كفئة عامة تحتوي على معاملين عامين رسميين، أحدهما Gيمثل البيانات المطلوبة والآخر Kيمثل مفتاح التجزئة لهذه البيانات.
class HASH_TABLE [ G , K -> HASHABLE ] …عندما يصبح صنفٌ ما عميلاً لـ HASH_TABLE، تُستبدل المعاملات العامة الرسمية بمعاملات عامة فعلية في اشتقاق عام . في تعريف السمة التالي، my_dictionaryسيتم استخدام كقاموس قائم على سلسلة نصية . على هذا النحو، يتم استبدال كل من المعاملات العامة الرسمية للبيانات والمفتاح بمعاملات عامة فعلية من النوع .STRING
قاموسي : جدول التجزئة [ سلسلة نصية ، سلسلة نصية ]أنواع البيانات
في لغات البرمجة ذات الأنواع القوية ، يجب تحديد نوع كل مُعامل في تعريف الإجراء. أما اللغات التي تستخدم استنتاج الأنواع، فتحاول اكتشاف الأنواع تلقائيًا من جسم الدالة واستخدامها. بينما تؤجل لغات البرمجة ذات الأنواع الديناميكية تحديد الأنواع حتى وقت التشغيل. أما اللغات ذات الأنواع الضعيفة، فلا تُجري سوى القليل من تحديد الأنواع، أو لا تُجريه على الإطلاق، معتمدةً بدلًا من ذلك على المبرمج لضمان صحة النتائج.
تستخدم بعض اللغات كلمة مفتاحية خاصة (مثلاً void) للإشارة إلى أن الدالة ليس لها معلمات؛ في نظرية النوع الرسمية ، تأخذ هذه الدوال قائمة معلمات فارغة (التي ليس نوعها void، بل نوع الوحدة ).
تمرير الوسائط
تعتمد آلية تعيين الوسائط للمعاملات، والتي تسمى تمرير الوسائط ، على استراتيجية التقييم المستخدمة لهذا المعامل (عادةً ما تكون الاستدعاء بالقيمة )، والتي يمكن تحديدها باستخدام الكلمات الرئيسية.
الوسائط الافتراضية
تسمح بعض لغات البرمجة، مثل Ada وC++ وClojure وCommon Lisp وFortran 90 وPython وRuby وTcl وWindows PowerShell، بتحديد وسيط افتراضي صراحةً أو ضمنًا في تعريف الدالة . وهذا يُمكّن المُستدعي من حذف هذا الوسيط عند استدعاء الدالة . إذا تم تحديد الوسيط الافتراضي صراحةً، فسيتم استخدام قيمته في حال عدم تحديده من قِبل المُستدعي. أما إذا كان الوسيط الافتراضي ضمنيًا (أحيانًا باستخدام كلمة مفتاحية مثل Optional ) ، فإن اللغة تُوفّر قيمة معروفة (مثل null أو Empty أو zero أو سلسلة نصية فارغة، إلخ) في حال عدم تحديد قيمة من قِبل المُستدعي.
مثال على استخدام PowerShell:
function doc ( $g = 1 . 21 ) { "$g جيجاوات؟ $g جيجاوات؟ يا إلهي!" }ملاحظة: هل هذا صحيح ؟ 1.21 جيجاوات؟ 1.21 جيجاوات؟ يا إلهي!ملاحظة: المستند رقم 88، 88 جيجاوات؟ 88 جيجاوات؟ يا إلهي!يمكن اعتبار الوسائط الافتراضية حالة خاصة من قائمة الوسائط ذات الطول المتغير.
قوائم المعلمات ذات الطول المتغير
تسمح بعض لغات البرمجة بتعريف الدوال بحيث تقبل عددًا متغيرًا من الوسائط . في هذه اللغات، يجب أن تتكرر الدوال عبر قائمة الوسائط.
مثال على استخدام PowerShell:
دالة مارتي { $args | foreach { "العودة إلى السنة $_" } }ملاحظة: مارتي 1985، العودة إلى عام 1985ملاحظة: مارتي ٢٠١٥ ١٩٨٥ ١٩٥٥ العودة إلى عام ٢٠١٥ العودة إلى عام ١٩٨٥ العودة إلى عام ١٩٥٥المعلمات المسماة
تسمح بعض لغات البرمجة، مثل Ada و Windows PowerShell ، للدوال بمعاملات مُسماة . وهذا يُتيح أن يكون الكود المُستدعي أكثر وضوحًا . كما يُوفر مرونة أكبر للمُستدعي، حيث يسمح غالبًا بتغيير ترتيب الوسائط، أو حذفها حسب الحاجة.
مثال على استخدام PowerShell:
دالة جينيفر ( الصفة الشابة ، الصفة الكبيرة ) { "جينيفر الشابة: أنا الصفة الشابة!" "جينيفر الكبيرة: أنا الصفة الكبيرة!" }ملاحظة: جينيفر "طازجة" "ذات خبرة" جينيفر الشابة: أنا طازجة! جينيفر العجوز: أنا ذات خبرة!ملاحظة: جينيفر - صفة قديمة "ذات خبرة" - صفة شابة "منتعشة" جينيفر الشابة: أنا منتعشة! جينيفر القديمة: أنا ذات خبرة!المعاملات المتعددة في اللغات الوظيفية
في حساب لامدا ، تحتوي كل دالة على مُعامل واحد فقط. ما يُعتبر عادةً دوالًا متعددة المعاملات يُمثل في حساب لامدا كدالة تأخذ المُعامل الأول، وتُعيد دالة أخرى تأخذ باقي المُعاملات. يُسمى هذا التحويل " التقسيم الجزئي ". تتبع بعض لغات البرمجة، مثل ML و Haskell ، هذا النمط. في هذه اللغات، تحتوي كل دالة على مُعامل واحد فقط، وما قد يبدو كتعريف لدالة متعددة المعاملات، هو في الواقع اختصار برمجي لتعريف دالة تُعيد دالة أخرى، وهكذا. تطبيق الدوال في هذه اللغات وحساب لامدا هو تطبيق تجميعي من اليسار ، لذا فإن ما يبدو كتطبيق لدالة على مُعاملات متعددة يُقيّم بشكل صحيح على أنه تطبيق الدالة على المُعامل الأول، ثم تطبيق الدالة الناتجة على المُعامل الثاني، وهكذا.
معلمات الإخراج
مُعامل الإخراج ، المعروف أيضًا باسم مُعامل الإخراج أو مُعامل الإرجاع ، هو مُعامل يُستخدم للإخراج، وليس للإدخال كما هو شائع. يُعد استخدام مُعاملات الاستدعاء بالمرجع ، أو مُعاملات الاستدعاء بالقيمة حيث تكون القيمة مرجعًا، كمُعاملات إخراج، أسلوبًا شائعًا في بعض اللغات، وخاصةً C وC++، [ أ ] بينما تدعم لغات أخرى مُعاملات الإخراج بشكلٍ مُدمج. تشمل اللغات التي تدعم مُعاملات الإخراج بشكلٍ مُدمج: Ada [ 11 ] (انظر البرامج الفرعية في Ada )، وFortran (منذ Fortran 90 ؛ انظر "intent" في Fortran )، والعديد من الامتدادات الإجرائية للغة SQL ، مثل PL/SQL (انظر دوال PL/SQL ) [ 12 ] و Transact-SQL ، و C# [ 13 ] وإطار عمل .NET ، [ 14 ] و Swift ، [ 15 ] ولغة البرمجة النصية TScript (انظر تعريفات دوال TScript ).
فيما يلي مثال على "معامل الإخراج" في لغة C++:
// تعريف دالة ذات مُعامل إخراج void sum ( int x , int y , int & out ) { out = x + y ; }// الاستخدام: int foo = 1 ; int bar = 2 ; int baz ; sum ( foo , bar , baz );x + yلن تُرجع الدالة أي شيء، ولكن سيتم تعيين قيمة المتغير الذي تم تمرير مرجعout إليه كـ .
وبشكل أدق، يمكن للمرء أن يميز ثلاثة أنواع من المعلمات أو أنماط المعلمات :معلمات الإدخال s،ومعلمات الإخراج،ومعلمات الإدخال/الإخراج ؛ويُشار إليها غالبًا بـ rinوoutl وin outأوinoutr/l. يجب أن تكون وسيطة الإدخال (الوسيط المُمرَّر إلى مُعامل الإدخال) قيمةً، مثل متغير مُهيأ أو قيمة حرفية، ويجب عدم إعادة تعريفها أو إسناد قيمة لها. يجب أن تكون وسيطة الإخراج متغيرًا قابلًا للإسناد، ولكن ليس من الضروري تهيئته، ولا يمكن الوصول إلى أي قيمة موجودة فيه، ويجب إسناد قيمة لها. يجب أن تكون وسيطة الإدخال/الإخراج متغيرًا مُهيأً وقابلًا للإسناد، ويمكن إسناد قيمة لها اختياريًا. تختلف المتطلبات الدقيقة وآليات التنفيذ بين اللغات - على سبيل المثال، في لغةAda 83،لا يمكن قراءة معلمات الإخراج، بل إسناد قيمة لها فقط، حتى بعد إسنادها (تم حذف هذا فيلغة Ada 95لإزالة الحاجة إلى متغير تراكمي مساعد). تُشابه هذه المفاهيم مفهومالقيمةفي التعبير، سواء كانت قيمة يمين (rvalue) (لها قيمة)، أو قيمة يسار (lvalue) (يمكن إسناد قيمة لها)، أو قيمة يمين/يسار (rvalue/lvalue) (لها قيمة ويمكن إسناد قيمة لها)، على التوالي، على الرغم من أن هذه المصطلحات لها معانٍ خاصة في لغتي C وC++.
في بعض الحالات، يُفرَّق بين الإدخال والإدخال/الإخراج فقط، مع اعتبار الإخراج استخدامًا خاصًا للإدخال/الإخراج، وفي حالات أخرى، يُدعم الإدخال والإخراج فقط (وليس الإدخال/الإخراج). يختلف الوضع الافتراضي بين اللغات: في فورتران 90، يكون الإدخال/الإخراج هو الوضع الافتراضي، بينما في لغة C# وامتدادات SQL، يكون الإدخال هو الوضع الافتراضي، وفي TScript، يُحدَّد كل مُعامل صراحةً كمدخل أو مخرج.
من الناحية التركيبية، يُشار إلى وضع المعاملات عادةً بكلمة مفتاحية في تعريف الدالة، كما هو الحال في لغة C#. تقليديًا، تُوضع معاملات الإخراج في نهاية قائمة المعاملات لتمييزها بوضوح، مع أن هذا ليس شرطًا دائمًا. تستخدم لغة TScript نهجًا مختلفًا، حيث تُدرج معاملات الإدخال أولًا، ثم معاملات الإخراج، مفصولة بنقطتين رأسيتين (:)، ولا يوجد نوع إرجاع للدالة نفسها، كما في هذه الدالة التي تحسب حجم جزء نصي:voidFn(outintx)
TextExtent ( WString text , Font font : Integer width , Integer height )أنماط المعاملات هي شكل من أشكال الدلالات التوضيحية ، تُحدد نية المبرمج وتُمكّن المُترجمات من اكتشاف الأخطاء وتطبيق التحسينات، ولا تُشير بالضرورة إلى الدلالات التشغيلية (كيفية تمرير المعاملات فعليًا). والجدير بالذكر أنه بينما يُمكن تنفيذ معاملات الإدخال بالقيمة، ومعاملات الإخراج ومعاملات الإدخال/الإخراج بالمرجع - وهذه طريقة مباشرة لتنفيذ هذه الأنماط في اللغات التي لا تدعمها بشكل مُدمج - إلا أن هذه ليست الطريقة المُتبعة دائمًا. يُناقش هذا التمييز بالتفصيل في مُبررات Ada '83، التي تُؤكد أن نمط المعاملات مُجرّد من آلية تمرير المعاملات المُستخدمة فعليًا (بالمرجع أو بالنسخ). [ 11 ] على سبيل المثال، في لغة C#، تُمرَّر معلمات الإدخال (افتراضيًا، بدون كلمة مفتاحية) بالقيمة، بينما تُمرَّر معلمات الإخراج ومعلمات الإدخال/الإخراج ( outو ) بالمرجع. أما في لغة PL/SQL ، فتُمرر معلمات الإدخال () بالمرجع، بينما تُمرَّر معلمات الإخراج ومعلمات الإدخال/الإخراج ( و ) افتراضيًا بالقيمة ويتم نسخ النتيجة، ولكن يمكن تمريرها بالمرجع باستخدام تلميح المُصرِّف . [ 16 ]refINOUTIN OUTNOCOPY
يُعدّ إسناد القيمة المُعادة إلى متغير يحمل نفس اسم الدالة طريقةً مشابهةً من الناحية التركيبية لمعاملات الإخراج. يُمكن إيجاد هذه الطريقة في لغات باسكال وفورتران 66 وفورتران 77 ، كما في مثال باسكال التالي:
دالة f ( x , y : عدد صحيح ) : عدد صحيح ; بداية f := x + y ; نهاية ;يختلف هذا من الناحية الدلالية حيث أنه عند استدعاء الدالة، يتم تقييمها ببساطة - لا يتم تمرير متغير من نطاق الاستدعاء لتخزين الناتج فيه.
يستخدم
يُستخدم مُعاملات الإخراج بشكل أساسي لإرجاع قيم متعددة من دالة، بينما يُستخدم مُعاملات الإدخال/الإخراج لتعديل الحالة باستخدام تمرير المُعاملات (بدلاً من استخدام بيئة مشتركة، كما هو الحال في المُتغيرات العامة). ومن الاستخدامات المهمة لإرجاع قيم متعددة حل مشكلة شبه المُسند، وهي إرجاع قيمة وحالة خطأ معًا - انظر: مشكلة شبه المُسند: الإرجاع متعدد القيم .
على سبيل المثال، لإرجاع متغيرين من دالة في لغة C، يمكن كتابة ما يلي:
int width ; int height ;f ( x , & width , & height );حيث xيمثل معامل إدخال و widthو heightهما معاملا إخراج؛ يشير الرمز "&" في &widthو &heightإلى عناوين الذاكرة لـ widthو height.
يُعدّ التعامل مع الاستثناءات من الاستخدامات الشائعة في لغة C واللغات المشابهة ، حيث تقوم الدالة بتخزين القيمة المُعادة في متغير إخراج، وتُعيد قيمة منطقية تُشير إلى نجاح أو فشل الدالة. ومن الأمثلة النموذجية على ذلك الدالة TryParseفي بيئة .NET، وخاصةً في لغة C#، التي تُحلل سلسلة نصية إلى عدد صحيح، وتُعيد قيمة منطقية trueعند النجاح وقيمة منطقية falseعند الفشل. ولها التوقيع التالي: [ 17 ]
public static bool TryParse ( string s , out int result )ويمكن استخدامها على النحو التالي:
باستخدام النظام ؛int result ; if ( ! Int32.TryParse ( s , result ) ) { // معالجة الاستثناء }تنطبق اعتبارات مماثلة على إرجاع قيمة من أحد الأنواع الممكنة العديدة، حيث يمكن لقيمة الإرجاع تحديد النوع ثم يتم تخزين القيمة في أحد متغيرات الإخراج المتعددة.
العيوب
غالبًا ما يُنصح بتجنب استخدام مُعاملات الإخراج في البرمجة الحديثة، نظرًا لكونها مُربكة ومُعقدة وذات مستوى منخفض للغاية، إذ تُعدّ قيم الإرجاع الشائعة أسهل بكثير في الفهم والتعامل معها. [ 18 ] ومن الجدير بالذكر أن مُعاملات الإخراج تتضمن دوالًا ذات تأثيرات جانبية (تُعدّل مُعامل الإخراج)، وهي تُشبه دلاليًا المراجع، التي تُعدّ أكثر إرباكًا من الدوال والقيم البحتة، وقد يكون التمييز بين مُعاملات الإخراج ومُعاملات الإدخال/الإخراج دقيقًا. علاوة على ذلك، ولأن معظم المُعاملات في أساليب البرمجة الشائعة هي مُعاملات إدخال فقط، فإن مُعاملات الإخراج ومُعاملات الإدخال/الإخراج غير شائعة، وبالتالي فهي عُرضة لسوء الفهم.
تمنع معلمات الإخراج ومعلمات الإدخال/الإخراج تركيب الدوال ، لأن الإخراج يُخزَّن في متغيرات، وليس في قيمة تعبير. لذا، يجب تعريف متغير في البداية، ثم تُمثَّل كل خطوة من سلسلة الدوال بعبارة منفصلة. على سبيل المثال، في لغة C++، يكون تركيب الدوال كما يلي:
MyObject obj = g ( y , f ( x ));عند كتابتها باستخدام معلمات الإخراج ومعلمات الإدخال/الإخراج، تصبح بدلاً من ذلك (لأنها Fمعلمة إخراج، ولأنها Gمعلمة إدخال/إخراج):
MyObject obj ; f ( x , & obj ); g ( y , & obj );في الحالة الخاصة لدالة ذات مُخرَج واحد أو مُدخل/مُخرَج واحد وبدون قيمة إرجاع، يكون تركيب الدوال ممكنًا إذا تم إرجاع مُخرَج أو مُدخل/مُخرَج واحد (أو عنوانه في لغة C/C++) بواسطة الدالة أيضًا، وفي هذه الحالة يصبح ما سبق كالتالي:
MyObject obj ; g ( y , f ( x , & obj ));البدائل
توجد بدائل متنوعة لحالات استخدام معلمات الإخراج.
لإرجاع قيم متعددة من دالة، يُمكن استخدام بديل وهو إرجاع مجموعة (tuple) . من الناحية التركيبية، يكون هذا أوضح إذا أمكن استخدام فك تسلسل تلقائي وتعيين متوازٍ ، كما هو الحال في لغتي Go أو Python، على سبيل المثال:
def f () -> tuple [ int , int ]: return 1 , 2 a , b = f ()لإرجاع قيمة من أحد أنواع متعددة، يمكن استخدام اتحاد مُوسَم ؛ وأكثر الحالات شيوعًا هي الأنواع القابلة للتصفير ( أنواع الخيارات )، حيث يمكن أن تكون القيمة المُرجعة فارغة للإشارة إلى الفشل. لمعالجة الاستثناءات، يمكن إرجاع نوع قابل للتصفير، أو إطلاق استثناء. على سبيل المثال، في بايثون، قد يكون لدينا أحد الخيارين التاليين:
النتيجة : str = parse ( s ) إذا كانت النتيجة None : # معالجة الاستثناءاتأو، بتعبير أكثر اصطلاحية:
حاول : النتيجة : str = parse ( s ) باستثناء ParseError : # معالجة الاستثناءاتيمكن أيضًا تطبيق التحسين الدقيق المتمثل في عدم الحاجة إلى متغير محلي ونسخ القيمة المرجعة عند استخدام متغيرات الإخراج على الدوال التقليدية وقيم الإرجاع بواسطة المترجمات المتطورة بما فيه الكفاية.
البديل المعتاد لمعاملات الإخراج في لغة C واللغات المشابهة هو إرجاع بنية بيانات واحدة تحتوي على جميع القيم المُعادة. [ 13 ] على سبيل المثال، إذا كانت لدينا بنية بيانات تحتوي على العرض والارتفاع، فيمكننا كتابة ما يلي:
العرض والارتفاع wh = f ( x );في لغات البرمجة الكائنية، بدلاً من استخدام معلمات الإدخال/الإخراج، يمكن في كثير من الأحيان استخدام الاستدعاء عن طريق المشاركة ، حيث يتم تمرير مرجع إلى كائن ثم تعديل الكائن، دون تغيير الكائن الذي يشير إليه المتغير. [ 18 ]
انظر أيضاً
ملحوظات
- ↑ يتم استدعاء C و C++ عن طريق القيمة، ولكن إذا كان النوع عبارة عن مرجع (مؤشر C/C++ أو مرجع C++)، فيمكن استخدام تعيين قيمة المرجع لإنتاج سلوك نمط الاستدعاء عن طريق المرجع.
مراجع
- ↑ "تمرير المعلومات إلى دالة أو مُنشئ (تعلم لغة جافا > الفئات والكائنات)" . دروس جافا™ التعليمية . تم الاطلاع عليه بتاريخ 9 سبتمبر 2021. تشير
المعاملات إلى قائمة المتغيرات في تعريف الدالة. أما الوسائط فهي القيم الفعلية التي يتم تمريرها عند استدعاء الدالة. عند استدعاء دالة، يجب أن تتطابق الوسائط المستخدمة مع معاملات التعريف من حيث النوع والترتيب.
- ^ براتا ، ستيفن (2004). C التمهيدي زائد (الطبعة الخامسة ). سامز. ص 276 – 277. ISBN 978-0-672-32696-7.
- ↑ "مسودة عمل، معيار للغة البرمجة C++" (ملف PDF) . المعايير المفتوحة . 19 أكتوبر 2005. مؤرشف من الأصل (ملف PDF) في 14 ديسمبر 2005. تم الاطلاع عليه في 1 يناير 2018 .
- ↑ غوردون، آرون. "البرامج الفرعية وتمرير المعاملات" . rowdysites.msudenver.edu/~gordona . مؤرشف من الأصل في 1 يناير 2018. تم الاطلاع عليه في 1 يناير 2018 .
- ↑ دولارد، كاثلين. "تمرير الوسائط بالقيمة وبالمرجع (فيجوال بيسك)" . مايكروسوفت ليرن . تم الاسترجاع في 27-10-2018 .
- ↑ "دليل برمجة GNU C" . crasseux.com . تم الاطلاع عليه بتاريخ 27-10-2018 .
- ↑ ماير، برتراند. بناء البرمجيات الموجهة للكائنات ، الطبعة الثانية، برنتيس هول، 1997، ص 444.
- ↑ ماير، ص 96.
- ↑ "الوظائف" . gigamonkeys.com . تم الاطلاع عليه بتاريخ 2021-06-02 .
- ↑ "الوسائط الاختيارية" . www.netlib.org . تم الاطلاع عليه بتاريخ 2021-06-02 .
- 1 2 8.2 أوضاع المعلمات ، " الأساس المنطقي لتصميم لغة برمجة Ada® "
- ↑ 8. البرامج الفرعية PL/SQL: تحديد أوضاع معلمات البرنامج الفرعي
- 1 2 بيتر هالام. "لماذا تحتوي لغة C# على كل من 'ref' و 'out'؟" . مؤرشف من الأصل بتاريخ 26-09-2011.
- ↑ تعداد اتجاه المعلمات
- ↑ الدوال — لغة البرمجة Swift (Swift 4.2)
- ↑ ٨. البرامج الفرعية PL/SQL: تمرير هياكل البيانات الكبيرة باستخدام NOCOPY (تلميح للمترجم)
- ↑ دالة Int32.TryParse (سلسلة نصية، عدد صحيح 32)
- 1 2 CA1021: تجنب معلمات الإخراج
- البرامج الفرعية
- متغير (علوم الحاسوب)
