المعاملات في لغة سي
يعتبر الـ parameter أنه متغير يتم كتابته و إنشاءه عند تعريف الدالة و هو يكون جزء من الدالة, أي عندما نقوم بإنشاء دالة جديدة فإن الباراميتر يكون هو المتغير الذي يتم تمريره للدالة من أجل أن يتم التعامل معه و عمل المهمة الخاصة في الدالة.
تعلّمنا في الدرس السابق ما هي الدوال و قلنا أن الدوال هي عبارة عن قطع برمجية منفصِلة عن بعضها البعض و هذا يعني أن كل المتغيرات داخل دالة معيّنة لا يُمكن الوصول إليها في دالة اُخرى و لذلك لنقل القيم من دالة إلى دالة اخرى نقوم بتمرير القيم لكن ما المقصود بالتمرير؟.
أمثلة لكيفية التعامل مع الباراميترات في لغة سي
مثال 1
إذا كان لدينا متغير في دالة main و نُريد طباعة قيمة هذا المتغير داخل دالة printMe مثلاً
#include <stdio.h> #include <stdlib.h> void printMe() { printf("AMVIIP\n %d", age); } int main(int argc, char** argv) { int age = 28; printMe(); return 0; }
عند تشغيل الكود نُلاحظ قد ظَهَرَ خطأ و إشارة إنذار حمراء عند السطر 5 و سبب هذا الخطأ هو أن المتغير age قد تم تعريفُه في داخل الدالة main. و كما قُلنا في الدروس السابقة بأن كل شيئ يتم تعريفه داخل نِطاق معيَّن أي بين قوسين مجعدين لا يكون. معرَّف خارجها سوف يَنتِج خطأ لأن المُتغير age غير معرَّف في هذا النطاق, و هنا توجد اكثر من طريقة لدينا لكن الخيار الأمثل هو أن نقوم بتمرير المتغير age داخل القوسين الخاصين بدالة printMe و كل ما يُكتب بداخل القوسين يُسمى معامل الدالة, سنقوُم بكتابة مُعامل الدالة بين القوسين في بداية الدالة
void printMe(int age)
و عند تشغيل الكود بهذا الشكل سوف نُلاحظ بأن الخطأ الذي ظَهَرَ مُسبقاً عند السطر 5 سوف يختفي لكن سينتج خطأ آخر عند أمر إستدعاء الدالة في السطر 10 لأن الدالة تتوقع أن يَمُر معها متغير من نوع int لذلك سوف نَكتٌب إسم المتغير age داخل قوسي الدالة و عند تشغيل الكود سوف يقوم بطباعة ما يلي
AMVIIP 28
قد يكوُن الأمر مُلخبطاً للمرة الأولى لكن ما حَدث هو في دالة printMe تم تعريف مُتغير خاص إسمه age في. رأس الدالة و قُلنا أن المتغيرات المعرَّفة بين القوسين تُسمى بمعاملات الدالة او parameters. و في الدالة main هناك مُتغير آخر إسمه age و هذا المُتغير ليسَ لهُ أي علاقة بالمتغير الذي في الأعلى عند void داخل القوسين. فيُمكننا أن نُسميهُ ما نريد و هذه هي القوة في البرمجة يُمكننا تسمية أسامي مُتشابهة. لنعرِف أن هذا المُتغير هو الذي سوف يتم تمريرهُ في هذه الدالة و يُمكن تمرير القيمة مباشرتاً بين القوسين. عند أمر إستدعاء هذه الدالة printMe(28) دون الحاجة لكتابة متغير كامل لتخزين القيمة فيه.
فعند إستدعاء الدالة سيتم وضع الرقم 28 داخل معامل الدالة داخل دالة printMe و هو معامل age الذي يُميز الدوال عن غيرها هو أن يُمكننا تشغيل الدالة مثلاً printMe لأكثر من قيمة و لكل قيمة تقوم بعمل مختلف. فإذا قُمنا بتكرار أمر إستدعاء الدالة بداخل main كما يلي
مثال 2
#include <stdio.h> #include <stdlib.h> void printMe(int age) { printf("AMVIIP %d\n", age); } int main(int argc, char** argv) { printMe(30); printMe(28); printMe(25); return 0; }
سيتم طباعة إسم AMVIIP و بعده الرقم, أي أن البرنامج قد عمل على اكثر من قيمة و الجدير في الذِكر. أن المعامل age سوف يتم تعريفه فقط عند إستدعاء الدالة و في إستدعاء الدالة الأولى بقيمة 30 تم. تعريف المعامل age في هذا الإستدعاء بقيمة 30 حتى تنتهي الدالة من عملها و تموُت الدالة و ثم يتم. إستدعاء الدالة مرة اُخرى بقيمة 28 بنفس مبدأ العمل الأول و نفسهُ في الإستدعاء الثالث, أي أن age لا تعتَمِد قيمتهُ من إستدعاء إلى آخر.
AMVIIP 30 AMVIIP 28 AMVIIP 25
كما يمكننا تمرير اكثر من قيمة بدلاً من قيمة واحدة مثل age, أي يُمكن تمرير عدد لا نهائي من القيم.
مثال 3
#include <stdio.h> #include <stdlib.h> void printMe(int age, double height) { printf("Agge %d, Length %f\n", age, height); } int main(int argc, char** argv) { printMe(30, 1.9); printMe(28, 1.7); printMe(25, 1.3); return 0; }
نلاحظ أنه قمنا بتمرير قيمتين الأولى متغير عددي إسمه age و الثانية متغير double إسمه height و طلبنا. من البرنامج أن يطبَع لنا قيمة المتغير الأول ثم المتغير الثاني و في الدالة main قُمنا بتمرير ثلاث قيم عبر دالة printMe التي. انشأناها و عند تشغيل الكود سنحصل على النتيجة.
Agge 30, Length 1.900000 Agge 28, Length 1.700000 Agge 25, Length 1.300000