النماذج المصغرة Prototype :
لننظر إلى بداية البرنامج وبالتحـديد في هذا الجزء من الكـود:
النمــاذج المصغرة// ;(x int)HowTimes void .8
9. void pointer();
10. void TheMain(int x);
كما ترى فلقد قمنا بكتابة رؤوس التوابـع فقـط وقمنـا بـالتفريق بينهـا بعلامــة
الفاصلة المنقوطـة ( ;) وينصـح دائمـاً فـي أي بـرامج تقـوم بكتابتهـا أن تكتـب
النماذج المصغرة لها كما هـو في هذا المثال وللنماذج المصغرة فوائد كثيرة:
1- لنفــرض أن لــديك تــابعين اثنــين ولنفــرض أن التــابع الأول احتــاج إلــى
إستدعاء التابع الثاني وفي نفس الوقت فقد يحتاج التـابع الثـاني إلـى
إستدعاء التابع الأول أي أن التابعين الاثنين يحتاجان إلى إسـتدعاء كـل
واحد منهـما فحينها لن تستطيع كتابة تعريف أحـد التـابعين قبـل الآخـر
والنماذج المصغرة تحل هذه المشكلـة.
2- لـن تحتــاج إذا قمـت باستعــمال النمـاذج المصـغرة إلـى كتابـة أسـماء
الوسائط والمتـرجم سـيتجاهل الأسـماء فـي الأسـاس الـذي تحتــاجه
فقــط هـــو كتابــة نـــوع المتغيــرات فلنفــرض أن لــديك تــابع يســتقبل
وسيطين اثنين من النـوع int و float ؛ في حال إذا أردت كتابة النموذج
المصغر فإنـه يستحسن أن تكتبه هـكذا:
int test(int , float);
3- أيضاً فإن هـناك فائدة أخرى وهـي أنه عـند تعريف التوابـع تحـت التـابع
main فلن تضطر إلى كتابة القيم المعادة للتوابع كمـا هــو ظـاهر لـدى
التابع TheMain في السطر 35.
هذه هـي أهـم فوائد النماذج المصغرة.
مشاكل المتغيرات العامـة:
يميل أكثر المبرمجيم المبتدئين إلى إستخدام المتغيرات العامـة فهي تبعــدك
كثيراً عـن مشاكل القيم المعادة وتبـادل المعلومـات بـين التوابـع إلا أن هــناك
مشاكل كثيرة لها وهــي أنهـا سـتبقى مرئيــة فـي المنـاطق التـي لا تريـدها
أيضاً فهي تجعل من عـملية تتبع البرنامج عـملية تكاد تكـون مستحيلــة نظـراً
للتعقيد ، ربما تعتبر هـذه المشـاكل هــي التـي جعلـت أول مبـدأ مـن مبـادئ
البرمجــة الشيئيــة يظهـر وهــو الكبسلــة الـذي سـنتعرض لـه فـي الفصـول
اللاحقـة.
تمرير الوسائط بواسطـة القيمـة:
بالرغـم من أننا أشرنا إلى هـذا الموضـوع إلا أنــه لا بـد مـن تناولـه فـي فقـرة
كاملـة ؛ على العـموم يوجد نـوعـان من التمرير بالوسائط إلى التوابع الأخرى:
1- التمرير بواسطـة القيمـة
2- التمرير بواسطـة المرجع
ويعتبر النـوع الثاني هـو الأفضل والأكثر أماناً إلا أن هـناك بعض الحالات التـي
تضطرك إلى إستخـدام النـوع الأول.
عـموماً تعتبر البارامترات (الوسائط الممررة ) متغيرات محليـة بالنسـبة للتـابع
الذي مررت إليه ويتم تدميرها عـند إنتهاء تنفيذ التـابع ، وعــموماً فيجـب عليـك
عـند كتابة النموذج المصغر للتابع أن تـذكر معــه نــوع البـارامترات ولا يشـترط
ذكر اسمها ، ولكن تذكر أن هذا الأمر خاطيء :
int function (int x, z);
والسبب في ذلك يعـود إلى أنك لم تذكر نـوع الوسيط الثاني ، صحيح أنـه قـد
يفهـم من الامر السـابق أنـك تقصـد أن البـارامتر الثـاني مـن النــوع int إلا أن
المترجم لن يفهـم هذا الأمر.
في حال ما إذا كان لديك أكثر من بارامتر فإنك تقوم بالفصـل بينهــا بواسطــة
الفاصلة العادية وليس الفاصلة المنقوطـة ؛ هـكذا (, ).
القيمـة العائدة Value return :
في نهاية كـل تـابع نجــد هـذه الكلمــة return والتـي تحــدد مـا هـي قيمــة
الإعادة ، انظر إلى هذا الأمر:
int function (int x,int z);
تجـد أنـه لا بد لهذا التابع أن يعيد قيمـة من النـوع int ، قد تكون هذه القيمـة
رقماً أو متغيراً من النـوع int ، انظر لهذا الأمر:
return ( 2) ;
لا يشـترط أن تضـع القيمــة المعــادة بـين قوسـين ولكـن يفضـل حتـى يصـبح
الكـود أكثر تنظيمـاً وفهــماً ، لربمـا أنـه تعلـم أنــه بإمكــانك إسـتبدال الـرقم 2
بمتغير آخر من النـوع int .
ليس ذلك فحسب بل بإمكـانك جعل القيمـة المعادة تابعاً كاملاً بحد ذاتـه انظر
لهذا المثال:
return (function(4));
إنـه يقوم بإستدعاء تابع إسمـه function وسيقوم هذا التابع بإستدعاء نفس
التابع وسيستدعي نفسـه إلى مالا نهاية مالم تضع للأمر حداً بواسطة
القرارات. وسنتناول هذا الإستدعاء المتكرر في موضوع آخر من هذه الوحدة.
أيضاً فإن للقيمـة المعادة فائدة كبيرة أخرى وهـي أنها تسمح لك بطباعـتها
دون الحاجـة إلى تخزين قيمتها في متغير ما ، فبدلاً من كتابة هذه الأوامر:
int number=function (4) ;
cout << number ;
كما ترى فلقد قمت بتخـزين القيمـة المعادة للتـابع function فـي متغيـر آخـر
حتى تقوم بطباعتها ، بإمكانك إختصار هذا الأمر إلى هذا السطر:
cout << function ( 4 ) ;
وسيقوم المتـرجم بطباعــة القيمــة المعـادة للتـابع function ، قـد تجـد هـذه
المواضيع سخيفـة أو ليس لها من داع ولكن ستسفيد منها كثيراً حينمـا تصـل
لمواضيع الكائنـات.
لننظر إلى بداية البرنامج وبالتحـديد في هذا الجزء من الكـود:
النمــاذج المصغرة// ;(x int)HowTimes void .8
9. void pointer();
10. void TheMain(int x);
كما ترى فلقد قمنا بكتابة رؤوس التوابـع فقـط وقمنـا بـالتفريق بينهـا بعلامــة
الفاصلة المنقوطـة ( ;) وينصـح دائمـاً فـي أي بـرامج تقـوم بكتابتهـا أن تكتـب
النماذج المصغرة لها كما هـو في هذا المثال وللنماذج المصغرة فوائد كثيرة:
1- لنفــرض أن لــديك تــابعين اثنــين ولنفــرض أن التــابع الأول احتــاج إلــى
إستدعاء التابع الثاني وفي نفس الوقت فقد يحتاج التـابع الثـاني إلـى
إستدعاء التابع الأول أي أن التابعين الاثنين يحتاجان إلى إسـتدعاء كـل
واحد منهـما فحينها لن تستطيع كتابة تعريف أحـد التـابعين قبـل الآخـر
والنماذج المصغرة تحل هذه المشكلـة.
2- لـن تحتــاج إذا قمـت باستعــمال النمـاذج المصـغرة إلـى كتابـة أسـماء
الوسائط والمتـرجم سـيتجاهل الأسـماء فـي الأسـاس الـذي تحتــاجه
فقــط هـــو كتابــة نـــوع المتغيــرات فلنفــرض أن لــديك تــابع يســتقبل
وسيطين اثنين من النـوع int و float ؛ في حال إذا أردت كتابة النموذج
المصغر فإنـه يستحسن أن تكتبه هـكذا:
int test(int , float);
3- أيضاً فإن هـناك فائدة أخرى وهـي أنه عـند تعريف التوابـع تحـت التـابع
main فلن تضطر إلى كتابة القيم المعادة للتوابع كمـا هــو ظـاهر لـدى
التابع TheMain في السطر 35.
هذه هـي أهـم فوائد النماذج المصغرة.
مشاكل المتغيرات العامـة:
يميل أكثر المبرمجيم المبتدئين إلى إستخدام المتغيرات العامـة فهي تبعــدك
كثيراً عـن مشاكل القيم المعادة وتبـادل المعلومـات بـين التوابـع إلا أن هــناك
مشاكل كثيرة لها وهــي أنهـا سـتبقى مرئيــة فـي المنـاطق التـي لا تريـدها
أيضاً فهي تجعل من عـملية تتبع البرنامج عـملية تكاد تكـون مستحيلــة نظـراً
للتعقيد ، ربما تعتبر هـذه المشـاكل هــي التـي جعلـت أول مبـدأ مـن مبـادئ
البرمجــة الشيئيــة يظهـر وهــو الكبسلــة الـذي سـنتعرض لـه فـي الفصـول
اللاحقـة.
تمرير الوسائط بواسطـة القيمـة:
بالرغـم من أننا أشرنا إلى هـذا الموضـوع إلا أنــه لا بـد مـن تناولـه فـي فقـرة
كاملـة ؛ على العـموم يوجد نـوعـان من التمرير بالوسائط إلى التوابع الأخرى:
1- التمرير بواسطـة القيمـة
2- التمرير بواسطـة المرجع
ويعتبر النـوع الثاني هـو الأفضل والأكثر أماناً إلا أن هـناك بعض الحالات التـي
تضطرك إلى إستخـدام النـوع الأول.
عـموماً تعتبر البارامترات (الوسائط الممررة ) متغيرات محليـة بالنسـبة للتـابع
الذي مررت إليه ويتم تدميرها عـند إنتهاء تنفيذ التـابع ، وعــموماً فيجـب عليـك
عـند كتابة النموذج المصغر للتابع أن تـذكر معــه نــوع البـارامترات ولا يشـترط
ذكر اسمها ، ولكن تذكر أن هذا الأمر خاطيء :
int function (int x, z);
والسبب في ذلك يعـود إلى أنك لم تذكر نـوع الوسيط الثاني ، صحيح أنـه قـد
يفهـم من الامر السـابق أنـك تقصـد أن البـارامتر الثـاني مـن النــوع int إلا أن
المترجم لن يفهـم هذا الأمر.
في حال ما إذا كان لديك أكثر من بارامتر فإنك تقوم بالفصـل بينهــا بواسطــة
الفاصلة العادية وليس الفاصلة المنقوطـة ؛ هـكذا (, ).
القيمـة العائدة Value return :
في نهاية كـل تـابع نجــد هـذه الكلمــة return والتـي تحــدد مـا هـي قيمــة
الإعادة ، انظر إلى هذا الأمر:
int function (int x,int z);
تجـد أنـه لا بد لهذا التابع أن يعيد قيمـة من النـوع int ، قد تكون هذه القيمـة
رقماً أو متغيراً من النـوع int ، انظر لهذا الأمر:
return ( 2) ;
لا يشـترط أن تضـع القيمــة المعــادة بـين قوسـين ولكـن يفضـل حتـى يصـبح
الكـود أكثر تنظيمـاً وفهــماً ، لربمـا أنـه تعلـم أنــه بإمكــانك إسـتبدال الـرقم 2
بمتغير آخر من النـوع int .
ليس ذلك فحسب بل بإمكـانك جعل القيمـة المعادة تابعاً كاملاً بحد ذاتـه انظر
لهذا المثال:
return (function(4));
إنـه يقوم بإستدعاء تابع إسمـه function وسيقوم هذا التابع بإستدعاء نفس
التابع وسيستدعي نفسـه إلى مالا نهاية مالم تضع للأمر حداً بواسطة
القرارات. وسنتناول هذا الإستدعاء المتكرر في موضوع آخر من هذه الوحدة.
أيضاً فإن للقيمـة المعادة فائدة كبيرة أخرى وهـي أنها تسمح لك بطباعـتها
دون الحاجـة إلى تخزين قيمتها في متغير ما ، فبدلاً من كتابة هذه الأوامر:
int number=function (4) ;
cout << number ;
كما ترى فلقد قمت بتخـزين القيمـة المعادة للتـابع function فـي متغيـر آخـر
حتى تقوم بطباعتها ، بإمكانك إختصار هذا الأمر إلى هذا السطر:
cout << function ( 4 ) ;
وسيقوم المتـرجم بطباعــة القيمــة المعـادة للتـابع function ، قـد تجـد هـذه
المواضيع سخيفـة أو ليس لها من داع ولكن ستسفيد منها كثيراً حينمـا تصـل
لمواضيع الكائنـات.
ليست هناك تعليقات:
إرسال تعليق