قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 03:29 PM المشاركة 9   
افتراضي



النماذج الأولية للدالة Function Prototypes :
إذا لم يتم تعريف الدالة قبل أن تستدعى , فإن المترجم سوف يولد رسالة خطأ . أحد طرق التغلب على هذه المشكلة هى إنشاء "نموذج أولى الدالة" function prototype . يمكن بناء النموذج الأولى للدالة بسهولة عن طريق نسخ رأسheader الدالة وإلحاق فاصلة منقوطة ";" بها ( لابد أنك لاحظت عدم وجودها فى السابق) . إذا كانت الدالة لها وسائط , فإن إعطاء أسماء لهذه الوسائط ليس إلزاميا, ولكن يجب تحديد نوع بيانات الوسائط .
مثال :
يتم إعلان النموذج الأولى للدالة المسماة Area , ومن المتوقع أن يكون لدى الدالة وسيط بنوع البيانات float:

كود:
float Area(float radius);

النموذج الأولى للدالة لهذه يمكن أيضا إعلانه بالطريقة التالية :

كود:
float Area(float);
النماذج الأولية للدوال يجب أن يتم إعلانها عند بداية البرنامج . بعد ذلك يمكن إجراء تعريفات واستدعاءات الدالة عند أى نقطة من البرنامج .

مثال 5 :

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 03:31 PM المشاركة 10   
افتراضي


مثال 5 :
المطلوب :
تكرار المثال 4 ولكن مع إعلان الدالة LowerToUpper كنموذج أولى للدالة .
الحل :
فيما يلى البرنامج . حيث يتم إعلان الدالة LowerToUpper كنموذج أولى للدالة عند بدابة البرنامج . فى هذا المثال , التعريف الفعلى للدالة تم كتابته بعد البرنامج الرئيسى .


كود:
/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
This program converts the lowercase character in variable Lc to uppercase
and stores in variable Uc.
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/
unsigned char LowerToUpper(unsigned char);
/∗ Start of main program ∗/
void main()
{
unsigned char Lc, Uc;
Lc = ‘r’;
Uc = LowerToUpper(Lc);
}
/∗ Function to convert a lower case character to upper case ∗/
unsigned char LowerToUpper(unsigned char c)
{
if(c >= ‘a’ && c <= ‘z’)
return (c – 0x20);
else
return c;
}

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 03:33 PM المشاركة 11   
افتراضي


ميزة هامة لاستخدام النماذج الأولية للدوال :هى أنه إذا كان هناك نموذج أولى لا يطابق تعريف الدالة الفعلية , فأن المترجم سوف يكشف ذلك ويعدل أنواع البيانات فى استداء الدالة لتتناسب مع أنواع البيانات المعلنة فى النموذج الأولى للدالة .
نفترض أن لدينا الكود التالى :

كود:
unsigned char c = 'A'; unsigned int x = 100; long Tmp; long MyFunc(long a, long b); // function prototype void main() { . . .. . .. . .. . .. . . . . .. . .. . .. . .. . . Tmp = MyFunc(c, x); . . .. . .. . .. . .. . . . . .. . .. . .. . .. . . }
فى هذا المثال , لأن النموذج الأولى للدالة أعلن الوسائط كنوع long , فإنه يتم تحويل المتغيرات c و x إلى long قبل أن تستخدم داخل الدالة MyFunc .

تمرير المصفوفات إلى الدوال Passing Arrays to Functions


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 04:58 PM المشاركة 12   
افتراضي


تمرير المصفوفات إلى الدوال Passing Arrays to Functions
هناك العديد من التطبيقات حيث نرغب فى تمرير المصفوفات إلى الدوال . تمرير عنصر مصفوفة واحد يتم بطريقة مباشرة , ببساطة يتم تحديد الرقم المسلسل index لعنصر المصفوفة المراد تمريره .
مثال :
فيما يلى إستدعاء لدالة والتى تمرر العنصر الثانى (index = 1 ) للمصفوفة "A" إلى الدالة Calc . من المهم أن ندرك أنه يتم تمرير العنصر المفرد عن طريق القيمة value ( أى يتم تمرير نسخة من عنصر المصفوفة إلى الدالة) :

كود:
x = Calc(A [1]);
فى بعض التطبيقات قد نرغب فى تمرير مصفوفات كاملة إلى الدوال . يمكن استخدام اسم المصفوفة كوسيط argument للدالة , مما يسمح بتمرير المصفوفة بأكملها . لتمرير مصفوفة كاملة إلى دالة , يجب أن يظهر اسم المصفوفة فى حد ذاته داخل الأقواس . حجم المصفوفة لا يتم تحديده داخل إعلان الوسيط رسميا .
فى رأس المصفوفة يجب تحديد اسم المصفوفة بزوج من الأقواس الفارغة . من المهم أن ندرك أنه عند تمرير مصفوفة كاملة إلى دالة , ما يتم تمريره فى الواقع ليس نسخة من المصفوفة ولكن عنوان العنصر الأول بالمصفوفة ( أى يتم تمرير عناصر المصفوفة حسب المرجع reference , وهو ما يعنى أنه يمكن تعديل عناصر المصفوفة الأصلية داخل الدالة) .
الأمثلة التالية توضح تمرير مصفوفة كاملة إلى دالة .
مثال 6 :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 04:59 PM المشاركة 13   
افتراضي


مثال 6 :
المطلوب :
كتابة برنامج لحفظ الأعداد من 1 إلى 10 فى مصفوفة تسمى Numbers . ومن ثم إستدعاء دالة تسمى Average لحساب متوسط average هذه الأعداد .
الحل :
فيما يلى البرنامج المطلوب .
الدالة Average تستقبل عناصر المصفوفة Numbers وتقوم بحساب متوسط عناصر المصفوفة .


