الدّالّة (5) - الإستدعاء حسب المرجع و الإستدعاء حسب القيمة)
يعد الإستدعاء حسب القيمة والإستدعاء حسب المرجع طريقتين مختلفتين لتمرير المتغيرات إلى الدّوال في C++.
الإستدعاء حسب القيمة هي آلية التمرير الافتراضية في C++. عندما يتم استدعاء دالة حسب القيمة، يتم تمرير نسخة من المتغير الفعلي إلى الدالة. تعمل الدالة بعد ذلك على هذه النسخة، وأي تغييرات يتم إجراؤها على النسخة داخل الدالة لن تنعكس في المتغير الفعلي خارج الدالة.
الإستدعاء حسب المرجع يسمح لك بتمرير مرجع المتغير الفعلي إلى الدالة. هذا يعني أن الدالة تعمل مباشرة على المتغير الفعلي خارج الدالة. أي تغييرات يتم إجراؤها على المتغير داخل الدالة سوف تنعكس في المتغير الفعلي خارج الدالة.
لتمرير متغير حسب المرجع، تحتاج إلى استخدام عامل التشغيل &
قبل اسم المتغير.
على سبيل المثال، يوضح البرنامج التالي كيفية إستدعاء دالة حسب القيمة:
#include <iostream> using namespace std; void swap(int x, int y) { int z = x; x = y; y = z; } int main() { int x = 10, y = 20; swap(x, y); cout << "x= " << x << " y= " << y << endl; return 0; } //x= 10 y= 20
يوضح البرنامج التالي كيفية إستدعاء نفس الدالة حسب المرجع:
#include <iostream> using namespace std; void swap(int&x, int&y) { int z = x; x = y; y = z; } int main() { int x = 10, y = 20; swap(x, y); cout << "x= " << x << " y= " << y << endl; return 0; } //x= 20 y= 10
كما ترى، نتيجة استدعاء الدالة swap()
تختلف اعتمادًا على ما إذا كانت تستدعى حسب القيمة أو حسب المرجع.
غالبًا ما يتم استخدام الاستدعاء حسب المرجع لتعديل قيم المتغيرات خارج الدالة. على سبيل المثال، swap()
هذه الدالة تستخدم لمبادلة قيم متغيرين.
يمكن أيضًا استخدام الاستدعاء حسب المرجع لتمرير objects كبيرة إلى الدوال دون الحاجة إلى نسخها. هذا يمكن أن يحسن أداء البرنامج الخاص بك.
ومع ذلك، من المهم استخدام الاستدعاء حسب المرجع بعناية، لأنه قد يؤدي إلى نتائج غير متوقعة إذا لم يتم استخدامه بشكل صحيح. على سبيل المثال، إذا قمت بتمرير مرجع إلى متغير محلي إلى دالة، وعادت الدالة، فسيخرج المتغير المحلي من النطاق، لكن مرجعه سيظل صالحًا. يمكن أن يؤدي هذا إلى تعطل البرنامج إذا حاولت الوصول إلى المتغير المحلي من خلال المرجع.
بشكل عام، من الأفضل استخدام الإستدعاء حسب القيمة إلا إذا كان لديك سبب محدد لاستخدام الإستدعاء حسب المرجع.
على سبيل المثال، يوضح البرنامج التالي كيفية إستدعاء دالة حسب القيمة:
#include <iostream> using namespace std; void fun(int x, int y) { x += 1; y += 2; } int main() { int k = 50, r = 10; fun(k, r); cout << "K= " << k << " R= " << r << endl; return 0; } //K= 50 R= 10
يوضح البرنامج التالي كيفية إستدعاء نفس الدالة حسب المرجع:
#include <iostream> using namespace std; void fun(int&x, int&y) { x += 1; y += 2; } int main() { int k = 50, r = 10; fun(k, r); cout << "K= " << k << " R= " << r << endl; return 0; } //K= 51 R= 12
كما ترى، نتيجة استدعاء الدالة fun()
تختلف اعتمادًا على ما إذا كانت تستدعى حسب القيمة أو حسب المرجع.