رسم بياني للمقارنة:
أساس للمقارنة | Call_By_Value | دعوة حسب المرجع |
---|---|---|
الأساسية | يتم تمرير نسخة من المتغير. | يتم تمرير متغير نفسه. |
تأثير | لا يؤدي التغيير في نسخة المتغير إلى تعديل القيمة الأصلية للمتغير الجانب الخارجي للوظيفة. | يؤثر التغيير في المتغير على قيمة المتغير خارج الوظيفة أيضًا. |
استدعاء المعلمات | function_name (variable_name1، variable_name2،....)؛ | function_name (& variable_name1، & variable_name2،....)؛ // في حالة الكائن object.func_name (الكائن)؛ |
تلقي المعلمات | اكتب function_name (اكتب variable_name1 ، اكتب variable_name2 ، ...). {. . } | type function_name (type * variable_name1، type * variable_name2،....) {. . } // في حالة الكائن اكتب function_name (class_type object_name) {. . } |
الاتصال الافتراضي | يتم تمرير النوع البدائي باستخدام "call by value". | يتم تمرير الكائنات ضمنيًا باستخدام "استدعاء حسب المرجع". |
تعريف المكالمة حسب القيمة
إذا قمت بتمرير نوع بيانات أولية (عدد صحيح ، وحرف ، وسلسلة) إلى دالة / طريقة ، فعندئذ يتم تمرير "القيمة" فقط إلى رمز الوظيفة. تنسخ الدالة قيمة تلك الوسيطة إلى "معلمة رسمية" لشفرة الدوال. إذا كان هناك أي تعديل للمعلمة الرسمية في رمز الدالة ، فلن يقوم بتعديل القيمة الأصلية للوسيطة المستخدمة في استدعاء هذه الدالة.
بكلمات بسيطة ، إذا تم استدعاء دالة / طريقة من خلال نهج "الاتصال حسب القيمة" ؛ ثم يتم تمرير نسخة من المتغير إلى رمز الوظيفة. إذا قام رمز الوظيفة بإجراء أي تغييرات على القيمة في نسخة المتغير ، فإنه لا يغير القيمة الأصلية للمتغير.
دعونا نرى مثالا لفهم هذا لفترة وجيزة.
// example in Java class check {void change (int i، int j) {i = i * i؛ j = j / 2؛ system.out.println ("قيمة المعلمة داخل الدالة") ؛ system.out.println ("قيمة 'i' التي تقبل قيمة الوسيطة 'a'" + i) ؛ system.out.println ("قيمة" j "التي تقبل قيمة الوسيطة" b "" + j) ؛ }} فئة call_by _value {public static void main (string args []) {int a = 12، b = 20؛ تحقق من C = شيك جديد () ؛ system.out.println ("قيمة" a "و" b "قبل استدعاء الدالة" + a + "" + b)؛ C.change (أ، ب). // اتصل بقيمة. system.out.println ("قيمة" a "و" b "بعد استدعاء دالة" + a + "" + b)؛ }} // قيمة الخرج 'a' و 'b' قبل استدعاء الدالة 12 20 قيمة المعلمة داخل قيمة الدالة 'i' التي تقبل قيمة الوسيطة 'a' 144 قيمة 'j' التي تقبل قيمة قيمة "b" 10 للحرفين "a" و "b" بعد استدعاء الوظيفة 12 20
تعريف دعوة حسب المراجع
طريقة استدعاء حسب المرجع يمر مرجع / عنوان وسيطة إلى رمز الدالة. عندما يتم تمرير عنوان وسيطة إلى رمز الدالة ، فإن المعلمة الرسمية التي تقبل هذا العنوان ستكون متغير "مؤشر". الآن ، عندما حصل رمز الوظيفة على عنوان وسيطة ، فإن التعديل في قيمة وسيطة سيعدل أيضا القيمة الأصلية للوسيطة.
في C ++ و Java ، من الشائع جدًا تمرير الكائن إلى الدالة / الأسلوب ويتم دومًا تمرير الكائن وفقًا لمرجعه. تؤثر التغييرات التي تمت على الكائن داخل الدالة / الطريقة على الكائن المستخدم لاستدعاء تلك الوظيفة / الطريقة.
يوضح الجزء التالي الطريقة الصحيحة "للاتصال حسب المرجع".
// example in C ++ class swap {void swap (int * x، int * y) {int temp؛ درجة الحرارة = * س. * س = * ذ؛ * Y = درجة الحرارة. }} int main {int a = 10، b = 20؛ cout << "قيمة a ، b قبل استدعاء الدالة" << a << "" <الآن دعونا نناقش "استدعاء بالإشارة" بتمرير "كائن" كحجة ، والتي يتم تمريرها ضمنيًا من خلال "استدعاء المكالمة".
الاختيار الطبقي {int a، b؛ check (int x، int b) {/ object objectised through this constrtuctor a = x؛ ب = ذ؛ تبادل فارغ (check ob) {ob.a = a * 2؛ ob.b = b / 2؛ }} class_class class {public static void main (string args []) {check C = new check (20،40)؛ // تهيئة الكائن. system.out.println ("قيمة" ob.a "و" ob.b "قبل استدعاء الدالة" + ob.a + "" + ob.b)؛ C.exchange (C)؛ // الاتصال حسب المرجع. system.out.println ("قيمة" ob.a "و" ob.b "قبل استدعاء الدالة" + ob.a + "" + ob.b)؛ }} // قيمة الإخراج 'ob.a' و 'ob.b' قبل استدعاء دالة 20 40 قيمة 'ob.a' و 'ob.b' بعد استدعاء الدالة 40 20الاختلافات الأساسية بين المكالمة حسب القيمة والمكالمة حسب المرجع
- تمرير الوسيطة باستخدام نهج "الاتصال حسب القيمة" يمر فقط نسخة ذلك المتغير ، لذلك لا تؤثر التغييرات التي أجريت على القيمة في نسخة ذلك المتغير على القيمة الأصلية لهذا المتغير. في النهج "استدعاء حسب المرجع" ، يتم تمرير المتغير نفسه كوسيطة ، لذلك فإن التغييرات عليه تعدل قيمة المتغير الأصلي.
- إذا كانت الوسيطات التي تم تمريرها هي أنواع بيانات بدائية ، فهي ببساطة "استدعاء حسب القيمة" ، ولكن إذا تم تمرير المراجع / العناوين الخاصة بالحجج أو الكائنات ، يتم استدعاء الدالة بطريقة "استدعاء حسب المرجع".
- في "أسلوب الدعوة حسب القيمة" ، فإن الحجج التي تم تمريرها هي فقط اسم المتغيرات ، بينما في النهج "استدعاء حسب المرجع" ، فإن الوسيطات التي تم تمريرها هي ، أو اسم المتغير على طول علامة "&" ، أو كائن يتم تمريره فقط باسمه.
- معلمات استلام الوسيطة في نهج "استدعاء حسب القيمة" هي اسم متغير مع نوع بياناتها. في النهج "استدعاء حسب المرجع" ، تكون معلمة الاستقبال دائمًا متغير مؤشر إلى جانب نوع البيانات وفي حالة الكائن ، يكون اسم الكائن مع نوع الفئة الخاصة به.
استنتاج:
تستخدم كل من C ++ و Java كلا النهجين بناءً على ما يتم تمريره. إذا كنت ترغب في تمرير فقط قيمة المتغير use'call حسب القيمة '، وإذا كنت ترغب في رؤية التغيير في القيمة الأصلية للمتغير ، فاستخدم نهج "الاتصال حسب المرجع".