كل برنامج C عبارة عن مجموعة من الوظائف. اكتشف كل ما يتعلق بهذه الأجزاء المفيدة من التعليمات البرمجية القابلة لإعادة الاستخدام، بدءًا من كيفية تعريفها وحتى معنى الفراغ.
ربما تكون قد قمت بتغطية بناء جملة لغة C الأساسية، بأمثلة بسيطة، وتتساءل الآن عن كيفية إنشاء برامج أكبر حجمًا في العالم الحقيقي. كبداية، ستحتاج إلى تنظيم التعليمات البرمجية الخاصة بك إلى أجزاء فعالة، مع الحد الأدنى من التكرار. في لغة C، كما هو الحال في معظم اللغات، الإجابة على مشاكلك هي الوظيفة.
يعد إنشاء الوظائف واستخدامها في لغة C أمرًا بسيطًا ويجلب العديد من الفوائد. تتيح لك الوظائف تقسيم البرامج المعقدة إلى أجزاء أصغر. وهي توفر إمكانية إعادة الاستخدام، سواء داخل برنامجك الأصلي أو في المكتبات ذات الصلة أو البرامج المنفصلة الأخرى.
للبدء، ستحتاج إلى التعرف على إعلانات الوظائف والنماذج الأولية والمعلمات وبيانات الإرجاع.
ما هي الوظائف في C؟
في البرمجة C، الوظيفة عبارة عن قسم مسمى من التعليمات البرمجية يقوم بشيء ما عندما تطلب منه ذلك. فهو يساعد في الحفاظ على تنظيم التعليمات البرمجية الخاصة بك ويتيح لك استخدام نفس الإجراء عدة مرات دون تكرار نفسك.
أبسط مثال هو الذي كنت تستخدمه بالفعل: الوظيفة الرئيسية (). الوظيفة الرئيسية خاصة بشكل خاص لأنها بمثابة نقطة الدخول الرئيسية لأي برنامج C. يمكنك أيضًا استخدام وظائف المكتبة، وهي تلك التي كتبها شخص آخر بالفعل، أو يمكنك كتابة وظائفك المعرفة من قبل المستخدم.
الوظائف: التصريح والتعريف والدعوة
هذه الجوانب الثلاثة أساسية لاستخدام الوظائف.
إعلان الوظيفة
يوفر هذا معلومات حول اسم الوظيفة ونوع الإرجاع والمعلمات، مما يتيح استخدامها قبل تعريفها الكامل. ويسمى أيضًا النموذج الأولي للوظيفة. ويتبع بناء الجملة البسيط هذا:
return_type function_name(parameters);
أين:
- return_type هو نوع بيانات القيمة التي ترجعها الدالة. يمكن أن يكون أي نوع بيانات C صالح أو فارغ إذا كانت الدالة لا ترجع قيمة.
- اسم وظيفة هو الاسم الذي تعطيه للوظيفة. ستستخدم هذا لاستدعاء الوظيفة لاحقًا.
- حدود هي قائمة بمعلمات الإدخال التي تقبلها الوظيفة، إن وجدت. تتكون كل معلمة من نوع بيانات متبوعًا باسم معلمة مفصولة بفواصل.
على سبيل المثال، إليك إعلان دالة بسيط:
intadd(int a, int b);
تعريف الوظيفة
عند استدعاء دالة، فإنها تقوم بتشغيل الكود المحدد في تعريفها. ويتضمن اسم الوظيفة ونوع الإرجاع وقائمة المعلمات والعبارات التي تحدد سلوكها. هنا هو بناء الجملة:
return_type function_name(parameters){
// Function body - code that defines what the function does
// Return a value if applicable
return value;
}
دعونا نحلل أجزاء من بناء الجملة:
هيئة الوظيفة: هذه هي كتلة التعليمات البرمجية المحاطة بأقواس متعرجة {}. يحتوي على الإرشادات التي تحدد ما تفعله الوظيفة عند استدعائها.
بيان العودة: إذا كانت الدالة لها نوع إرجاع غير فارغ، ال يعود البيان يرسل قيمة مرة أخرى إلى المتصل. يجب أن تتطابق هذه القيمة مع نوع الإرجاع المحدد.
إليك مثال بسيط لتعريف الدالة:
intadd(int a, int b){
int sum = a + b;
return sum;
}
استدعاء الوظيفة
تمامًا مثل الطهي، قد يكون لديك وصفة (تعريف الوظيفة) وبعض المكونات (الحجج)، لكنك لا تزال بحاجة إلى اتباع التعليمات للحصول على نتيجة. سوف يقوم استدعاء الدالة بتشغيل الدالة باستخدام الوسائط المحددة؛ وهنا بناء الجملة:
return_type result = function_name(arguments);
الحجج: هذه هي القيم أو التعبيرات التي تمررها إلى الوظيفة كمدخلات. افصل بين كل وسيطة بفاصلة. يجب أن يتطابق عدد الوسائط وترتيبها وأنواع بياناتها مع قائمة معلمات الوظيفة.
نتيجة: إذا كانت الدالة لها نوع إرجاع غير فارغيمكنك التقاط القيمة التي تم إرجاعها باستخدام متغير من نوع البيانات المناسب.
فيما يلي مثال لاستدعاء دالة:
#include
// Function prototype
intadd(int a, int b);intmain(){
int x = 5, y = 3;// Call the function and store the result in 'sum'
int sum = add(x, y);
printf("The sum of %d and %d is %d\n", x, y, sum);
return0;
}
// Function definition
intadd(int a, int b){
return a + b;
}
باتباع هذه الخطوات الثلاث — الإعلان عن الوظيفة، وتوفير تنفيذها، واستدعائها باستخدام الوسائط المناسبة - يمكنك استخدام الوظائف بشكل فعال لتنفيذ مهام مختلفة في جهازك برنامج.
معلمات الوظيفة وقيم الإرجاع
المعلمات هي متغيرات تم الإعلان عنها في تعريف الدالة أو تعريفها وتعمل كعناصر نائبة للقيم التي تم تمريرها إلى الدالة عند استدعائها. فهي تسمح لك بتمرير البيانات إلى الوظيفة، وتمكينها من العمل مع تلك البيانات ومعالجتها. القيم المرجعة هي القيم التي تنتجها الوظيفة وترسلها مرة أخرى إلى المتصل.
هناك طريقتان لتمرير المعلمات.
تمر بالقيمة
باستخدام هذا الأسلوب، يقوم استدعاء الدالة بنسخ قيمة الوسيطة الفعلية إلى معلمة الدالة. لا تؤثر التغييرات التي يتم إجراؤها على المعلمة داخل الوظيفة على الوسيطة الأصلية.
على سبيل المثال:
#include
intsquare(int num){
num = num * num;
return num;
}intmain(){
int x = 5;
int y = square(x);// Output: x and y after function call: 5 25
printf("x and y after function call: %d %d\n", x, y);
return0;
}
- تأخذ الدالة المربعة معلمة عدد صحيح، رقم.
- تقوم الدالة Square بحساب مربع العدد وتحديث قيمته وإرجاع هذه القيمة الجديدة.
- تعلن الدالة الرئيسية عن متغير عدد صحيح، س، ويعين لها القيمة 5.
- ثم تقوم باستدعاء الدالة المربعة، وتمريرها بقيمة x. يقوم بتعيين النتيجة إلى المتغير الثاني، ذ.
- بعد استدعاء الدالة، يطبع main قيم x وy. تظل قيمة x كما هي لأن تغيير المعلمة num داخل المربع لا يؤثر على قيمة x الأصلية.
تمر حسب المرجع
باستخدام هذا الأسلوب، يمكنك تمرير عنوان الذاكرة (المؤشر) لقيمة ما إلى دالة. تؤثر التغييرات التي يتم إجراؤها على المعلمة داخل الوظيفة على القيمة الأصلية خارجها.
تعد المؤشرات، بما في ذلك استخدامها كمعلمات، أحد جوانب C التي تجعلها مختلفة عن لغة مثل بايثون.
#include
voidsquare(int *num){
*num = *num * *num;
}intmain(){
int x = 5;
square(&x);
// Output: x after function call: 25
printf("x after function call: %d\n", x);
return0;
}
- ال مربع تأخذ الدالة مؤشرًا صحيحًا (كثافة العمليات *) معامل، رقم. ولا يقوم بإرجاع قيمة.
- الدالة المربعة تحسب مربع القيمة التي رقم يحتوي على تلك القيمة ويقوم بتحديثها باستخدام عامل التشغيل المرجعي للمؤشر، *.
- ال رئيسي تعلن الدالة عن متغير عدد صحيح، س، ويعين لها القيمة 5.
- ومن ثم يدعو مربع وظيفة مع مؤشر ل س باستخدام عنوان المشغل: &x.
- بعد استدعاء الدالة، يطبع main قيمة س، ايهما 25 منذ التغييرات ل *عدد داخل مربع وظيفة تؤثر على الأصل س.
باختصار، الفرق الرئيسي بين الطريقتين هو كيفية تأثير التغييرات في المعلمة داخل الدالة على القيمة الأصلية خارجها. يؤدي التمرير حسب القيمة إلى إنشاء نسخة، بينما يسمح التمرير حسب المرجع (المؤشر) بالتلاعب المباشر بالقيمة الأصلية.
غالبًا ما تحتوي اللغات الأخرى على ما يعادل مؤشرات لغة C، لكنها تعمل بشكل عام على مستوى أعلى. أحد الأمثلة على ذلك هو دعم C# للمتغيرات الخارجية.
وظائف باطلة
الوظائف الفارغة في برمجة C هي وظائف لا تُرجع قيمة. استخدمها لتنفيذ إجراءات أو مهام دون تحقيق نتيجة. يمكنهم تغيير المعلمات الخاصة بهم باستخدام التمرير حسب المرجع، لكن ليس عليهم القيام بذلك.
وفيما يلي مثال على وظيفة باطلة:
#include
// Void function with no parameters
voidgreet(){
printf("Hello, MUO!");
}intmain(){
// Call the void function, output: "Hello, MUO!"
greet();
return0;
}
تعد الوظائف الفارغة مفيدة لتنفيذ الإجراءات أو طباعة الرسائل أو تعديل البيانات أو تنفيذ المهام دون الحاجة إلى قيمة إرجاع.
اكتشف الوظائف في برمجة C
إن التدرب على إنشاء الوظائف يعزز فهمك وتطبيقك لبرمجة لغة C. علاوة على ذلك، فإنه يزيد من إمكانية قراءة التعليمات البرمجية وسهولة الصيانة. انغمس في التطبيقات المختلفة للوظائف لتتعرف على مزاياها.
عندما تتقن أساسيات وظائف لغة C وترغب في تحدي نفسك، فكر في الخوض في التكرار.