كيفية تمرير الوسيطات إلى الدوال في C ++: حسب القيمة مقابل المرجع؟

Kyfyt Tmryr Alwsytat Aly Aldwal Fy C Hsb Alqymt Mqabl Almrj



يجب أن تتمتع أي لغة برمجة ، بما في ذلك C ++ ، بالقدرة على توفير معلمات للوظائف. بواسطة قيمة وبواسطة مرجع هما الطريقتان الرئيسيتان اللتان يمكن استخدامهما لتمرير المعلمات. كلا النهجين لهما مزايا وعيوب ، لذلك من الضروري للمبرمجين معرفة متى يستخدمون كل منهما.

1: تمرير الحجج بالقيمة

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

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







2: تمرير الحجج بالإحالة

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



لمنع التعديلات غير المقصودة ، يجب تعيين دالة صراحة على أنها ثابتة. ستؤدي إضافة الكلمة الأساسية const إلى إعلان الوظيفة ، كما في 'int calculate (const int & a، const int & b)' ، إلى تحقيق ذلك.



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





ضع في اعتبارك الكود التالي الذي يوضح كليهما طرق تمرير الجدل :

# تضمين

استخدام اسم للمحطة ؛

فارغ PassByValue ( int x ) {

x = 5 ؛

كوت << 'داخل PassByValue:' << x << endl ؛

}

فارغ PassByReference ( int & x ) {

x = 5 ؛

كوت << 'داخل PassByReference:' << x << endl ؛

}

int رئيسي ( ) {

int عدد 1 = 2 و عدد 2 = 2 ؛

كوت << 'قبل استدعاءات الوظائف: num1 =' << عدد 1 << 'num2 =' << عدد 2 << endl ؛

PassByValue ( عدد 1 ) ؛

PassByReference ( عدد 2 ) ؛

كوت << 'بعد استدعاءات الوظائف: عدد 1 =' << عدد 1 << 'num2 =' << عدد 2 << endl ؛

يعود 0 ؛

}

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



انتاج |

كما هو متوقع ، مخرجات المكالمة الأولى 5 ، لكن ليس لها تأثير على المتغير الأصلي. في المقابل ، تقوم المكالمة الثانية بتغيير قيمة num2 إلى 5 ، مما يؤثر على ناتج العبارة النهائية.

المرور بالقيمة مقابل المرور بالمرجع

1: طريقة لاستدعاء وظيفة

فرق واحد بين يمر بالقيمة و يمر بالإشارة هي كيف يتم استدعاء الوظيفة. متى يمر بالقيمة ، يجب أن يتضمن استدعاء الوظيفة قيمة المتغير ، مثل `` احسب (أ ، ب) `. متى يمر بالإشارة ، يجب أن يتضمن استدعاء الوظيفة عنوان ذاكرة المتغير ، الذي يُرمز إليه بحرف علامة العطف ، مثل `` احسب (& أ ، & ب) `.

2: أنواع البيانات

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

خاتمة

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