بسم الله الرحمن الرحيم
نكمل ما بدأنا ...
الجلسة الخامسة الـ Functions (الدوال)
يقولون في عالم النفس: إذا واجهتك مشكلة كبيرة .... حاول تقسيمها إلى أجزاء ... وقم بإيجاد حل لكل قسم على حدا ... ومن ثم إجمع الحلول في حل واحد .. بهذه النظرية تستطيع حل المشكلة :)
نعم إستخدم المبرمجون هذه النظرية أيضاً في كتابة البرامج ... وأسموها بي الـ Functions
ومنه نستخلص بأن البرنامج هو عبارة عن مجموعة من الـ Functions إتحدت مع بعضها لتكون برنامج.
يعني نستطيع أن نطلق على الـ Function الواحدة إسم Sub Program (برنامج فرعي).
يكفي فلسفة ولنرى الجانب العملي:
على بركة الله نبدأ ....
ما رأيك أن نكمل مثال الـ Game Programmer الذي تكلمنا عنه بالأعلا ..
لنكمل قصة مسخنا ...
حسناً من الممكن أن نضيف أصوات مثل صوت مرعب أو صوت تألم وهو يطلق عليه الرصاص, وأيضاً ما رأيك ببعض البهارات :) مثل جعل التحكم في الإضاءة أثناء سيرة بأماكن مظلمة أو مفتوحة ...
سيكون الكود قريباً لذلك:
شفرة:
Sound()
{
Make Sound
…..
…..
}
light()
{
Display Light
…..
…..
}
Monster()
{
Drawing
Moving
…..
…..
}
Main()
{
Call Monster()
Call sound()
Call light()
}
لنمثل الكود في الأعلى بيانياً:

نستخلص من الرسم التالي:
لكل function قوسين كالتالي
{
…
…
}
تكمن فائدة هاذان القوسان بتحديد البداية والنهاية لكل block
أقصد بي الـ Block أي دالة أو جملة loop أو أي جزء في الكود.
يسمي الكود بداخل هذان القوسان بي الـ Scope
وهذه ببساطة آلية عمل الـ Functions
أعتقد أنه إلى هنا إنتهى وقت اللعب لنأتي إلى الجد
وهو ما مهدت له منذ بدأت بالشرح من الجلسة الأولى:
وهو :
ثانياً: شرح الكود (الجلسة الاخيرة)
أقصد بي الكود وهو الكود بالأعلا ... وهو التالي:-
شفرة:
char array[] = {1,2,3,4,5};
short sigma(char *cptr,int n)
{
int i;
int sum;
sum= 0;
for(i=0;i<n;i++)
{
sum = sum+ cptr[i];
}
return(sum);
}
void main()
{
int retval;
retval = sigma(array,5);
printf ("%d",retval);
}
لنسير مع هذا الكود من الأول إلى الإنتهاء بي النتيجة:
شفرة:
void main()
أول ما نقوم بعمل Compile بواسطة المترجم يقوم بالبحث عن الدالة الرئيسية وهي الـ Main() وتسمى بي الـ Access Point تمتاز هذه الدالة عن باقي الدوال بأنها تكون من نوع Static والتي تعني بأن المترجم (Compiler) يقوم بالإحتفاظ بعنوان وحجم ثابت لها طوال فترة عمل البرنامج أي من بداية الكود إلى نهايته.. وأيضاً أن لا يقوم المترجم بي حذف هذه الدالة.
أتدري ما فائدة هذا الكلام .. أنا أقول لك ... لتبقي الدالة الرئيسية مرجع ثابت طوال فترة عمل الكود يعني إذا قام الكود بي الخروج من الدالة الرئيسية فأنه يضمن خط العودة لأن العنوان والحجم يبقى ثابت...
ولاكن لماذا يخرج؟ …
عندما يقوم بإستدعاء دالة آخرى يجب علية الخروج لمعالجة هذه الدالة ومن ثم العودة.
حسناً وكيف يخزن خط العود؟ ...
بواسطة الـ Stack.
وما هي الـ Stack؟
هي منطقة تخزين مؤقته ينشئها المترجم من أجل تخزين البيانات بنظرية (أول من يدخل هو أخر من يخرج) First In Last Out ..
وكيف تتوضع هذه المعلومات بداخل الـ Stack؟
لو أردنا الإستمرار بهذه الأسئله لما إنتهينا :) .... على كلن ستتضح الأمور بعد قليل ...
وكما نرى هي في مثالنا بالأعلا من نوع Void أي أنها لا ترجع أي قيمة ... ما معنى هذا الكلام .. معناه بأن هذه الدالة لا تقوم بإخراج أي نتيجة إلى الخارج نطاقها ..
لنكمل مسيرتنا ...
شفرة:
int retval;
هنا قام بحجز مكان للمتغير retval
نكمل مع الكود ..
شفرة:
retval = sigma(array,5);
هنا قمنا بعملية في منتهى الخطورة ... قمنا بي الإشارة للمترجم بأن هذا المتغير الذي عرفناه بالأعلا والمسمى retval يساوي قيمة الداله sigma() ..
الآن تبدأ عملية تجهيز الحقائب للسفر والبحث عن الدالة sigma() ولأكن قبلها يجب علينا حفظ موقعنا الحالي... تتم هذه العملية عن طريق تجهيز منطقة في ذاكرة ال