الوظائف#
مقدمة#
تُعدّ الدوال عنصرًا أساسيًا في برمجة لغة C++، حيث تُجمّع أجزاءً من التعليمات البرمجية في أقسام قابلة لإعادة الاستخدام وفعّالة، مصممة لأداء مهمة محددة. يمكن استدعاء الدوال عدة مرات داخل البرنامج، مما يُسهّل تنظيم التعليمات البرمجية ويُساعد على تجنّب تكرارها. كما تُسهّل الدوال عملية تصحيح الأخطاء.
تتناول هذه الصفحة أساسيات استخدام الدوال في لغة C++، بما في ذلك:
بنية الدالة وبنيتها — كيفية كتابة الدوال في لغة C++، بما في ذلك أنواع الإرجاع والأسماء والمعلمات.
نماذج الوظائف — ما هي وظائف النموذج الأولي ولماذا يتم استخدامها.
تعريف واستدعاء الدوال — كيفية إنشاء الدوال واستدعائها من برنامجك.
قيم الإرجاع — كيف يمكن للدوال إرسال البيانات مرة أخرى إلى المستدعي.
التمرير بالمرجع — كيف يمكن للدوال تعديل المتغيرات خارج نطاقها الخاص.
وظائف الاستدعاء — كيف يمكن تمرير الوظائف إلى وظائف أخرى واستدعائها تلقائيًا استجابةً للأحداث.
الدوال ذات الوسائط الافتراضية — كيفية إعطاء المعلمات قيمًا افتراضية عندما لا يتم توفير أي وسيط.
بنية الدالة وبنيتها#
في لغة C++، يجب تعريف الدوال مع تحديد نوع القيمة المُعادة واسمها ومعاملاتها. الصيغة الأساسية هي:
return_type function_name(parameters) {
// Code to execute when the function is called
return result; // Optional, used to return a value
}
أجزاء وظيفية |
وصف |
|---|---|
|
نوع البيانات التي تُرجعها الدالة، ومن الخيارات الشائعة:
|
|
اسم الدالة. |
|
اختياري. قائمة مفصولة بفواصل من المعاملات المُحددة النوع، مكتوبة على النحو التالي: |
|
اختياري. القيمة التي تُرجعها الدالة. إذا لم يكن |
ملاحظة: يجب دائماً تعريف الدالة قبل استدعائها، أو يجب عليك توفير نموذج الدالة.
نماذج الوظائف الأولية#
في لغة C++، تتم قراءة الكود من الأعلى إلى الأسفل. وهذا يعني أنه يجب أن تكون الدالة معروفة للمترجم قبل استدعائها.
يُمكّنك نموذج الدالة من استخدام الدالة قبل كتابة كامل شفرتها. وهذا يسمح لك بوضع main() في بداية البرنامج، مع وضع تعريفات الدوال لاحقًا، حيث يسهل تنظيمها وقراءتها.
بدون نموذج أولي، سيتعين عليك تعريف كل دالة أعلى من main()، مما قد يجعل متابعة المشاريع أكثر صعوبة مع نموها.
عرّف النموذج الأولي للدالة (خارج النطاق
int main())// The function's prototype void greeting();استدعاء الدالة داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); greeting(); }اكتب جسم الدالة بعد
void greeting() { Brain.Screen.print("Hello!"); }
تعريف واستدعاء الدوال#
Functions with No Parameters#
إذا لم تتطلب الدالة مدخلات، يمكنك تعريفها بدون معلمات. استخدم void كنوع الإرجاع إذا لم تُرجع الدالة قيمة.
عرّف الدالة (خارج النطاق
int main())// Define a function to display a message void greeting() { Brain.Screen.print("Hello!"); }استدعاء الدالة داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Call the function to display the message greeting(); }
Functions with Parameters#
يمكنك أيضًا إضافة معلمات إلى الدوال، مما يسمح لك بتمرير المعلومات التي ستستخدمها الدالة.
ملاحظة: يمكن تمرير النص باستخدام سلاسل نمط C (const char*) أو سلاسل C++ (std::string).
عرّف الدالة (خارج النطاق
int main())// Define a function with a parameter void namedGreeting(const char* name) { Brain.Screen.print("Hello, %s!", name); }استدعاء الدالة مع مُعامل داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Call the function to display the message namedGreeting("Stranger"); }
القيم المُعادة#
يمكن للدوال إرسال البيانات إلى المُستدعي باستخدام الكلمة المفتاحية return . يتيح لك هذا التقاط المخرجات واستخدامها في مشروعك.
عرّف الدالة (خارج النطاق
int main())// Define a function that multiplies numbers by 2 int timesTwo(int number) { return number * 2; }استدعاء الدالة مع مُعامل داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Display the return value Brain.Screen.print("%d", timesTwo(2)); }
المرور عن طريق الإحالة#
بشكل افتراضي، تمرر لغة C++ معاملات الدوال بالقيمة، مما يعني أن الدالة تتلقى نسخة من المتغير الأصلي variable. التغييرات التي تُجرى داخل الدالة لا تؤثر على القيمة الأصلية.
عرّف الدالة (خارج النطاق
int main())// Add 1 to the number void addOne(int number) { number++; }استدعاء الدالة مع مُعامل داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); int value = 5; addOne(value); // "value" will still be 5 }
To allow a function to modify the original variable, parameters can be passed by reference using the & symbol.
عرّف الدالة (خارج النطاق
int main())// Add 1 to the number void addOne(int& number) { number++; }استدعاء الدالة مع مُعامل داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); int value = 5; addOne(value); // "value" will now be 6 }
يسمح التمرير بالمرجع للدوال بتحديث المتغيرات المعرفة خارج الدالة دون إرجاع قيمة.
دوال الاستدعاء#
دالة الاستدعاء هي دالة يتم تمريرها إلى دالة أخرى ويتم استدعاؤها تلقائيًا عند وقوع حدث معين.
تُستخدم عمليات الاستدعاء بشكل شائع للأحداث مثل الضغط على الأزرار أو تحديثات المستشعرات.
بدلاً من استدعاء الدالة بنفسك، يقوم المشروع باستدعائها نيابةً عنك عند وقوع الحدث.
عرّف دالة الاستدعاء (خارج نطاق
int main())// Create a callback function void onPressed() { Brain.Screen.print("Screen pressed!"); }قم بتسجيل دالة الاستدعاء داخل الدالة الرئيسية
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Call onPressed whenever the screen is pressed Brain.Screen.pressed(onPressed); }
Callback Signatures#
يجب أن تتبع كل دالة رد نداء توقيعًا محددًا، والذي يحدد ما يلي:
نوع الإرجاع
عدد المعلمات
أنواع المعلمات
يتم تحديد التوقيع المطلوب بواسطة واجهة برمجة التطبيقات (API). يجب أن تتطابق دالة الاستدعاء مع هذا التوقيع تمامًا.
// This callback function cannot include any parameters
void callback(void);
// This callback function includes four parameters
void callback(axisType axis, double x, double y, double z);
أسماء المعلمات وصفية وقد تختلف، ولكن يجب أن يتطابق نوع الإرجاع وترتيب المعلمات وأنواع المعلمات تمامًا.
الدوال ذات الوسائط الافتراضية#
يمكن للدوال تحديد قيم افتراضية لمعامل واحد أو أكثر. ويتم استخدام وسيط افتراضي عندما لا يتم توفير قيمة لهذا المعامل عند استدعاء الدالة.
قواعد الوسائط الافتراضية:
يجب أن تكون الوسائط الافتراضية هي آخر المعاملات في تعريف الدالة.
بمجرد أن يكون لأحد المعلمات قيمة افتراضية، يجب أن يكون لجميع المعلمات التي تليها قيم افتراضية أيضًا.
إذا حددت دالة ما وسائط افتراضية في النموذج الأولي، فلا يجب تحديد تلك القيم الافتراضية مرة أخرى في تعريف الدالة.
عرّف الدالة (خارج النطاق
int main())// Required parameter first, default parameter last void greeting(const char* name, int repeatCount = 1) { for (int i = 0; i < repeatCount; i++) { Brain.Screen.print("Hello, %s!", name); Brain.Screen.newLine(); } }استدعاء الدالة داخل
int main()int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Say what name to greet (IQ) and // use default value for repeatCount (1) greeting("IQ"); Brain.Screen.newLine(); // Overrides the default value to 3 greeting("IQ", 3); }