أي تابع بلغة الـ C++ يتألف من قسمين أساسيين : (1 ترويسة التابع : function header وهي توجد في بداية التابع وتتألف.
Download
Report
Transcript أي تابع بلغة الـ C++ يتألف من قسمين أساسيين : (1 ترويسة التابع : function header وهي توجد في بداية التابع وتتألف.
أي تابع بلغة الـ C++يتألف من قسمين أساسيين :
(1
ترويسة التابع : function headerوهي توجد في بداية التابع وتتألف من ثالث أجزاء :
Return Type of The Functionوهذا الجزء يحدد النمط الذي يرده التابع .
Name of The Functionوهذا الجزء يحدد اسم التابع .
Types and Names of Parametersوهذا الجزء يحدد أسماء وأنماط متحوالت دخل التابع.
(2
جسم التابع : Bodyوهذا الجزء هو الذي سيعبر عن وظيفة التابع بحيث يعالج الدخل ويقوم بإعطاء خرج
يتوافق مع مهمة التابع المكتوب .
يوجد طريقتين لكتابة تابع بلغة c++هما :
(1
الطريقة األولى :باستخدام الـ . function prototype
نحتاج إلى )function prototype(function declaration
نحتاج طبعاً إلى . function definition
(2الطريقة الثانية :باستخدام كتابة التابع بشكل كامل قبل أماكن استدعاءه.
نحتاج طبعاً إلى . function definition
يوجد طريقتين لكتابة تابع بلغة c++هما :
(1
الطريقة األولى :باستخدام الـ . function prototype
يسمى الشكل السابق بـ prototypeأو declarationللتابع ،وينتهي بفاصلة منقوطة.
يتم وضعه في الـ global sectionقبل أماكن االستدعاء ولمرة واحدة .
ومن بعدها يتم وضع الـتابع بشكل كامل function definitionفي أي مكان يلي الـ
. prototype
prototype
Header + body
وهذه الطريقة صحيحة أيضاً إذ أننا
نقوم باخبار المترجم في سطر الـ
prototypeأنه لدينا تابع اسمه add
prototyp
e
يأخذ متحولين كالهما من النمط int
(ال يهمني اسمهم هنا طالما ال يتم
استخدامهما أي ال يوجد جسم للتابع).
نهتم باسماء المتحول عند كتابة الـ
.function definition
Header +
body
هنا سيرى المترجم استدعاء
تابع غير معرف عنده .
Header + body
إذاً في هذه الطريقة يتم في البداية
تعريف الـ prototypeللتابع ونضعه
في األعلى فوق الـ mainحتى يتم
prototyp
e
رؤيته من جميع التوابع األخرى .
ثم يتم تعريف كامل التابع function
( definitionالترويسة +جسم
التابع) في أي
. prototype
مكان يلي الـ
Header +
body
يوجد طريقتين لكتابة تابع بلغة c++هما :
(1
الطريقة الثانية :باستخدام الطريقة المألوفة .
يتم وضع الـتابع بشكل كامل function definitionفي أي مكان
ضمن الـ global sectionوقبل مكان االستدعاء ،كي يتم رؤيته .
يتم وضع الـتابع بشكل كامل
في أي مكان ضمن الـ
global sectionوقبل
مكان االستدعاء ،كي يتم
رؤيته .
Header + body
الـ function signatureهو جزء من الـ function prototypeالذي
يتألف من اسم التابع وأنماط الـ parameters listمن دون نمط اإلرجاع .
يتم الفصل بين المتحوالت بفاصلة .
المتحوالت هي
local variablesأي تموت هذه المتحوالت بعد الخروج
من التابع .
ال يمكن تعريف متحول داخل التابع بنفس اسم متحول دخل للتابع .
لكتابة تابع بدون متحوالت إما نترك الـ parameter listفارغة أو نكتب
الكلمة voidلتدل على ال شيء.
يتم وضع اسم للتابع بحيث يعبر عن وظيفته .
يجب أن يكون اسم التابع غير محجوز مسبقاً .
ال يمكن تعريف تابع ضمن تابع آخر !
يمكن استدعاء تابع ضمن تابع آخر .
عندما يتم تمرير قيمة متحول لتابع فإنه
يتم في البداية أخذ نسخة من هذا
10
5
المتحول وتعطى كدخل للتابع وبالتالي
يتم المحافظة على القيمة السابقة كي ال
يتم تغييرها من داخل التابع.
هنا تم نسخ المتحول xفي التابع f1
وإعطاء النسخة كدخل للتابع f2فأي
تعديل على xداخل f2لن يعدل على x
يوجد مكتبة تحوي مجموعة من التوابع الرياضية وتدعى . cmath
نقوم بتضمين المكتبة السابقة في برنامجنا لنتمكن من استدعاء التوابع الموجودة بداخلها .
>#include <cmath
أغلب التوابع الموجودة في المكتبة السابقة يكون دخلها من النمط
doubleوالخرج أيضاً . double
يوجد تابع يدعى ) ( randيقوم بتوليد أعداد عشوائية ضمن المجال ]32767
التابع السابق يوجد ضمن المكتبة >. <cstdlib
كل مرة يتم توليد رقم جديد ضمن المجال السابق وفق استراتيجية ما
بدءاً من قيمة ما تدعى البذرة . seed
ستنتج نفس القيم المولدة عند إعادة تنفيذ البرنامج من جديد !
. [0
يوجد تابع يدعى ) srand(unsigned intوالذي يقوم بتعيين القيمة األولية لألعداد المولدة عشوائية أي تحديد
قيمة البذرة . seed
التابع السابق أيضاً يوجد ضمن المكتبة >. <cstdlib
في حال كانت القيمة المدخلة ثابتة فإنه سيتم توليد كل مرة
تنفيذ نفس سلسلة األرقام المولدة .
التابع السابق يتم استدعاءه لمرة واحدة فقط .
إذاً ماذا نفعل إذا كنا نريد في كل مرة تنفيذ توليد قيم مختلفة
؟
في كل مرة نقوم بإدخال قيمة مختلفة كدخل للتابع
) . srand( unsigned int
مثالً ندخل الوقت الحالي بالثواني !!! يوجد تابع يقوم بذلك
يدعى ) time(0وهو ضمن المكتبة >. <ctime
في كل مرة نقوم فيها بتنفيذ البرنامج ستنتج لدينا قيم
عشوائية مختلفة بسبب اختالف قيمة البذرة .
ذكرنا أن التابع ) ( randيقوم بتوليد قيمة عشوائية ضمن المجال ]32767
ولكن ........ماذا سنفعل إذا كنا نريد توليد قيمة ضمن المجال ]end
قيمة ضمن المجال ]11
. [2
. [0
[startمثال توليد
ذكرنا أن التابع ) ( randيقوم بتوليد قيمة عشوائية ضمن المجال ]32767
. [0
ولكن ........ماذا سنفعل إذا كنا نريد توليد قيمة ضمن المجال ]end
[startمثال توليد قيمة
ضمن المجال ]11
. [2
سنقوم بالبداية بإجراء عملية باقي القسمة %ألن x % yسيعطينا قيمة ضمن المجال ]y-1
ثم نقوم بعملية إزاحة بقيمة ما ليتم إزاحة كامل المجال !! .
[0
مثال توليد قيمتين ضمن المجال ]11
مختلفة عن القيم السابقة .
[2وبحيث كل مرة يتم فيها تنفيذ البرنامج يتم توليد قيم
أحياناً نقوم بكتابة عدة ملفات تحوي عدد كبير من التوابع .....لماذا ال نقوم بفرز هذه التوابع بشكل منطقي وفقاً
لوظيفتها ،مثالً التوابع الرياضية نقوم بوضعها لوحدها (في ملف منفصل) ،والتوابع المسؤولة عن تصميم
الواجهات في مكان آخر ،وهكذا ....
(هذه األجزاء هي عبارة عن ملفات منفصلة تدعى مكاتب)
هذا األمر يساعدنا أيضاً في إعادة استخدام هذه األجزاء المنفصلة في أكثر من مشروع .
سابقاً كنا نقوم باستخدام مكاتب جاهزة في اللغة ولتضمينها نكتب :
ولكن ماذا لو كنا نريد كتابة مكتبة خاصة بنا !!!
سنقوم اآلن بكتابة مكتبة رياضية بسيطة خاصة بنا تحوي تابع وحيد اآلن يقوم بجمع عددين ....
نقوم بإنشاء ملف headerنسميه باسم المكتبة الذي نريد مثالً my_mathونضعه ضمن مجلد الـ
headerفي الـ projectالحالي .
تكون الحقة المكتبة .hألنه سيكون ملف . header
نقوم بكتابة headerالتوابع التي نريد فقط الترويسة أي prototypeمن دون كتابة جسم التابع في
ملف الـ ، headerكما يمكننا أيضاً تعريف متحوالت إذا أردنا .
نقوم بكتابة أجسام التوابع كاملة في ملف جديد باالسم my_math.cppسيتضمن كود تحقيق تلك
التوابع الموجودة في الـ ، header fileإذاً سيتم وضع ملف جديد باالسم السابق ضمن الـ . source
اآلن بقي لنا تضمين مكتبتنا الجديدة لنقوم باستخدامها .
اآلن نقوم بتضمين مكتبتنا في الملف األساسي حتى نتمكن من استخدام توابعنا الجديدة .
Compiler Error
عملية التضمن >… < #includeتستخدم
للمكاتب التي أتت مع اللغة وتكون موجودة
في مكان خاص في القرص الصلب.
ويكون التضمين لمكاتبنا الجديدة باستخدام
”#include “filename.h
اآلن نقوم بتضمين مكتبتنا في الملف األساسي حتى نتمكن من استخدام
توابعنا الجديدة .
8.2
إذاً أصبح لدينا ثالث ملفات اآلن :
األو ًل :
إذاً أصبح لدينا ثالث ملفات اآلن :
الثاني:
إذاً أصبح لدينا ثالث ملفات اآلن :
الثالث:
النطاق المحلي local scopeهو أي نطاق يبدأ بـ { وينتهي ب } .
}. {………………………………………..
جسم التابع يوجد ضمن نطاق ،والـ switch bodyأيضاً هو نطاق ،
.....
يمكن تعريف نطاق بداخل نطاق .
جميع المتحوالت التي يتم تعريفها ضمن نطاق ما تكون فترة حياتها
ضمن هذا النطاق أي أنها تموت بعد الخروج من هذا النطاق .
المجال الذي ال يقع ضمن أي blockهو نطاق عام . global block
فترة حياة المتحوالت ضمن الـ ) global scope (file scopeهي
بانتهاء تنفيذ البرنامج.
تمكننا الـ global variableمن سهولة الوصول إليها أينما كنا .
ولكن ينبغي تجنبها .....إذ أنه في حال جعلنا جميع المتحوالت لدينا
هي globalسيصبح هنا عدد هائل من المتحوالت وعدم التمييز بينها
الحقاً ،مما يصعّب من صيانة البرنامج في حال أردنا تعديله .
Global variables
Local variable in main
Local variable in scope
inside main
يمكن تعريف متحول ما على أنه . static
يمكن تعريف متحول ساكن محلي static localضمن تابع مثالً ،عندها
فإن هذا المتحول يتم تهيئته لمرة واحدة فقط (بحيث يصبح ساكن ضمن
التابع) وتكون فترة حياته بانتهاء البرنامج ولكن ال تتم رؤيته إال من داخل
التابع .
لدينا متحول عام global variable
ولكننا حتى اآلن لم نصل إليه !!!!
كيف سنطبع قيمة الـ xالعامة ؟!!
عن طريق المعامل ::والذي يتم وضعه
قبل اسم المتحول والذي يقصد به الخروج
إلى الـ global scopeثم انتقاء المتحول
.
انتقل للمثال التالي ....
التوابع العودية هي توابع يتم تنفيذها مرة واحدة أو أكثر ويتم الخروج
منها عند عدم تحقق شرط ما يدعى شرط التوقف .
التابع العودي هو تابع يقوم باستدعاء نفسه كل مرة إلى أن يصل إلى
شرط التوقف فيتوقف عن االستدعاء ويقوم بتحصيل النتائج المتراكمة
عن االستدعاءات السابقة .
هذا مثال يقوم بإيجاد عاملي لعدد ما ولكن بشكل تكراري وليس عودي .
هذا مثال يقوم بإيجاد عاملي لعدد ما ولكن بشكل تكراري وليس عودي .
يمكننا كتابة المهمة السابقة عن طريق تابع عودي باالستناد إلى العالقة
التالية :
نقوم بالتوقف عن العودية عندما يصبح العدد المدخل للتابع هو . 0
إذاً لدينا قاعدتين :
الحالة الخاصة (شرط التوقف)
الحالة العامة (الحالة التي يحصل فيها استدعاء عودي للتابع نفسه)
هذا مثال يقوم بإيجاد عاملي لعدد ما ولكن بشكل عودي .
كل عملية استدعاء لتابع تكو ًن له متحوالته الخاصة واملستقلة عن االستدعاء
السابق .
يجب تنفيذ جميع التعليمات املوجودة في االستدعاء العودي الحالي .
انتقل للمثال التالي والذي يشرح كامل الفكرة !!
التابع األول يقوم بعملية جمع األعداد من 1إلى nحيث nقيمة مدخلة للتابع بطريقة
تكرارية (حلقة)
التابع الثاني يقوم بعملية جمع األعداد من 1إلى nحيث nقيمة مدخلة للتابع بطريقة
عودية
التابع الثالث يقوم بعملية جمع األعداد من 1إلى nحيث nقيمة مدخلة للتابع بطريقة
(ليست عودية وليست تكرارية) أي تعليمات فقط من دون أن يكون هناك أي تكرار أو
عودية