كود:
/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ This program stores numbers 1 to 10 in an array called Numbers. Function Average is then called to calculate the average of these numbers. ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/ /∗ Function to calculate the average ∗/ float Average(int A[ ]) { float Sum = 0.0, k; unsigned char j; for(j=0; j<10; j++) { Sum = Sum + A[j]; } k = Sum / 10.0; return k; } /∗ Start of the main program ∗/ void main() { unsigned char j; float Avrg; int Numbers[10]; for(j=0; j<10; j++)Numbers[j] = j+1; Avrg = Average(Numbers); }


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 05:01 PM المشاركة 14   
افتراضي


مثال 7 :
المطلوب :
تكرار المثال السابق , ولكن هذه المرة يتم تعريف حجم المصفوفة عند بداية البرنامج ومن ثم تمرير حجم المصفوفة إلى الدالة .
الحل :
فيما يلى البرنامج المطلوب :

كود:
/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ This program stores numbers 1 to N in an array called Numbers where N is defined at the beginning of the program. Function Average is then called to calculate the average of these numbers. ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/ #define Array_Size 20 /∗ Function to calculate the average ∗/ float Average(int A[ ], int N) { float Sum = 0.0, k; unsigned char j; for(j=0; j<N; j++) { Sum = Sum + A[j]; } k = Sum / N; k; } /∗ Start of the main program ∗/ void main() { unsigned char j; float Avrg; int Numbers[Array_Size]; for(j=0; j<Array_Size; j++)Numbers[j] = j+1; Avrg = Average(Numbers, Array_Size); }


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 05:03 PM المشاركة 15   
افتراضي


من الممكن أيضا تمرير المصفوفة بالكامل إلى الدالة باستخدام المؤشرات pointers . يتم تمرير عنوان أول عنصر بالمصفوفة إلى الدالة , وبعد ذلك يمكن للدالة التعامل مع المصفوفة تبعا للمطلوب باستخدام عمليات المؤشر كما فى المثال التالى .
مثال 8 :
المطلوب :
تكرار المثال 4-6 , لكن فى هذه المرة يتم استخدام المؤشر لتمرير عناصر المصفوفة إلى الدالة .
الحل:
فيما يلى البرنامج المطلوب .
يتم استخدام مؤشر لعدد صحيح integer pointer لتمرير عناصر المصفوفة إلى الدالة , ثم يتم التعامل مع عناصر المصفوفة باستخدام عمليات المؤشر . لاحظ أنه يتم تمرير عنوان العنصر الأول بالمصفوفة كعدد صحيح بالعبارة &Numbers[0]

كود:
/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ This program stores numbers 1 to 10 in an array called Numbers. Function Average is then called to calculate the average of these numbers. ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/ /∗ Function to calculate the average ∗/ float Average(int ∗A) { float Sum = 0.0, k; unsigned char j; for(j=0; j<10; j++) { Sum = Sum + ∗(A + j); } k = Sum / 10.0; return k; } /∗ Start of the main program ∗/ void main() { unsigned char j; float Avrg; int Numbers[10]; for(j=0; j<10; j++)Numbers[j] = j+1; Avrg = Average(&Numbers[0]); }


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-12-2012, 05:05 PM المشاركة 16   
افتراضي


تمرير المتغيرات عن طريق "المرجع" Reference إلى الدالة :
فى الوضع الافتراضى , يتم تمرير الوسائط arguments إلى الدوال عن طريق القيمة . على الرغم من أن هذه الطريقة لها العديد من المزايا الواضحة , إلا أن هناك حالات يكون من الأكثر ملائمة وكفاءة تمرير عنوان الوسائط بدلا من ذلك , وهذا هو "تمرير الوسيط عن طريق المرجع" . عندما يتم تمرير عنوان لوسيط , يمكن تعديل القيمة الأصلية عن طريق الدالة , وبالتالى فإن الدالة ليس من الضرورى أن تعود بأية متغيرات .
المثال التالى يوضح كيف يمكن تمرير عنوان الوسائط إلى الدالة وكيف يمكن تعديل قيم هذه الوسائط داخل الدالة .
مثال 9 :
المطلوب :
كتابة دالة تسمى Swap لقبول وسيطين لأعداد صحيحة ومن ثم مبادلة بين swap قيم هذه الوسائط , مع استخدام هذه الدالة فى برنامج رئيسى لعمل مبادلة بين قيم متغيرين .
الحل :
فيما يلى البرنامج المطلوب .
يتم تعريف الدالة Swap من النوع الفارغ void حيث أنها لا تعود بأى قيمة . هذه الدالة لها وسيطين , a و b , وفى رأس الدالة يتم استخدام مؤشرين للأعداد صحيحة integer pointers لتمرير عناوين هذه المتغيرات . بداخل جسم الدالة , يتم قبول قيمة الوسيط عن طريق وضع الحرف “*” أمام الوسيط . فى داخل البرنامج الرئيسى , يتم تمرير عناوين المتغيرات إلى الدالة باستخدام الحرف “&” أمام أسم المتغير . فى نهاية البرنامج , يتم تحديد المتغيرات p و q بالقيم 20 و 10 على الترتيب .


كود:
/*************************************************************
This program shows how the address of variables can be passed to functions.
The function in this program swaps the values of two integer variables.
***************************************************************/
/* Function to swap two integers */
void  _Swap(int *a, int *b)
{
int temp;
temp = *a; // Store a in temp
*a = *b; // Copy b to a
*b = temp; // Copy temp to b
}

/* Start of the main program */
void main()
{
int p, q;
p = 10; // Set p = 10
q = 20; // Set q = 20
_Swap(&p, &q); // Swap p and q (p=20, q=10)
}



الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 01:40 AM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)