 |
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
|
|
نشاط [ F.Abdelaziz ]
قوة السمعة:333
|
|
29-05-2017, 11:51 AM
المشاركة 1
|
|
الدوال والميكروسى برو :
بشكل عام ، يكون من ممارسة البرمجة الجيدة ، كتابة البرنامج المعقد الكبير فى صورة مجموعة من الوحدات الأصغر ، حيث يمكن اختبار كل وحدة بشكل منفصل عن الكود الرئيسى . يمكن التفكير فى "الدالة" function على أنها كود برنامج مستقل بذاته قابل للاختبار ، تم إنشاؤه لأداء مهمة محددة . يتم إنشاء الدوال أيضا عندما يكون مطلوب تكرار خوارزمية (حل برمجى) معينة فى عدة أماكن مختلفة من البرنامج الرئيسى . على سبيل المثال ، قد تكون هناك حاجة لتحويل درجة الحرارة من فهرنهيت إلى مئوية فى عدة أماكن فى البرنامج . بدلا من تكرار الكود ، فإنه يكون أكثر كفاءة ويكون البرنامج أكثر قابلية للصيانة إذا تم كتابة كود تحويل درجة الحرارة فى شكل "دالة" . يمكن بعد ذلك استدعاء هذه الدالة كلما كان ذلك مطلوبا لإجراء التحويل المطلوب .
الشكل العام لإعلان الدالة :
كود:
type name(parameters)
{
body
}
عادة (وليس دائما) ما تقوم الدالة بإجراء عملية معينة وإرجاع (إعادة) return بيانات إلى البرنامج القائم بالاستدعاء . النوع type فى الدالة يشير إلى نوع البيانات التى ترجعها ، والاسم name هو اسم الدالة ، وينبغى الفصل بين البارامترات parameters (إن وجدت) بفواصل . العبارات الموجودة داخل الدالة (جسم الدالة) يجب أن تطوق بزوج من الأقواس المعكوفة {…} .
فيما يلى مثال لإعلان دالة ، والتى تقوم بحساب محيط الدائرة circumference ، بدلالة نصف قطرها ، وتعود إلى البرنامج القائم بالاستدعاء . هنا ، نصف قطر الدائرة radius يتم تمريره كوسيط argument للدالة .
كود:
float Circumference(float radius)
{
float c;
c = 2*PI*radius;
return c;
}
لنفرض أننا نريد حساب محيط الدائرة التى نصف قطرها 2.5 cm ، وتخزين النتيجة فى متغير يسمى Circ ، يمكن استدعاء الدالة السابقة كما يلى :
كود:
Circ = Circumference(2.5);
إليك بعض الأمثلة :
مثال :
اكتب دالتين لحساب مساحة وحجم اسطوانة ، موضحا كيف تستخدم هذه الدوال فى البرنامج لحساب مساحة وحجم اسطوانة نصف قطرها 3.0 cm وارتفاعها 12.5 cm ، خزن المساحة فى المتغير c_area والحجم فى المتغير c_volume .
الحل :
البرنامج التالى يبين الدالتين . الدالة Cyl_Area لحساب مساحة الاسطوانة ، والدالة , Cyl_Volume لحساب حجم الاسطوانة .
كود:
//
// This function calculate the area of a cylinder. The radius and height
// are passed as parameters to the function
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculate the volume of a cylinder. The radius and height
// are passed as parameters to the function
//
Float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
البرنامج الرئيسى يستدعى هذه الدوال كما هو مبين أدناه . يستخدم نصف قطر وارتفاع الاسطوانة كبارامترات للدوال . يتم تخزين المساحة فى المتغير c_area والحجم فى المتغير c_volume .
كود:
/*-----------------------------------------------------------------------------------------------
This program calculates the area and volume of a cylinder. The radius and height
of the cylinder are passed as parameters to two functions which calculate the
area and the volume.
In this example the radius and height are assumed to be 3.0cm and 12.5cm
respectively.
The area is stored in variable c_area, and the volume is stored in variable
c_volume.
------------------------------------------------------------------------------------------------*/
//
// This function calculates the area of a cylinder. The radius and height are passed
// as parameters to the function
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculates the volume of a cylinder. The radius and height are
// passed as parameters to the function
//
float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
//
// Main program
//
void main()
{
float r, h, c_area, c_volume;
r = 3.0; // The radius
h = 12.5; // The height
c_area = Cyl_Area(r, h); // Calculate the area
c_volume = Cyl_Volume(r, h); // Calculate the volume
}
النماذج المبدئية (الأولية) للدوال Function Prototypes :
إذا لم يتم تعريف الدالة قبل استخدامها في البرنامج الرئيسي، فإن المترجم يولد خطأ. وذلك لأن المترجم لا يعرف نوع البيانات التي ترجعها الدالة ونوع بارامتراتها . الطريقة الوحيدة لتجنب رسائل الخطأ هي إنشاء نموذج مبدئى للدالة وإعلانه في بداية البرنامج قبل استدعاء الدالة من قبل البرنامج الرئيسي. ويتكون النموذج المبدئى للدالة من نوع الدالة واسمها، يليهما أنواع بارامتراتها .
فيما يلي مثال لإعلان النموذج المبدئى :
كود:
float Circumference(float radius);
اسم البارامترات اختيارى ، ويمكن تجنبه كما يلى :
كود:
float Circumference(float);
البرنامج التالى يوضح كيف يمكن تعديل البرنامج المبين أعلاه لاستخدام النماذج المبدئية ، حيث يتم إعلان النماذج المبدئية للدالة قبل البرنامج الرئيسى ، ثم يتم إعلان الدالتين بعد البرنامج الرئيسى .
كود:
/*-----------------------------------------------------------------------------------------------
This program calculates the area and volume of a cylinder. The radius and height
of the cylinder are passed as parameters to two functions which calculate the
area and the volume.
In this example the radius and height are assumed to be 3.0cm and 12.5cm
respectively.
The area is stored in variable c_area, and the volume is stored in variable
c_volume.
------------------------------------------------------------------------------------------------*/
float Cyl_Area(float, float);
float Cyl_Volume(float, float);
//
// Main program
//
void main()
{
float r, h, c_area, c_volume;
r = 3.0; // The radius
h = 12.5; // The height
c_area = Cyl_Area(r, h); // Calculate the area
c_volume = Cyl_Volume(r, h); // Calculate the volume
}
//
// This function calculates the area of a cylinder
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculates the volume of a cylinder
//
float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
الدوال الخالية (الفارغة) void Functions :
الدالة الفارغة هى إحدى الحالات التى تظهر فيها الكلمة المخصوصة (المحجوزة) void كمحدد لنوع الدالة ، للإشارة إلى أن الدالة لا ترجع أى قيمة لبرنامج الاستدعاء . بالمثل ، الدالة التى بدون بارامترات يتم تحديدها باستخدام الكلمة المخصوصة void فى قائمة بارامتراتها . مثل هذه الدالة يتم استدعاؤها بدون بارامترات .
فيما يلى مثال على دالة فارغة void ، والتى ببساطة تحدد جميع أطراف خرج المنفذ PORTB بالحالة المرتفعة . هذه الدالة ليس لها بارامترات ولا تعيد أى بيانات :
كود:
void SET_LED(void)
{
PORTB = 0xFF;
}
تمرير البارامترات إلى الدوال :
من المهم إدراك أنه كلما تم استدعاء دالة ببارامترات ( ما عدا المصفوفة ، والتى سوف نتناولها فى الفقرة القادمة) ، يتم تمرير جميع البارامترات إلى الدالة بواسطة قيمة . وهذا يعنى أن قيم هذه البارامترات يتم نسخها إلى الدالة واستخدامها محليا بواسطة الدالة . لا يمكن تعديل قيم هذه البارامترات بواسطة الدالة .
فيما يلى مثال بسيط لتوضيح مفهوم "تمرير البارامترات بواسطة قيمة" :
كود:
float Inc(float x)
{
x++;
return x;
}
//
// Main program
//
void main()
{
float a, b;
a = 5.0; // a = 5.0
b = Inc(a); // a = 5.0, b = 6.0
}
فى هذا المثال قيمة بارامتر الدالة (a) كان “5” قبل استدعاء الدالة . داخل الدالة ، النسخة المحلية لهذا البارامتر يتم تزايده إلى “6” ، لكن قيمة هذا البارامتر تظل “5” فى البرنامج الرئيسى . عندما تعود الدالة يتم تخصيص القيمة “6” للمتغير “b” .
تمرير المصفوفات إلى الدوال :
فى بعض التطبيقات ، قد نرغب فى تمرير مصفوفات إلى دوال . يعد تمرير عنصر واحد من المصفوفة أمرا سهلا . كل ما علينا فعله هو فهرسة index العنصر الذى نرغب فى تمريره . كما هو موضح فى الفقرة السابقة ، يتم تمرير مثل هذا المتغير إلى الدالة كقيمة . على سبيل المثال ، العنصر الذى فهرسه (ترتيبه) “5” بالمصفوفة MyArray ، لتمريره إلى دالة تسمى Sum وتخزين قيمة العائد فى المتغير “a” ، ببساطة يمكن كتابة ما يلى :
كود:
a = Sum(MyArray[5]);
تمرير المصفوفة بالكامل إلى دالة أكثر تعقيدا قليلا . فى هذه الحالة ، ببساطة نكتب اسم المصفوفة فى برنامج الاستدعاء . فى رأس الدالة ينبغى علينا أن نعلن مصفوفة من نفس النوع متبوعة بزوج من الأقواس الفارغة . من المهم أن ندرك أننا لا ننسخ المصفوفة بالكامل إلى الدالة ، ولكن ببساطة نمرر عنوان العنصر الأول من المصفوفة ، وهو أيضا يساوى اسم المصفوفة . ونظرا لأنه يتم تمرير العنوان إلى الدالة ، يقال أن عناصر الدالة تم تمريرها عن طريق المرجع . نتيجة لذلك ، يمكن تعديل عناصر المصفوفة الأصلية داخل الدالة . فيما يلى مثال لتوضيح العملية .
مثال :
اكتب برنامج لتحميل مصفوفة أعداد صحيحة تسمى “N” بالقيم من “1” إلى “10” . بعد ذلك استدعى دالة لحساب مجموع عناصر المصفوفة والعودة بالمجموع إلى برنامج الاستدعاء .
الحل :
البرنامج :
كود:
/*-----------------------------------------------------------------------------------------------
This program demonstrates how an array can be passed to a function. Here, array N is initialized with numbers 1 to 10. Then, function Sum is called to calculate the sum of the array elements. The sum is then returned to the main program and stored in variable s
------------------------------------------------------------------------------------------------*/
//
// This function calculates the sum of the elements of an array
//
int Sum(int A[ ])
{
char i;
int Total = 0;
for(i = 0; i < 10; i++) Total = Total + A[i];
return Total;
}
//
// Main program
//
void main()
{
int s, N[10];
char i;
for(i = 0; i < 10; i++) N[i] = i + 1; // Initialize array N
s = Sum(N); // Calculate the sum of elements
}
يتم تهيئة مصفوفة الأعداد الصحيحة N بالقيم من 1 إلى 10 فى البرنامج الرئيسى . بعد ذلك يتم استدعاء الدالة Sum ويتم تمرير المصفوفة إلى هذه الدالة . الدالة تحسب مجموع عناصر المصفوفة وتعيد المجموع إلى المتغير s فى البرنامج الرئيسى . لاحظ أن المصفوفة تسمى N فى الدالة الرئيسية ، لكنها تسمى A فى الدالة .
|