MR.SD

شرح مفصل للدوال في C++

24 ردود في هذا الموضوع

--------------------------------------------------------------------------------

بسم الله الرحمن الرحيم

اخوتي الاعزاء اعضاء منتديات الفريق العربي للبرمجه المحترمين ..

طوال قراءتي في المنتديين الذين لطالما استفدت منهما علمية وهي منتديات العاصفة ومنتديات الفريق العربي للبرمجه وجدت ان هناك كثير من الاعضاء لديهم مشاكل في فهمهم للدوال في لغة C++ . لذلك قررت إن شاء الله تعالى ان ابدأ سلسلة من الدروس التي تعتبر مقدمة جيده وقوية الى كل من وصل الى الدوال ووقف ولكن اتمنى ان انوه الى الملاحظات التاليه وهي ملاحظات عامه ..

اولا ::: ان يكون العضو لديه معلومات في هذه اللغة اي ليس من الممكن ان اشرح في موضوع الدوال وياتي عضو اخر ويسال عن طريقة تعريف المتغيرات او الفرق بين المتغير العام والخاص . هذه المعلومات ممكن ان تاتي من خلال الشرح .

ثانيا ::: انا ذكرت في بداية حديثي منتديان اثنين وهما العاصفة والفريق العربي للبرمجة لذلك سيكون هذا الموضوع في هذين المنتديين ((هذا لا يتعارض مع قوانين الادارة في طرح المواضيع )) لذلك فان الموضوع لو تكرر بغير هذين الموقعين يجب ذكر المصدر وهو اسم الموقعين وايضا اسم الكاتب .

ثالثا ::: لغرض تطبيق البرامج الموجودة في الموضوع ارجو استخدام اما Turbo C++ او Dev C++ لانني استخدمها حتى لاتحصل مشاكل .

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

اول شئ سأبدأ به في هذا الموضوع الموسع هو مقدمة عامه عن مفهوم الدوال وعن فائدتها وفرقها عن دوال الرياضيات من دون استخدام اي كود او فقط برامج قليله صغيره توضيحيه .

توكلنا على الله ..

5

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بسم الله الرحمن الرحيم

اتمنى ان تكونوا بخير ..

نبدأ على بركة الله ..

المقدمة ..

في بداية دراستي للغة C++ سمعت عن شئ اسمه الدوال ، استغربت هل هو مفهوم مشابه لمفهوم الالدوال الرياضية ، هل تقع عليها نفس العمليات ونفس القواعد والشروط ولكن تكون بصورة برمجية ، ولكن عندما تقدمت في هذه اللغة ووصلت الى مرحلة الدوال بدأت بدراسة مستفيضة عن هذا الجزء من اللغة ووجدت انه يتشابه مع دوال الرياضيات بالاسم والفكرة فقط ، فلو اردنا ان نتكلم عن الدوال الرياضية سنقول انها معادلة تحتوي على مجاهيل لها مهمة معينة ، ابسط مثال على ذلك ..

F(x)=x+3

هذه دالة رياضية ، ومن الواضح انها تحتوي على مجهول واحد .. اما الدالة البرمجية ..

لناخذ هذا المثال من واقعي الشخصي ويمكن ستنتبهوا له حتى انتم ..

وانا عمري 10 اعوام بدأت امي تعلمني طريقة صنع الحليب صباحا أي قبل ان اذهب الى المدرسة فقالت لي .. (( اولا ننضف القدح اللازم لشرب الماء بعدها نبدأ بغلي الماء ثم بعد ذلك نضع كمية من الحليب في القدح مع كمية من السكر ثم نسكب الماء عليها بعد ان يصل الى درجة حرارة معينة ثم نبدأ بتحريك المزيج لكي بمتزج مع بعضه بصورة جيده ثم نبدأ بالشرب .))

من الطبيعي ان اقوم بعدها انا بصنع الحليب((( الا اذا))) واضع خمسون خطا تحت كلمة الا اذا .. الا اذا انا خطأت بالطريقة وقمت مثلا بوضع الحليب والسكر من دون ان انظف القدح فستاتي والدتي وتخبرني بانني اخطأت وقد اصاب بامراض نتيجة لذلك والمرض كما تعلمون لن يصيبني مباشرة .. وانما بعد فترة ..

او قد يكون الخطأ ان انسى وضع السكر فيكون الحليب ذو مذاق غير مرغوب فيه ولكن بعد ان اتعلم الطريقة جيدا (وهو الذي حصل بعدما قمت باخطاء عديده في الاول)) ولكن الحمدلله الى الان انا اصنع حليبي الصباحبي بنفسي ..

ناتي الان لتفسير الفائدة من هذا المثال لانكم لحد الان لم تعرفوا مافائدته ...

اولا :: لو عدنا الى طريقة والدتي سنجد انها عبارة عن خطوات .. وهي خطوات ثابتة بالنسبة لامي لصنع الحليب ولكن لدي سؤال اطرحه الان .. هل احتاج بعد ذلك الى ان تقوم امي كل يوم بتعليمي الطريقة .؟؟؟ ام ماذا ؟؟؟

