الوظائف#
مقدمة#
تُعدّ الدوال عنصرًا أساسيًا في برمجة لغة 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()، مما قد يجعل متابعة المشاريع أكثر صعوبة مع نموها.
// The function's prototype
void greeting();
int main() {
greeting();
}
// Write the function's body after
void greeting() {
Brain.Screen.print("Hello!");
}
تعريف واستدعاء الدوال#
Functions with No Parameters#
إذا لم تتطلب الدالة مدخلات، يمكنك تعريفها بدون معلمات. استخدم void كنوع الإرجاع إذا لم تُرجع الدالة قيمة.
// Define a function to display a message
void greeting() {
Brain.Screen.print("Hello!");
}
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
vexcodeInit();
// Call the function to display the message
greeting();
}
Functions with Parameters#
يمكنك أيضًا إضافة معلمات إلى الدوال، مما يسمح لك بتمرير المعلومات التي ستستخدمها الدالة.
ملاحظة: يمكن تمرير النص باستخدام سلاسل نمط C (const char*) أو سلاسل C++ (std::string).
// Define a function with a parameter
void namedGreeting(const char* name) {
Brain.Screen.print("Hello, %s!", name);
}
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
vexcodeInit();
namedGreeting("Stranger");
}
القيم المُعادة#
يمكن للدوال إرسال البيانات إلى المُستدعي باستخدام الكلمة المفتاحية return . يتيح لك هذا التقاط المخرجات واستخدامها في مشروعك.
// Define a function that multiplies numbers by 2
int timesTwo(int number) {
return number * 2;
}
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
vexcodeInit();
// Display the return value
Brain.Screen.print("%d", timesTwo(2));
}
المرور عن طريق الإحالة#
بشكل افتراضي، تمرر لغة C++ معاملات الدوال بالقيمة، مما يعني أن الدالة تتلقى نسخة من المتغير الأصلي variable. التغييرات التي تُجرى داخل الدالة لا تؤثر على القيمة الأصلية.
// Add 1 to the number
void addOne(int number) {
number++;
}
int main() {
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.
// Add 1 to the number
void addOne(int& number) {
number++;
}
int main() {
int value = 5;
addOne(value);
// "value" will now be 6
}
يسمح التمرير بالمرجع للدوال بتحديث المتغيرات المعرفة خارج الدالة دون إرجاع قيمة.
دوال الاستدعاء#
دالة الاستدعاء هي دالة يتم تمريرها إلى دالة أخرى ويتم استدعاؤها تلقائيًا عند وقوع حدث معين.
تُستخدم عمليات الاستدعاء بشكل شائع للأحداث مثل الضغط على الأزرار أو تحديثات المستشعرات.
بدلاً من استدعاء الدالة بنفسك، يقوم المشروع باستدعائها نيابةً عنك عند وقوع الحدث.
void onPressed() {
Brain.Screen.print("Screen pressed!");
}
// Call onPressed whenever the screen is pressed
int main() {
vexcodeInit();
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);
أسماء المعلمات وصفية وقد تختلف، ولكن يجب أن يتطابق نوع الإرجاع وترتيب المعلمات وأنواع المعلمات تمامًا.
الدوال ذات الوسائط الافتراضية#
يمكن للدوال تحديد قيم افتراضية لمعامل واحد أو أكثر. ويتم استخدام وسيط افتراضي عندما لا يتم توفير قيمة لهذا المعامل عند استدعاء الدالة.
قواعد الوسائط الافتراضية:
يجب أن تكون الوسائط الافتراضية هي آخر المعاملات في تعريف الدالة.
بمجرد أن يكون لأحد المعلمات قيمة افتراضية، يجب أن يكون لجميع المعلمات التي تليها قيم افتراضية أيضًا.
إذا حددت دالة ما وسائط افتراضية في النموذج الأولي، فلا يجب تحديد تلك القيم الافتراضية مرة أخرى في تعريف الدالة.
// 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() {
vexcodeInit();
// Say what name to greet (V5) and
// use default value for repeatCount (1)
greeting("V5");
Brain.Screen.newLine();
// Overrides the default value to 3
greeting("V5", 3);
}