وهذا شئ اساسي في الدوال لذلك لو قمنا بتسمية هذه الدالة بدالة صنع الحليب لاحتوت على الخطوات الموضوعه داخل القوسين . فهذه الدالة ساقوم بحفظها في ذاكرتي وعندما ااتي لصنع الحليب فقط اقوم باستدعائها من ذاكرة الدماغ لاقوم بتنفيذها وهي خالية من الاخطاء لانني الوالدة قد قامت بتعليمي جيدا حتى بعد ان اخطأت فيها ..

ثانيا ::: عندما قصدت في المثال المرض فهي لم تكن جملة فقط من دون فائدة عليمية لها وانما قصدت بها التالي وهو ان خطأ بسيط قد يؤدي لمشكلة قوية او ممكن ان تكون ثغرة في برنامج كله بسبب الدالة كما قد يصيبني المرض بسبب عدم تنظيف القدح .فقد اصاب بمرض خطير يؤدي الى ....

ثالثا :: هذه الطريقة خاصة بوالدتي فهي ليست ثابته وقاعدة عامة لدى جميع النساء فقد تكون ام زميلي دالتها لصنع الحليب تختلف عن دالة امي لذلك فانني اقصد من هذه الملاحظة ان الدالة ليس من شروطها ان تكون ثابتة بين الناس . فمن الممكن ان ابرمج دالة لطباعة جملة على الشاشة باستخدام printf وممكن ان استخدم putcha والاثنين لهما نفس المهم مع اختلاف بسيط بينهم .

رابعا :: هناك شئ لم اذكره في المثال متعمدا لكي لا تختلط الامور وها انا الان اذكره وهو انه يمكن ان احد اخوتي في يوم من الايام يستيقظ معي لكي يذهب الى عمله .. اي هناك احتمال ان يكون هناك اكثر من قدح للشرب .. فكيف علاج مثل هذه المشكله ؟؟ علاجها هو بالتفكير مسبقا بهذا الشئ ان يكون العدد اكثر من واحد لذلك ساخذ احتمال اكثر من شخص فعندما ياتي اخي ويقول اصنع لي معك كوبا من الحليب اقوم بادخال العدد 2 لدالة صنع الحليب التي تعلمتها من والدتي والعدد 2 هنا هو عدد الاقداح لان واحدا لي والاخر لاخي وهذا مايسمى برميجا بالمعاملات او parameters وتلفظ باراميتر . ((سااتي لشرحها لاحقا ولكن هذا فقط لكي نفكر بطريقة صحيحه .

فالباراميتر هو الشئ الذي يمكن ان يتغير في الدالة كان يكون اسم او رقم او اي شئ يتوقع ان يتغير عند ادخال المستخدم للمعلومات (المستخدم وليس المبرمج ) . فمثلا لو برمجنا دالة صنع الحليب سنطلب من السمتخدم ادخال عدد الاقداح وهو الشئ الوحيد الذي يمكن ان يتغير ... فمهما كان العدد ستبقى طريقة الصنع ثابتة ..

ومن الممكن تطوير الدالة لتستقبل باريمتر اخر لو كان اخي لديه اختلاف معي في عدد معالق السكر التي اضعها له .. فهذا يمكن وضعه في السؤال ايضا وكباراميتر ايضا . فنساله كم عدد المعالق التي تريد من السكر فيجيب اثنين مثلا وانا دائما اصع ثلاثة وهذا اختلاف متوقع حصوله ..

لذلك بعد هذا المثال المتكامل الذي وضحت فيه اهم وابرز اجزاء الدوال سنأتي الى تعريفها العلمي ..

هي مجموعة من الجمل والخطوات البرمجية تنفذ سوية مهمة معينة وايضا الدوال تعتبر برنامجا فرعيا أي يمكن اخذ الداله من برنامج نعمل عليها ونضعها في برنامج اخر لتعطي نفس النتيجة .

وظيفة الدالة او الفائدة منها تظهر عندما تصبح برامجنا اكثر تعقيدا وطولا .. أي تلك التي تصل الى الاف الاسطر البرمجية .. حيث تكون عملية اكتشاف خطأ يحصل في برنامج بسهولة اكثر مما لو استخدمة الدالة الرئيسية main فقط . انا متأكد انك تفكر في ان اطول برنامج قد قمت ببرمجته لم يصل الى العشرين سطرا .. ولكن لا .. كلما توسعت في اللغة اكثر كلما زاد برنامجك طولا وتعقيدا .. لاننا لانبقى على نفس البرنامج طوال حياتنا وانما نتوسع في طريقة الحل والتفكير ..

من الواضح ان ابسط امور الحياة تتضمن دوال لم نكن نفكر بها سابقا لذلك فانا اعطيكم نصيحة لتخيل هذا المثال مع امثلة اخرى مثلا لدينا دالة من الواقع ايضا ولها نفس الامور في مثالنا السابق

وهو عن دالة الاتصال بالهاتف . .. فلكي نقوم بالاتصال نقوم اولا بالبحث عن الاسم المراد الاتصال به ثم نضغط على زر الاتصال وهنا لدينا شرط وهو ان يكون الهاتف مشغولا او خارج نطاق التغطيه او ان يتم رفع السماعه .

سؤال يطرح نفسه .. هل يتطلب هذا المثال(الدالة ) باراميتر او معامل له ..؟؟؟؟؟

نعم .. والمعامل هنا هو رقم الهاتف .. فالشئ الوحيد الذي يختلف لدينا في كل مرة عندما نتصل هو رقم الهاتف فقط فلا يمكن ان نتصل في المرة القادمة بالضغط على زر الخروج مثلا ..

هذه هي نهاية المقدمة سأترككم متعمدا لمدة يومين لغرضين وهما ان تقوموا بدراسة هذا الشرح جيدا لكي نذهب برمجة الدوال تفصيليا مع امثلة عليها ..

والغرض الثاني لكي اقوم بتحضير الدرس الثاني ..

اتمنى بعد ان تقرأوا الموضوع ويعجبكم شرحي ان تكتبوا ذلك لكي ابقى على نفس الطريقة او اغيرها ومن دون مجاملة وكذلك اكتبوا رايكم في السؤال التالي هل اضع الدرس القادم في نفس هذا الموضوع ام اقوم بوضعه بموضوع منفصل ..

والى الادارة الكريمة اتمنى ان تقوم بتثبيت هذا الموضوع لكي يكون مفيدا للجميع ..

تحياتي العطرة والى اللقاء في الدرس الثاني

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ثلاثين قراءة ولا شخص غير الاخ moon land يرد على الموضوع وانا تعبت من الكتابة ..

على الاقل اريدكم ان تبينوا هل الموضوع واضح ام لا ..؟؟؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مجهود رائع

بس فيه حاجة كل الشرح ده في المقدمة إمال الباقي هيبقي اد ايه :D

اشرح براحتك وإحنا معاك للنهاية

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بسم الله الرحمن الرحيم

ها نحن ثانية نعود في دروسنا عن الدوال وإن شاء الله سناخذ اليوم تعريف الدوال .

في البداية او ان اوضح ان هناك نوعين من الدوال وكذلك هنالك مكانين لتعريف الدوال

انواع الدوال ..

اولا .. الدالة التي تعيد قيمة .

هي تلك الدالة التي يراد من خلالها ترجيع قيمة لكي تستخدم في البرنامج الريئيسي

مثلا في دالة اتصال الهاتف التي ذكرتها في الدرس السابق كنا نحتاج لترجيع قيمة وهي اذا تمت عملية الاتصال بنجاح ..

التوضيح ..

بعد ان نبرمج الدالة الخاصة بالاتصال سنختبرها هل تمت عملية الاتصال ام ان الهاتف مشغول ولاحظوا معي هنا جملة شرطية تحتوي اذا (IF) أي انه اذا قمنا بالاتصال فارجع القيمة تم والا فارجع لم يتم ..

مالفائدة من هذا الشئ (الترجيع ) .؟؟؟

الفائدة .. لو اننا اختبرنا عمل هذه الدالة في البرنامج الرئيسي MAIN ووضعنا القيمة 1 عند نجاح عملية الاتصال والقيمة 0 عند عدم نجاحها لظهرت لنا قيمة من تلك القيم لنتيجة الشرط اما 1 او 0 .

وانواع الترجيع هي على انواع المتغيرات نفسها ((طبعا لا اقصد المتغيرات ولكن اقصد انواع المتغيرات )) ان هنالك ترجيع من نوع عدد صحيح int وهنالك ترجيع من نوع رمز char . ويعتمد نوع الترجيع على نوع الدالة

واذا كانت الدالة لا ترجع أي قيمة ونعرف ذلك من خلال تفكيرنا وتحليلنا لها قبل عملية الكتابة البرمجية فنحن نكتب الكلمة المحجوزة void والتي تبين بان الدالة لاتعيد أي قيمة ..

طريقة تعريف الدالة ..

نستطيع تعريف الدالة في مكانين من البرنامج وهذين المكانين هما اما قبل الدالة main او بعدها ولا توجد اختلافات كبيره بينها سوى اختلافين سنوضحهما بعد قليل .

الشكل العام للتعريف

Data type  Function_name ()

المقصود من data type هو نوع الدالة اذا كانت عددية او رمزية او ..... . اما function name فهو اسم الدالة ويخضع اسم الدالة لجميع قوعد الاسماء في المتغيرات وهي واضحة للجميع .

مثال : عرف دالة من نوع عدد صحيح اسمها number ..

الحل : طبعا لا يوجد سؤال في الدنيا مثل هذا السؤال ولكن هذا للتوضيح فقط وتعلم طريقة الاستخدام

int number ()

هذا هو تعريف الدالة المطلوبه بالسؤال .. ولو دققنا النظر لوجدنا ان number يشبه الى حد كبير تعريف المتغيرات ولكن الفرق هو وجود اقواس ومن هنا اكتب لكم ملاحظة جوهريه ومهمه جدا جدا ...

ملاحظة .. تتميز الدالة عن أي تعبير موجود في لغتي السي والسي ++ بوجود اقواس امامها .. وهذا بالنسبة للدوال الجاهزة وللدوال التي نبنيها ونستدعيها نحن .. فمثلا دالة الطباعة في لغة السي Printf فمن الخطأ التعبير عنها سواء بشرح او بعملية الكتابة البرمجيه بالصورة التي كتبتها الان انا .. لكن الصورة الصحيحه هي ان تكتب هكذا printf() لتتميز على انها دالة .

سؤال يطرح نفسه .. ما هي فائدة الاقواس .. ؟؟

الجواب .. الغرض الاول كما قلنا للتدليل على انها دالة ولكن ليست هذه هي الفائده فقط وانما لان المعامل او الparameter يوضع داخل الاقواس .. كما قلنا في الدرس السابق عنه ...

لتوضيح ما سبق سنقوم بكتابة مثالنا السابق الخاص بصنع الحليب بدالة برمجية متكاملة مع شرحها ..

اولا نحلل الدالة .. الدالة خطواتها معروفة مسبق ولكن هل تحتاج الى معاملات وكذلك الى ترجيع ..؟؟

من الواضح انها تحتاج الى معاملات وهو عدد الاقداح .. اذا لدينا معامل من نوع int ومعامل اخر هو عدد ملاعق السكر وهو ايضا من نوع int .

لا تحتاج هذه الدالة الى ترجيع لانه كما تعلمون مالذي يمكن ان نعيده .. نحن سنصنع بواسطتها كوب حليب ولا نرجع أي شئ ... ولكي لا يصبح هناك فهم خاطئ فالترجيع هنا ليس ترجيع ما يبقى من الحليب او السكر ولكن ترجيع شئ نستفاد منه بالدالة الرئيسية main تفيدنا في عمل البرنامج . واذا ما فهمتوا هذا الجزء انا اقوللكم هذا المتوقع ولكن مع الدروس وكذلك مع الممارسة ستفهموه جيدا .

Void milkmake( int cubs  ,  int shugar ) 
{

}

هذا هو تعريف الدالة وسنوضحه بالتفصيل الان ..

استعملنا كلمة void لان الدالة لا ترجع أي شئ وقد وضحنا هذا الشئ قبل قليل . لذلك فان الدالة لا نوع لها .

Milkmake هنا هو اسم الدالة وهي دالة صنع الحليب .

بعد اسم الدالة تاتي الاقواس التي في داخلها تكتب المعاملات . ولدينا اول معامل هو cubs والذي هو عدد الاقداح واخذ النوع int وايضا للدالة معامل اخر وهو shugar الخاص بعدد معالق السكر .

اما الاقواس {} فهي تعني ان بما داخلها هو جسم الدالة .

يمكننا ان نضع الخطوات الخاصة بتلك الدالة بين هذه الاقواس

هنا بينا للمصرف الخاص بلغة سي ++ باننا قد قمنا بتعريف دالة .

والان سنقوم بكتابة مثال الاس التربيعي وهو مثال برمجي بسيط يبين لنا برمجة الدوال

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

لدينا الان برنامج سنقوم ببرمجته مرتين الا وهو برنامج الاس التربيعي .. ففي المرة الاولى سنجعل البرنامج يرجع قيمة الناتج وفي المرة الثانية سنطبع النتيجة من دون ترجيع ..

الاول ...

// Creating a function and using it. Doesn’t use return. 

#include <iostream>
using namespace std;

void square(int i);

int main(void)
{
int num;
cout << "Please enter a number: ";
cin >> num;
square(num);
return 0;
}

void square(int i)
{
int sq = i * i;
cout << "Square of " << i << " is " << sq;
}

والثاني

// Creating a function and using it. Uses return. 

#include <iostream>
using namespace std;

int square(int i);

int main(void)
{
int num;
int sq;
cout << "Please enter a number: ";
cin >> num;
sq = square(num);
cout << "Square of " << num << " is " << sq;
return 0;
}

int square(int i)
{
int sq = i * i;
return sq;
}

والان سنأتي الى تفصيل البرنامجين ..

في البرنامج الاول قمنا بتعريف الدالة قبل الدالة الرئيسية وهو شئ مسموح به باللغتين السي والسي++ . ولكن مع ملاحظة شئ وهو وجود الفارزة المنقوطة في نهاية العبارة . لكن لو قمنا بتعريفها بعد الدالة main فلا يمكن وضع فارزة منقوطة ...

void square(int i);

استخدمنا الكلمة المحجوزة void والتي مفادها كما اسلفت سابقا بان الدالة لا تقوم بترجيع اي شئ لذلك نستخدمها هنا في هذا المثال .

لو خرجنا لدقائق من السي وذهبنا الى الرياضيات .. عندما نقوم بعملية تربيع رقم فنحن نحتاج الى كم معامل لذلك

مثلا لو سالتك ربع الرقم 5 ستقول مباشرة 25 لانك استخدمت الطريقة المعروفة بضرب العدد في نفسه اي

5 * 5 .. وبذلك كان الناتج 25 ..

نفس الطريقة سنتخدمها ولكن اين ..؟؟؟ ستكون داخل اقواس جسم دالة square وايضا ان عدد معاملات هذه الدالة هو معامل واحد لان الدالة لا تتطلب اكثر من رقم واحد هو الرقم الذي سنقوم بعملية الضرب عليه .

وهذا ما نلاحظه هنا ..

void square(int i) 
{
int sq = i * i;
cout << "Square of " << i << " is " << sq;
}

قمنا بتعريف المعامل i على انه عدد صحيح ومن ثم تم تعريف المتغير sq الذي سيحتفظ بنتيجة الضرب .. ثم بعد ان تتم عملية الضرب هذه تذهب الدالة الى كائن الطباعة cout ليطبع لنا النتيجة ..

هنالك ملاحظة اود ذكرها وهي اننا ندرس لحد الان الدالة الجديدة ولم ندخل في main ونرى كيفية الاستدعاء وانا اقول هذا لكي لا تختلط الامور لديكم ..

اما البرنامج الثاني فانه يعمل على نفس الفكرة وهي ضرب المعامل i بنفسه لكي تظهر النتيجة ولكن الفرق هو اننا استخدمنا فيه الترجيع فقمنا بتعيين نوع الدالة على انها int

int square(int i) 
{
int sq = i * i;
return sq;
}

وبعدها عرفنا المتغير sq الذي تخزن بداخله نتيجة الضرب ثم نقوم بترجيع sq .

سؤال لماذا قمنا بترجيع sq و لم نقم بترجيع بترجيع i ؟؟

الجواب .. هو لاننا نريد ترجيع قيمة ناتج الضرب... فلا يوجد اي خطأ اذا قمنا بترجيع i ولكن المشكلة هي اننا سنرجع قيمة i الى main ونقوم بطباعتها بعد ان ادخلناها .. فما الفائدة من البرنامج اذا .؟؟؟؟

المقصود من الترجيع هو ترجيع قيمة الناتج الى الدالة الرئيسية main للتصرف بها هناك حسب ما نحتاج من البرنامج ففي هذا البرنامج نحن نحتاج الى ان نطبع هذه القيمة فعندما نرجع قيمة ناتج الضرب في الدالة square اي تذهب قيمة ناتج الضرب الى الدالة الرئيسية فاننا سنقوم بطباعتها من هناك ...

ملاحظة اتمنى دراستها جيدا وهي ..

عندما نعرف دالة قبل دالة main فانه يمكننا ان نكتب فقط نوع المعامل من دون ان نضع له اسما ولكن بعد ان نكمل كتابة الmain نبدأ ببرمجة الدالة الجديدة فانه يستوجب علينا ان نكتب اسم ونوع المعامل .

ولكن اذا قمنا بتعريف الدالة وبرمجتها بعد الmain فانه يتم كتابة الدالة كاملة اي اسمها ونوع واسم معاملاتها ..

من هذين البرنامجين استطعنا ان نفهم شيئا مبسطا عن الترجيع وعدم الترجيع ...

الان ساتوقف عن طرح الدروس وارجو منكم الشئ التالي وهو ..

اي عضو قرا الدروس ارجو ان يكتب استفساره لانني سادخل في دوال اطول واصعب وساقوم بعملية شرح الاستدعاء ..

فالذي ارجوه اسالوا اذا كان هناك اي شئ غير واضح ... لكي اوضحه وان اضع امثله اخرى اذا استقضى الامر ..

تحياتي وانا في الخدمة ...

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بسم الله الرحمن الرحيم

اليوم سنكمل إن شاء الله درسا اخر في الدوال .. وهو شرح عن استدعاء الدوال ...

بعد انهاء برمجة دالة تؤدي غرض معين في برنامجنا يجب ان نقوم بتشغيل تلك الدالة .. وتشغيلها يكون في وقت نحن نحدده كأن يكون نتيجة لاختبار شئ في داخل البرنامج او نتيجة لطلب من المستخدم ..

والمقصود من تشغيل الدالة هنا هو استدعائها او مايسمى بـ calling .

سنشاهد هذا المثال البرمجي المهم وهو برمجة واستدعاء عدة دوال ..

#include<iostream.h>

int sum(int , int);
int sub(int,int;
int mul(int,int);
int dev(int,int);

int main()
{
int a,b,result;
char op;
cout << "pleas enter the first number" << endl;
cin >> a;
cout << "pleas enter the second number" << endl;
cin >> b;
cout << "type + for summing and - for subtracting and * for multiplaying>> " << endl;
cin >> op;

switch(op)
{
case '+':
result = sum(a,B);
cout << result;
break;

case '-':
result = sub(a,B);
cout << result;
break;

case '*':
result = mul(a,B);
cout << result;
break;
}

}

int sum(int x,int y)
{
return x+y;
}


int sub(int x,int y)
{
return x-y;
}

int mul(int x,int y)
{
return x*y;
}

طبعا هذا المثال هو لانشاء حاسبة تقوم بعملية الجمع والطرح والضرب بين عددين

قمنا ااولا بتعريف ثلاثة دوال الاولى sum الخاصة بجمع عددين والثانية sub والخاصة بطرح عددين والثالثة mul والتي تختص بضرب عددين .. لاحظوا ان الدوال عندما عرفناها في الجزء العلوي فوق الدالة الرئيسية كانت معاملاتها لا تحتوي اسماء وانما مجرد انواع وهذا مقبول في السي بلس بلس والسي القياسية ايضا .. اما برمجتها وضع اسماء للمعاملات فكانت بعد ان اكملنا برمجة الدالة الرئيسية mian .

معلومة برمجية .. انا قلت في الدرس السابق يمكن برمجة الدالة في مكانين اما قبل الدالة الرئيسية او بعدها ولكن هناك فرق في المكانين وهو .. لو قمنا ببرمجة الدالة كما في المثال السابق اي بعد الدالة الرئيسية يتوجب علينا ان نقوم بتعريفها قبل الدالة الرئيسية main وهذا هو الذي حصل في مثالنا السابق .. والسبب في ذلك هو ان مصرف لغة السي والسي بلس بلس يجب ان يعرف عندما يواجه دالة في الدالة الرئيسية يجب ان يكون قد واجه اسم تلك الدالة قبل ان يتفاجئ بها ..

والمكان الاخر لبرمجة الدالة يكون قبل الدالة الرئيسية وهنا لا نحتاج الى تعريفها بل مباشرة اعطاءها النوع والبارمترات ((ويجب هنا تسمية البارمترات )) ثم القيام ببناء جسم الدالة ..

تعودتوا في طريقة شرحي على اخذ امثلة واقعيه وها انا الان اعطيكم مثال واقعي وهو الاتي ..

لو ذهب اي شخص منا لزيارة شخص اخر اليس من المفروض ان ناخذ موعد سابق منه .. ؟؟؟

لو ذهبت الى احد اصدقائي يجب ان ابلغه مسبقا بانني قادم اليه لكي ينتظرني او يمكن انه يتعذر مني لاسباب شخصية لديه كانشغاله بعمل ما او لديه ضيوف اخرين .. وكذلك لكي لا يتفاجئ بي عند قدومي من دون موعد فقد يسبب الاحراج له ولي ..

هذا هو الحاصل في مصرف السي ... يجب ان تعطي اسم ونوع الدالة وعدد بارمتراتها قبل ان تقوم بالدخول الى الدالة main لكي لا يتفاجئ بها وتظهر لك رسالة خطأ عند القيام بعملية التصريف والخطأ هو استدعاء دالة غير معروفة ..

هذا ما قصدته من الموعد في المثال ..

الان دخلنا الى الدالة main .. اولا قمنا بتعريف متغيرين a و b وهما الخاصان بالاعداد المدخلة والمتغير result وهو الذي ستخزن به قيمة ناتج كل دالة ..

بالنسبة للمتغير الرمزي op هذا المتغير خاص بالعملية الحسابية التي نريد القيام بها على العددين .. وهذه معلومة يجب ان تعرفونها جيمعا ومن لم يعرفها سابقا سيعرفها الان وهي ان رموز العمليات الحسابية كالـ+ و - تعتبر من نوع char لانها ستوضع بين علامتا اقتباس مفردة ' + ' وكما هو معروف اي رمز يوضع بين علامتا اقتباس مفردة او مزدوجة يتحول الى القيمة المقابلة له في جدول الاسكي كود ...

بعدها قمنا باختبار المتغير op الذي سيدخله المستخدم .. باستخدام عبارة الاختبار switch

اولا .. اذا كان المدخل + سنتدعي الدالة sum التي هي خاصة بجمع عددين .. ثم نفوم بترجيع ناتج الجمع باستخدام عبارة return وكما قلت سابقا الفائدة من الreturn هو ان ناتج الجمع هذا سيذهب الى الدالة الرئيسية main وفي مثالنا هذا سيخزن في المتغير result ,, بعدها نقوم بطباعة المتغير result الذي هو خاص بناتج الجمع ..

ثانيا وثالثا نفس اولا باستثناء المدخل فاذا كان * او - سنستدعي الدالة الخاصة بالعملية المطلوبة اي نفس ما جرى للجمع ..

ملاحظة مهمه جدا جدا ..

الان نحن اكملنا العمل في الدالة الرئيسية واقفلنا القوس .. ووصلنا الى برمجة الدوال .. واضن انني شرحت برمجة الدوال في الدرس السابق ولا توجد لديكم مشكلة فيها فكل شخص يستطيع برمجة برنامج يجمع او يطرح او يضرب عددين فقط يضعها في دالة يكمل لديه برمجة تلك الدالة .. اما الملاحظة فهي التالية ,,,,

عندما قمنا باستدعاء دالة من تلك الدوال ولتكن دالة الجمع مثلا ..

result = sum(a,B);

قمنا بوضع المتغيرين a و b داخل اقواس البارمترات .. ركزوا معي قليلا رجاءا لانها ملاحظة هامه وهي اساس استدعاء الدوال ..

هنا سيقوم مصرف لغة سي بنقل نسخة من الارقام التي ادخلها المستخدم عندما طلبنا منه ادخال الرقم الاول والثاني الى المتغيرين الموضوعين في برمجة تلك الدالة وهما x و y ..

مقلا لو ادخل المستخدم الرقم 5 على انه الرقم الاول فسيخزن في المتغير a وعند استدعاء الدالة سيتم نسخ نسخه من هذا الرقم وارساله الى جزء برمجة الدالة بعد الدالة الرئيسيه لكي تتم معالجته في الدالة وسيخزن في المتغير x والسبب انه خزن في x وليس في y لان الx اول بارمتر في الدالة وكذللك a هو اول بارمتر فسيتم الارسال من اول بارمتر في الدالة المستدعاة الى اول بارمتر في جزء برمجة تلك الدالة ..

كذلك لو فرضنا ان المستخدم قام بادخال العدد 7 على انه العدد الثاني فسيخزن في المتغير b وستم نسخه وارساله الى المتغير y في جزء برمجة تلك الدالة وهذا ايضا يخضع لنفس القاعده التي قلتها قبل قليل وهي ان البارمتر الثاني في الدالة المستدعاة داخل الدالة الرئيسية main ينسخ ويرسل الى جزء برمجة الدوال ويوضع في المتغير y لكي تتم معالجته داخل الدالة ...

طبعا الى هنا سانهي هذا الدرس .. وإن شاء الله ارجو منكم اذا كان هناك اي شئ غير مفهوم ان تكتبوه لكي اشرحه واوضححه ...

والان ساكتب لكم مسائل ارجو حلها لكي اتاكد ان الشرح قد افاد الجميع ..

تحياتي العطرة ..

تم تعديل بواسطه MR.SD
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ملاحظة عن الدرس السابق ...

ممكن ان يكون المثال البرمجي المكتوب فيه يحتوي على اغلاط بسيطة وذلك لاني كتبته من ذاكرتي لاني حاليا لاملك مترجم لغة السي على الحاسبة التي اعمل عليها الان .. .لذلك ابلغوني اذا لم يعمل البرنامج لديكم ...

لكي اقوم بتصليحه ...

تحياتي ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

Thank you...

شكرا على الدرس .... وهو واضح و مفهوم و سأطبقه عمليا ...

و لكن أود التنبيه إلى انك نسيت عملية الDivision (القسمة)...

أتمنى ان تكتب لنا كود القسمة و هل تأخذ int type or float ؟

و لك جزيل الشكر على مجهودك....

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بك اخي العزيز Moon Land ....

طبعا بالنسبة لعملية القسمة كانت هي السؤال الذي كنت اود طرحه الان ولكن انت سبقتني ...

لذلك فهذا سؤال موجه اليك والى كل عضو قد قام بقراءة المجموعة الاولى من الدروس بالقيام ببرمجة برنامج يقوم بعملية القسمة وعملية النسبة المؤية وعملية التكعيب للعد وعملية ايجاد الباقي للقسمة العدد على عدد اخر ...وبالنسبه لنوع الدالة فهذا جزء من التفكير البرمجي الصحيح الذي يجب عليكم التفكير به ..

اتوقع انه ليس بالسؤال الصعب ..

لذلك انا انتظر من الجميع المشاركة وحل هذا السؤال باستخدام الدوال ..

تحياتي وارجو ان تكون الحلول مرتبه لكي استطيع قراءتها ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أعتقد أن كود القسمة على نمط برنامجك هو:

float dev(int,int);
int main()
{
int a,b,result;
char op;
cout<<"PLZ enter the first number:"<<endl;
cin>>a;
cout<<"PLZ enter the second number:"<<endl;
cin>>b;
cout<<"type/ for devision "<<endl;
switch(op)
{
case'/':
result=dev(a,b);
cout<<result;
break;
}}
float dev(int x,int y)
{
return x/y;
}

و أتمنى أن تكون محاولتي صحيحة و اذا و جدت فيها خطأ الرجاء منك التنبيه له و لك جزيل الشكر ....

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اخي العزيز moon land ..

محاولتك صحيحة ولكنك استخدمت الكوبي والبيست للبرنامج الذي كتبته انا في الدرس ...

والدليل ان عبارة الاختبار switch ليس لها اي داعي في دالتك ...

افهم قصدي ..

في البرنامج الذي كتبته انا كنت احتاج الى دالة الاختبار لان هناك اكثر من مدخل وكل مدخل تعتمد عليه دالة بينما في برنامجك هناك مدخل واحد فقط وهو الخاص بعملية القسمه .. لذلك ما الفائده من الاختبار ..؟؟؟

تحياتي والبرنامج صحيح وانا اريد منك شيئا وهو ان تطبقه على الكلام الذي قلته لك ..

لكي تستفيد اكثر ..

تحياتي العطره ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكرا لك ...أخي MR.SD

و لكنك لم تفهم قصدي .. أنا قصدت ببرنامجي أن أكمل به على برنامجك .. أي أن أضيف كود القسمة من النوع float إلى برنامج الآلة الحاسبة الذي كتبته أنت .. لذلك استخدمت ال switch لأن برنامج الحاسبة يتضمن أكثر من عملية (قسمة - ضرب - جمع - طرح) ... أتمنى انك فهمت قصدي ...

و لك فائق الشكر على اهتمامك و مجهودك ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ..

اهلا بك اخي moon land اعذرني فانا لم اعلم انك تحاول تكملة البرنامج وهو الحل كامل ...

تحياتي لك وبالتوفيق وإن شاء الله تستفيد من بقية الدروس ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بك اخي dr_abdalrhman

شكرا على تصليحك للخطأ .. ولكنني بالاصل لم اركز على الswitch بقدر ماكنت اركز على الدوال ..

وانا ايضا سبق وان ذكرت اذا كانت هناك مشكله بالبرنامج لانني لم اقم بعمل كومبايل له لانني الان لا امتلك مترجم اللغه ..

ولكن شكرا لك مرة اخرى لان البرنامج الان قد اكتمل بالفعل وعلمت بانه صحيح ...

تحياتي العطره للجميع ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

Thank you

و أنا بالفعل استفدت من دروسك الكثير و أريد منك المزيد...

تحياتي ....

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أولا : شكرا جزيلا على مجهودك

لكن اسمح لي ان اضيف تعقيب بسيط وخاصة للاخوة المبتدئين ,,

بعد سؤال المستخدم عن العملية التي يريدها , يوضع كود بسيط يستخدم للتأكد من أن الادخال الذي قام به الuser صحيح ,,, لكي لا نواجه مشاكل من هاذا النوع وايضا انصح بوضع if statment

 cin >> op;



if(!cin)

{

cout << " ERROR " <<

endl;

system("pause");

return main();

}







switch(op)

أول جملة (if(!cin

يسأل الكمبيوتر نفسه , اذا كان المدخل هو غير ال type تبع op أي اذا كان int or float وهكذا .

و return main هي لاعادة تشغل البرنامج

ويفضل وضع default:

وبعدها

;cout << " wrong, choose" << Endl

تحياتي ..

طارق عودة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جميل جدا يا اخ طارق هذه الاضافة وهي مفيدة للبرامج عدة ...

تحياتي وإن شاء الله في القريب ساكمل الدروس وستكون انتقاله الى المواضيع الاعقد قليلا في الدوال ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مشكووووووووور يعطيك الف عافيه ياربي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الله يجزااك الف خير ياسنان :clapping:

وانتظر بقية الدروس في الدوال (الاعقد :rolleyes: )

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اخي الكريم

بارك الله بيك على هذا الشرح المميز

ورحم الله والديك

انا ادرس علوم حاسبات مرحلة ثانية

واستفدت جدا من شرحك الجميل

عندي سؤال طرحه علينا الاستاذ بصراحة صارلي اسبوع دايخ بالفكرة

اذا امكن تساعدني بأن تعطيني رأس الخيط وانا اكمل

مارأيك؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الشكر الجزيل لكم

تابعتكم واستفدت من الشروحات : )

وأسألك الإكثار من البرامج البسيطة القصيرة التي تناقش الموضوع المحدود

مثلاً: الإرجاع... برنامجين صغيرين جداً جداً،

أحدهما فيه return والآخر لا

البرامج التي وضعتها مفهومة بحمد الله تعالى

ولكن كلما كان البرنامج قصيراً ومختصاً بمسألة واحدة كان أفضل -برأيي- للتركيز

مثلاً بدون إرجاع ولا تمرير:

#include <iostream.h>
#include <conio.h>

void m();

void main ()
{
m();

getch ();
}

void m()
{
int x=5;
cout << x;
}

مع إرجاع وبدون تمرير:

#include <iostream.h>
#include <conio.h>

int m();

void main ()
{
cout << m();

getch ();
}

int m()
{
int x=5;
return x;
}

مع تمرير معاملات، وبدون إرجاع:

#include <iostream.h> 
#include <conio.h>

int m(int, char);

void main ()
{
int c=2;
char d= 'S';
m(c,d);

getch ();
}

int m(int a, char b)
{
cout << a << b;
}

تمرير وإرجاع:

#include <iostream.h>
#include <conio.h>

char m(int, char);

void main ()
{
int c=2;
char d= 'S';
cout << m(c,d);

getch ();
}

char m(int a, char b)
{
if (a>0)
return b;
}

تم تعديل بواسطه م. صفاء جعيدي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .