أساسيات سي بلس بلس
سنبدأ اليوم سلسلة دروس عن لغة
سي بلس بلس إنها لغة صعبة ولكنها قوية جدا أريدك أن تعرف معلومة هامة كلمة كانت لغة
البرمجة صعبة كلما كانت قوية وإذا كنت تتعلم لغة الآن وأحسست بسهولتها فيجب أن تعلم
أنها لغة ليست قوية هذا رأيي الخاص واظنه شئ صحيح أحب أن تعرف معلومة أخرى أن لغة
سي بلس بلس ليست هي لغة سي مع التشابه الكبير لأوامر ودوال اللغتين المهم معنا الآن
أننا نتعامل مع لغة سي بلس بلس وأضيف شئ أخير انك إذا لم تفهم هذه الدروس فمعنى ذلك
أنني أخفقت في الشرح والتوضيح وتأكد حينها أن العيب عندي
أنا وليس عندك ولكي نبدأ دروسنا يجب عمل الآتي.
متطلبات العمل
1- كومبايلر للغة ودعني أقول لك ما هو الكومبايلر حتى وان كنت تعرفه انه البرنامج الذي يحول البرنامج الذي تكتبه إلى برنامج تنفيذي قابل للتشغيل والتوزيع والبيع إلى آخر ذلك وهناك أنواع كثيرة مثل:
Borland C++
Microsoft Visual C++
Watcom C/386
DJGPP.
أنا انصح بالكومبايلر الأول أو
الثاني أما الثالث والرابع فلم أجربهم ولست في حاجة إليهم ولست اقصد بذلك ألا
تستعملهم ولكن فقط لم أجربهم
استعد أنت الآن لبداية التعلم
لكي نبدأ فورا
عند
تعلم لغة كومبيوتر جديدة أصبحت عادة أن تقوم بطبع رسالة هالو ورلد:
Hello World
بالطبع هم يخاطبون العالم ولهم الحق في ذلك ولكن أنا سوف اطبع رسالة هالو أراب:
Hello Arab
// This is the 1st lesson
#include <iostream.h>
int main()
{
cout<<"HEY, Hello Arabs";
return 0;
}
دعونا نشرح ما كتبنا لقد بدأت
بالعبارة الآتية
// This is the 1st lesson
عند كتابة // معناها أنني اكتب
ملاحظات وبالتالي كل ما يليها لا يهم الكومبايلر عند الترجمة وفائدة الملاحظات
عظيمة فكلما كتبت جزء من البرنامج وضحت هاتين العلامتين وبعدها ما تريد أن تقوله
لنفسك أو لمن يراجعون بعدك ماذا تفعل فإذا عدت لتعديل البرنامج بعد فترة من الزمن
سيكون ذلك رائع أن تتذكر أفكارك في البرنامج موضع التعديل والآن إلى التعليمة
التالية لقد كتبنا
#include <iostream.h>
العلامة # يليها أمر
include
هي من تعليمات المعالج المبدئي
Preprocessor directive
لاحظ أن أوامر
اللغة تكتب بالحروف الإنجليزية الصغيرة
يلي ذلك مابين القوسين <> اسم
ملف ينتهي بالامتداد h
هذا النوع من الملفات يسمى
header files
وهي ملفات تأتي مع كومبايلر
اللغة وان كنت ستتعلم في مرحلة متقدمة من هذه الدروس عملية إنشاء ملفاتك الخاصة وهي
عبارة عن ملفات يوجد بها تعريف لأوامر اللغة المستخدمة داخل برنامجك وبالتالي لكل
مجموعة أوامر ملفاتها الخاصة لا تقلق سوف تعرف كل ذلك قريبا
إذا الأوامر المستخدمة في
مثالنا السابق يحتاج الملف iostream.h
وهذا الملف هام جدا ورئيسي
دائما ضم هذا الملف باستخدام الأمر
#include <iostream.h>
ملخص
|
#include |
من أوامر
لغة سي ++ (المعالج المبدئي) |
|
iostream.h |
ملف أو
هدير فايل لتعريف الأوامر المستخدمة |
|
<> |
أقواس لوضع
الملف المطلوب ضمه أو تحميله بينهما |
ببساطة شديدة الأمر cout الذي
سيلي شرحة يحتاج الملف
iostream.h
ننتقل الآن لشرح التعليمة
التالية
int main()
ومعناها الإعلان عن الدالة أو
جسم البرنامج الرئيسي الذي من خلاله نستدعي كل شئ ونعمل كل شئ وسوف نضع بداخله
الأوامر كلها
ولكن ما هو الأمر
int
انه من أوامر الإعلان عن نوع
المتغيرات ودعني أوضح ذلك
|
أمر اللغة
الذي يعلن عن المتغير |
نوع
المتغير |
|
int |
الإعلان عن
إعداد صحيحة |
|
float |
الإعلان عن
إعداد عشرية |
|
char |
الإعلان عن
حروف |
|
void |
لاشئ
|
وسوف نتعرض للأنواع الأخرى
فيما بعد وكمثال
int
x = 5;
int y = 65;
float z = 4.677777;
float q = 77.5443;
char *b = “Mohamad Hasan”;
char *c =
"My Home Page”;
لقد أعلنا أن الدالة الرئيسية
للبرنامج نوعها أو ستعيد في نهاية عملياتها عدد صحيح فقد تحتاج مثلا لعمل دالة لضرب
عددين في بعضهما والنتيجة تعيدها الدالة حسب نوع الإعلان
ويحدد ذلك الأمر return وكما
ترى أعاد الأمر القيمة صفر وهو بالطبع عدد صحيح نتيجة الإعلان عن دالة تعيد إعداد
صحيحة
فمثلا لو أنشأنا دالة لإعادة
إعداد عشرية يجب إن تعيد في نهايتها إعداد عشرية مثلا
float
NewFunc ()
{
float x , y , z;
x = 10.5;
y = 11.67887;
z = x * y;
return z;
}
لقد أعادت الدالة حاصل ضرب
10.5 * 11.67887 وحاصل الضرب هو عدد عشري لان نوع الدالة إعداد عشرية وهكذا دعنا
نعود لبرنامجنا الأصلي
|
int |
نوع الدالة
تعيد إعداد صحيحة |
|
main |
اسم الدالة
الرئيسية أساسي وهام |
|
() |
قوسين
مغلقين لا يوجد داخلهم شئ في هذه المرحلة |
إلى التعليمة التالية القوس
{
يجب أن يفتح به الدالة وتنتهي
به أيضا لاحظ الاتجاه إلى اليسار في بداية الدالة والى اليمين في نهايتها لتحديد
بلوك الأوامر
والآن إلى التعليمة التالية
cout<<"HEY, Hello ِArabs";
الأمر cout يليه القوسين <<
مفتوحين إلى اليمين معناها إخراج ما بين علامتي الاقتباس
|
Cout << |
أمر طباعة
على الشاشة |
|
"
" |
علامات
اقتباس لطبع الرسالة التي بينهما كما هي |
إلى الأمر الأخير
return 0;
وقد شرحناه أثناء تناولنا
لموضوع أنواع البيانات أخيرا ينتهي البلوك الرئيسي للبرنامج بإعادة قيمة صفر وهو
العدد الصحيح حسب الإعلان مع الدالة الرئيسية بالأمر int
وتتفق معي انه لا يجب أن يكون
صفر دائما ولكن كيفما تريد وحسب العمليات ولكن المهم أن يكون عدد صحيح 1 أو 2 أو
غيرها لأننا أعلنا عن ذلك وعلينا الالتزام به والا سوف يعطي الكومبايلر رسالة خطأ
انه قوس نهاية البلوك ولاحظ
انه إلى اليسار ليغلق البلوك الذي فتح بمثله ولكن إلى اتجاه اليمين والآن انتهى
برنامجنا الافتتاحي والى ملاحظاتنا
تذكر أن
1-
أوامر اللغة تكتب بحروف صغيرة
small letters
2-
البرنامج يبدأ بأوامر المعالج المبدئي لضم الملفات
# include
3-
الدالة الرئيسية main يجب أن تكون موجودة
4-
يفتتح البرنامج بالقوس} ويغلق بالقوس{
5-
الملف الذي أنشأته سيقوم برنامج التحرير بحفظه باسم ينتهي بالامتداد
cpp
6-
جميع سطور البرنامج وبعد نهاية الأوامر والإعلانات نضع الفاصلة المنقوطة
;
بعد أقواس
افتتاح البرنامج وبعد أوامر المعالج المبدئي وبعد اسم الدالة حاليا أقول لك نضعها
فقط بعد الأوامر داخل بلوك الدالة ومعناها نهاية الأمر اهتم بذلك
ماذا لو أعلنا عن
نوع الدالة الرئيسية بالأمر void ومعناه غير مطلوب منها إعادة شئ سيكون الأمر
return بدون قيم بالطبع أو كما يلي
// This a modification no. 1
#include <iostream.h>
void main()
{
cout<<"HEY, Hello
ِArabs";
return ;
}
لاحظ الأمر return لم يوضع
بعده قيم
وتذكر أن ما يلي // هي عبارة
عن ملاحظات لسطر واحد فقط وكلما وضعت سطر ملاحظات ضع هاتين العلامتين في بداية
السطر
// This is a remark no. 1
// And this is the remark no. 2
// It is no. 3
وهناك اسلوب اخر لكتابة الملاحظات في عدة سطور بأن تبدء بالعلامة /*
ثم تكتب ما شئت من ملاحظات في اي عدد من السطور ثم
تنهيها بالعلامة */
مع ملاحظة الاتجاهات وتكون الملاحظات السابقة بالاسلوب الذي شرحناه كما يلي
/*
This is a remark no. 1
And this is the remark no. 2
It is no. 3
*/
لاحظ الفرق لكي يتضح لك الشرح
استخدم ايهما أو ما تراه أسهل لك منهم اقصد من الأسلوبين السابقين
أوامر الاشتراطات
كما تحدثنا عن اللغات بصفة
عامة وقلنا أن الاشتراطات من الأمور الهامة في أي لغة والآن لا نريد أن نعيد ما
قلناه سابقا لندخل مباشرة في موضوع اليوم
المعنى البسيط والقريب لموضوع
اليوم انك تريد من برنامجك أن يفعل أشياء معينه عند تحقق شروط معينه ولكن كيف نصيغ
هذه الأوامر هذا هو موضوع اليوم
انك ترى الشروط دائما وربما
بدون أن تدري فأول شئ فعلته اليوم عند اتصالك بالانترنت هو إدخال كلمة السر – أليس
كذلك – نعم هو كذلك ولا شئ غيره – إن برنامج الاتصال قد وضع شرط صحة كلمة السر لكي
يمكنك من الدخول وربما أشياء أخرى مثل عدم انتهاء مدة الاشتراك وصحة اسم المستخدم
وهكذا كلها شروط أنها أيضا موضوعنا هذا اليوم ومعظم الشروط المستخدمة لقيمتين هي هل
هما متساويتان أم احدهما اكبر أو اصغر بالإضافة إلى المعاملات البولينية
Boolean operators
ومن درس منكم علم الجبر سوف
يتذكرها بسرعة أم من نسى أو لم يدرسها أصلا فالموضوع بسيط جدا لأنك تمارسه في حياتك
اليومية ربما دون أن تدري وهي
AND , OR , NOT
كمثال من الحياة اليومية
Ask Mohamad AND Ali
يجب أن تسأل محمد وعلى وليس
واحد منهم فقط بل يجب أن يكون السؤال للاثنين
Ask Mohamad OR ALI
أي يجب أن تسأل محمد أو على
يكفي فقط واحد منهم
Ask Mohamad NOT Ali
أي يجب أن تسأل محمد وليس على
فلو سألت على فان الشرط غير متحقق
الجدول التالي يعبر عن طريقة صياغة المعاملات البولينية في لغة سي++
|
التعبير أو الصيغة |
التفسير |
|
|| |
OR
|
|
&& |
AND |
والجدول التالي يعبر عن
العلاقات الشرطية وكيف تصاغ في لغة سي++
|
التعبير أو الصيغة |
التفسير |
|
> |
اكبر
من فتحة القوس في اتجاه الأكبر |
|
< |
اصغر
من |
|
== |
يساوي (تذكر أنهم علامتين متجاورتين |
|
>= |
اكبر
من أو يساوي |
|
<= |
اصغر
من أو يساوي |
|
!= |
لا
يساوي |
تذكر جيدا خطأ
من السهل أن تقع فيه أن الشروط غير التخصيص بمعنى انك عندما تخصص قيمة لمتغير فانك
لابد أن تستخدم علامة يساوي واحدة فقط مثل
A=5;
B=A;
C=18;
أما في صياغة
شرط فانك لابد أن تضع علامتين إذا اشترطت التساوي مثل
if (A==B)
if (A==18)
أرجو أن تنتبه
لذلك
ولنأخذ مثال اليوم فقد تأخرنا
كثيرا
// This is a remark do you remember
?
// It has no
effection , just for you , is it?
#include <iostream.h>
int main()
{
int Num;
cout<<"Please input a Number
: ";
cin>>Num;
if(Num < 50)
{
cout<<"The Number is less than 50";
}
if(Num == 50)
{
cout<<"The Number is equal to 50";
}
if(Num > 50)
{
cout<<"The
Number is bigger than 50";
}
return 0;
}
لقد بدأت السطور الحمراء بالأمر
cin<<Num;
هذا الأمر جديد علينا أن معناه ادخل قيمة المتغير
Num والذي أعلن عنه في بداية البرنامج على انه عدد صحيح
فسوف يتوقف البرنامج عند هذا الأمر ليطلب منك إدخال قيمة يخزنها في المتغير
Num ليجري عليها العمليات التي تلي السطر المذكور سابقا
والآن إلى الأوامر التالية موضع شرحنا اليوم
if(Num < 50)
{
cout<<"The Number is less than 50";
}
والقاعدة هي
الأمر if
ويفتح قوسين عاديين بينهما شروط حسب القاعدة السابق شرحها في
أول الموضوع ثم قوس لبداية بلوك تعليمات واحد لفتح بداية بلوك والأخر للتحديد نهاية
بلوك وما بداخل القوسين عدة تعليمات ينفذها البرنامج إذا تحقق الشرط
وهنا الشرط هو انك إذا أدخلت
قيمة اصغر من 50 فمعنى ذلك تحقق الشرط وعليه سوف يطبع البرنامج الرسالة
cout<<"The Number is less than 50";
وإذا لم يتحقق الشرط فلن يطبع
الرسالة ألسابقه بل سيتحول إلى السطور التالية
if(Num == 50)
{
cout<<"The Number is equal to 50";
}
بنفس الأسلوب السابق يختبر
الأمر if ماذا كان الرقم الذي ادخله المستخدم يساوي 50
فإذا كان ذلك صحيحا فسوف يقوم بتنفيذ الأمر أو الأوامر التي بداخل بلوك الشروط وهي
cout<<"The Number is equal to 50";
فاءذا لم يتحقق الشرط فسوف لن
ينفذ البرنامج ما بداخل بلوك الشروط وينتقل إلى السطور التالية
if(Num > 50)
{
cout<<"The
Number is bigger than 50";
}
فإذا تحقق الشرط هو أن العدد
المدخل اكبر من خمسون فسوف ينفذ البرنامج الأمر أو الأوامر التي بداخل بلوك الشرط
وهو الأمر
cout<<"The
Number is bigger than 50";
والا فسوف ينتقل البرنامج إلى
السطور التالية
return 0;
}
حيث ينتهي البرنامج ويخرج
وتذكر قوس إغلاق البلوك وهو البلوك الرئيسي للدالة main
البرنامج السابق هو برنامج
بسيط يقوم باستقبال رقم منك ليتعرف عليه ما إذا كان هذا الرقم اصغر من أو يساوي أو
اكبر من 50 وفي كل حالة حسب ما تدخل من أرقام سوف يطبع لك الرسائل
·
الرقم اصغر من 50
·
الرقم يساوي 50
·
الرقم اكبر من 50
بالطبع سوف تحصل على إجابة
واحدة من الثلاثة حسب المدخلات
لنأخذ عدة أوامر شرطية في صورة
فردية للشرح لدمج كل ما سبق شرحة في دالة واحدة
if (A == 5 && B == 7)
{
نفذ هذه الأوامر
عند تحقق الشرط
}
الشرط هو أن تكون قيمة المتغير
A تساوي خمسة وقيمة المتغير B
تساوي 7 لتنفيذ
ما بداخل بلوك الشروط فاءذا كانت مدخلاتك كما يلي
|
A |
B |
مدى
تحقق الشرط |
|
3 |
2 |
لا
يتحقق الشرط |
|
5 |
3 |
لا
يتحقق الشرط |
|
3 |
7 |
لا
يتحقق الشرط |
|
5 |
7 |
يتحقق الشرط |
|
7 |
5 |
لا
يتحقق الشرط |
|
1 |
2 |
لا
يتحقق الشرط |
ولمثال آخر بلوك الشروط
التالية
if (A > 5 || B <= 7)
{
نفذ هذه
الأوامر عند تحقق الشرط
}
وقد كان الشرط السابق أن تكون
قيمة A اكبر من 5 أو قيمة
B اصغر من أو تساوي
7 فلو كانت ادخالاتك كما يلي
|
A |
B |
مدى
تحقق الشرط |
|
3 |
2 |
لا
يتحقق الشرط |
|
5 |
3 |
لا
يتحقق الشرط |
|
3 |
7 |
لا
يتحقق الشرط |
|
7 |
2 |
يتحقق الشرط |
|
10 |
8 |
لا
يتحقق الشرط |
|
10 |
7 |
يتحقق الشرط |
دائما يكون إمامك حالة من
اثنين مهما كانت الشروط التي تضعها
·
الحالة الأولى تحقق الشرط أو بمعنى آخر
TRUE
·
الحالة البديلة عدم تحقق الشرط أو بمعنى
FALSE
إن ما بداخل أقواس الشروط ولا
اقصد بلوك الشروط هو عملية حسابية – دائما كل شئ بالنسبة للكومبيوتر هي عمليات
حسابية كل شي في الدنيا يمكن أن يعبر عنه بأرقام من اسمك إلى صورتك مرورا بخريطة
بلدك أو نوع الفاكهة التي تحبها – كل شئ نعم كل شئ هو عمليات حسابية – ربما نتطرق
إلى ذلك لاحقا – لا ادري قد يجبرنا احد الأمثلة على شرح ذلك – وناتج العملية
الشرطية بالنسبة للكومبيوتر هو إما TRUE لينفذ ما بداخل
بلوك الشروط أو FALSE لينفذ شروط أخرى داخل بلوك
else إذا كان موجودا أو يستكمل باقي سطور البرنامج كما حدث مع
المثال السابق هذا يقودنا إلى أمر آخر من أوامر الشروط وهو في لغة c++
ودائما يكون تابع للأمر if وهو
الأمر
else
أنت لا تحتاج الآن لان أقول لك
أن أوامر لغة سي في مجملها تكتب بحروف صغيرة ودعني أكمل شرح الأمر السابق انه أمر
غير مستقل انه تابع بالطبع أنت توافقني على ذلك انك لا يمكن أن تسمع شخص يقول والا
– إلا إذا كان قد ذكر أشياء قبلها إذا هذا الأمر تابع فإذا كنت تكره الأشخاص
التابعين من ذوي الشخصيات الضعيفة فأرجو ألا يمتد بغضك هذا إلى الأمر
else لأنه أمر هام ويسهل خطوات كثيرة
وان كان يسهل الاستغناء عنه ودعنا نعبر عن ذلك بعدة سطور
if(GiveMe >= 50)
{
cout<<"Thank you – I like to take more than or equal 50 Rayals";
}
else
{
cout<<"I am
very angry – I don’t like to take less than 50 Rayals";
}
جزء البرنامج السابق يعبر عن رد فعل احد الشحاذين
فإذا أعطيته مبلغ اكبر من أو يساوي 50 ريالا سوف يتحقق الشرط والنتيجة تكون
TRUE لينفذ ما بداخل بلوك الشروط لينفذ الأمر الخاص بطبع
رسالة شكر ليخبرك بأنه (الشحاذ ولست أنا بالطبع) يقول لك شكرا أنا دائما أحب إن
تعطيني مبلغ خمسون ريالا أو أكثر وإذا لم يتحقق الشرط أي أن نتيجة العملية الحسابية
FALSE كأن تكون قد أعطيته اقل من 50 ريالا فسوف ينتقل
التنفيذ مباشرا إلى البلوك التابع else لينفذ ما بداخل
بلوكة وهي هنا رسالة ضيق وتبرم بأنه لا يحب أن يأخذ اقل من خمسون ريالا حتى لو كانت
المبلغ يقل بهللة واحدة فقط عن الخمسون ريالا انها عمليات حسابية يا صديقي العزيز
وأنا انصح من يمتهنون هذه المهنة ببرمجة روبوت بجزء البرنامج السابق مع مزيد من
الشكر والأدعية في حالة تحقق الشرط وتبرم وضيق ولا أمانع من سيل من الشتائم في حالة
عدم تحقق الشرط . ياله من روبوت رائع وسوف يختزن بداخله مبالغ مالية كثيرة سواء
لخفة دمه في حالة تحقق الشرط أو لقلة أدبه في حالة عدم تحقق الشرط.
سوف تختتم هذا
الدرس بهذا الملخص الذي قد يقود إلى قاعدة هامة
if(FALSE)
{
Not executed
if its false
}
else
{
do all of
this
}
سندخل في الموضوع
مباشرة بدون لف أو دوران مع أن الموضوع يتعلق بالدوران والتكرار لقد تحدثنا عن فكرة
الحلقات التكرارية أو Loops في
المقال العام عن البرمجة إذا لم تكن قد قرأته من
فضلك راجعه الآن
طريقتين لعمل هذه
الحلقات الأسلوب الأول بلامر for والثاني بالأمر
while
لنأخذ جزئية
البرنامج التالي
#include <iostream.h>
int main()
{
int x;
for(x=0;x<100;x++)
{
cout<<x<<endl;
}
السطور ذات اللون
الأزرق تناولنا شرحها بالدرس الأول أما السطور
ذات اللون الأحمر فهي موضوع دراستنا اليوم
تقوم الحلقات
التكرارية بتنفيذ عدة أوامر موضوعة داخل بلوك ونقصد ببلوك مابين القوسين } مجموعة
اوامر{ إلى أن تنتهي الحلقات أو عدد الحلقات المحددة منك وعددها في مثالنا السابق
100 حلقة تكرارية وبدقة تبدأ الحلقات من رقم صفر إلى رقم 99 ومعنى ذلك أن العدد
الإجمالي 100 حلقة بعد حساب الصفر من ضمن الأرقام انتبه لذلك وتذكر أن المتغير x
يجب الإعلان عنه قبل استخدامه وذلك حسب نوع استخدامك له وهنا استخدمنا نوعه كعدد
صحيح بالطبع يمكنك استخدامه كعدد عشري واليك صيغة الأمر بالتفصيل
|
الصيغة |
التفسير |
|
for |
أمر
اللغة لعملية التكرار |
|
( |
قوس مفتوح يوضح بداخله
بارامترات الأمر |
|
x=0; |
المتغير = رقم بداية
الحلقات |
|
x<100; |
شرط نهاية الحلقات
|
|
x++ |
المتغير يزيد بمقدار واحد
مع بداية كل حلقة – لا تضع بعده فاصلة منقوطة |
|
) |
قوس نهاية
بارامترات الأمر
– لا تضع بعده فاصلة منقوطة |
|
{ |
قوس بداية بلوك الأوامر
المطلوب تكرارها |
|
بداخل
أقواس البلوك توضع الأوامر المطلوب تكرارها |
|
|
} |
قوس نهاية بلوك الأوامر
المطلوب تكرارها |
بداخل بلوك
الأوامر تم تنفيذ الأمر
cout<<x<<endl
وهو أمر يقوم
بطبع قيمة x التي تتغير في كل
مرة ابتداء من صفر حسب ما ذكرت أن
X=0 وتزيد في كل
مرة بمقدار 1 حسبما ذكرت أن x++ وذلك
حتى يصل إلى 99 حسبما ذكرت أن x<100
وendl
تعني end of line
أي انتقل إلى سطر جديد كلما طبعت قيمة حتى لا يسرد طبع الأرقام
متجاورة بل يطبع على كل سطر قيمة المتغير وبالتالي ستكون مخرجات البرنامج كما يلي
0
1
2
3
4
.
.
.
99
لنستفيد أكثر من
قوة الحلقات التكرارية وأيضا نرى امكانات أخرى لها بوضع حلقة داخل حلقة كما يلي
في البرنامج الذي يطبع جدول الضرب من جدول واحد حتى
جدول 12
#include <iostream.h>
int main()
{
int x , y , z;
for(x=1;x<13;x++)
{
for(y=1;y<13;y++)
{
z
= x * y;
cout<<x<<”*”<<y<<”=”<<z<<endl;
}
}
return 0;
}
كما تعلم أن
السطور الزرقاء سبق دراستها ولكن ننوه فقط أننا أعلنا عن ثلاث متغيرات لأعداد صحيحة
الأول للحلقة الأولى والثاني للحلقة الثانية والثالث لاحتواء حاصل الضرب وهو الهدف
من البرنامج.
بنفس ما سبق شرحه
وضعنا حلقة تكرارية تبدأ من رقم واحد وتنتهي برقم 12 وتزيد بمقدار واحد وأوامر هذه
الحلقة مكتوبة للتوضيح بخلفية صفراء حيث بدأت الحلقة بالصيغة السابق شرحها ثم قوس
بداية البلوك وقوس نهاية البلوك حيث يوضع مابين القوسين سلسلة أوامر لتنفيذها كما
سبق واتفقنا عليه
for(x=1;x<13;x++)
{
أوامر
مطلوب تنفيذها
}
وبداخل أقواس
البلوك للحلقة الأولى مطلوب وضع أوامر للتنفيذ فكانت أوامر التنفيذ داخل البلوك
عبارة عن حلقة أخرى وما المانع فالحلقات وغيرها هي نفسها أوامر والحلقة الأخرى كانت
عبارة عن عداد يعد من الرقم 1 إلى الرقم 12 وهي أيضا تحتاج إلى صيغة معينة وأقواس
بلوك للتنفيذ وهي موضوعة في البرنامج بخلفية خضراء كما يلي
for(y=1;y<13;y++)
{
z
= x * y;
cout<<x<<"*"<<y<<"="<<z<<endl;
}
وبداخل بلوك
الأوامر للحلقة الثانية وضعنا عدة أوامر لتفي بالغرض الذي من اجله تم عمل البرنامج
وهو جدول الضرب – عبارة عن معادلة لحساب حاصل ضرب المتغيرين x
و y
ويوضع الناتج في
المتغير z كما يلي
z =
x * y;
بالطبع تلي
ذلك صيغة لطبع مخرجات البرنامج والا ما الفائدة منه إذا لم أرى نتيجة عملي وهذه
الصيغة سأشرح لك فيما بعد وفي هذا الدرس لماذا اخترت هذه الصيغة بالتحديد فهو ليس
موضوعنا الآن ودعني اشرح لك الأهم من ذلك وهو ميكانيكية عمل الحلقتين
·
يبدأ البرنامج بالدخول إلى الحلقة الأولى ويخصص للمتغير اكس
القيمة واحد حيث أنها قيمة عداد البداية ثم يدخل إلى داخل أقواس بلوكه لتنفيذ ما
بداخله فيجد حلقه أخرى فيبدأ بتنفيذها وطلبت الحلقة أن يكون متغيرها وأي يبدأ
بالقيمة واحد وينتهي بالقيمة 12 ثم تدخل الحلقة الثانية إلى بلوك أوامرها فتجد
معادلة يضرب فيها قيمة اكس التي هي واحد الآن وتتغير قيمة وأي فيها ثم طبع النتائج
وتظل الحلقة الداخلية تنفذ بتغير وأي مع ثبات اكس بالطبع وتكون النتائج كما يلي
1 * 1
= 1
1 * 2
= 2
1 * 3
= 3
.
.
.
1 * 12
= 12
وعند وصول نهاية
عداد الحلقة الداخلية إلى 12 وهو نهاية الحلقة ينتهي تنفيذ الحلقة فيستمر البرنامج
فيجد أمامه قوس نهاية الحلقة الخارجية ذو الخلفية الصفراء فيعود إلى الحلقة
الخارجية حيث تزيد قيمة اكس بمقدار واحد وتصبح قيمتها = 2 فيدخل إلى بلوك أوامره
كما سبق فيجد حلقة أخرى تبدأ من واحد وتنتهي ب 12 وبداخلها معادلة وأمر طبع فيكون
التنفيذ كما يلي
2 * 1
= 2
2 * 2
= 4
2 * 3
= 6
.
.
.
2 * 12
= 24
وهكذا يستمر
التنفيذ إلى أن تصل الحلقة الخارجية إلى نهايتها بالرقم 12 وأثناء ذلك تنفذ الحلقة
الداخلية من بدايتها إلى نهايتها أي من 1 إلى 12 وتطبق المعادلة وأمر الطبع ليكون
آخر تنفيذ كما يلي
12 * 1
= 12
12 * 2
= 24
12 * 3
= 36
.
.
.
12 * 12
= 144
شرح صياغة أمر
الطبع بالصورة التالية
cout<<x<<"*"<<y<<"="<<z<<endl;
ما بداخل علامات
الاقتباس دائما يطبع كما هو وهو مميز أعلاه بالخلفية
الخضراء وكل ما يوضع داخل علامة الاقتباس يطبع نصه كما هو إما ما هو خارج علامات
الاقتباس بين أزواج الأقواس >>متغير>>
فيطبع قيمة المتغير وليس اسم المتغير فمثلا x لا تطبع x ولكن تطبع قيمتها فمثلا 1
– 2 – 3 ----- 12 حيث أنها متغيرات وتميز أعلاه بالخلفية الصفراء
وذلك للحصول على شكل مقبول يوضح العملية المطلوبة لتظهر النتائج بالصورة
12 *
12 =
144
والآن إلى
النوع الثاني من الحلقات وهو ابسط من السابق ولكن السابق أكثر استخداما وأكثر قوة
While
#include <iostream.h>
int main()
{
int x=0;
while(x<100)
{
cout<<x<<endl;
x++;
}
return 0;
}
سوف اشرحها لك في
سطور قليلة لبساطتها الأوامر باللون الأزرق سبق شرحها أما الحلقة موضع النقاش فهي
باللون الأحمر وصيغتها
while(x<100)
وبعد الإعلان عن
المتغير اكس خلاصة شرح الأمر السابق (أعد تنفيذ ما بداخل البلوك طالما اكس أو
المتغير اقل من 100 ثم أقواس بلوك تضع ما شئت بداخله من أوامر وقوس نهاية البلوك
ويزيد معنا فقط عداد للمتغير ليزيد ه بالمقدار الذي تريده ويوضع في أي مكان داخل
الحلقة أو حسب أفكارك عن البرنامج المهم لا تنساه والا سوف يدور البرنامج داخل
الحلقة إلى الأبد حيث أن شرط نهايتها ان تزيد اكس عن 100 وطالما لم تضع عداد زياده
للمتغير فلن يتحقق الشرط وبالتالى لن تنتهي الحلقه الى الابد ويظل يعمل الكومبيوتر
بلا نهاية للبرنامج
ويميز العداد
بالخلفية الصفراء
واليك جدول صياغة الامر الذي
تعودنا عليه.
|
الصيغة |
التفسير |
|
while |
امر
اللغة لعملية التكرار |
|
( |
قوس مفتوح يوضح بداخله
بارامترات الامر |
|
X<100 |
المتغير مع شرط لنهاية
الحلقة |
|
) |
قوس نهاية
بارامترات الامر
– لاتضع بعده فاصلة منقوطة |
|
{ |
قوس بداية بلوك الاوامر
المطلوب تكرارها |
|
بداخل اقواس البلوك توضع
الاوامر المطلوب تكرارها |
|
|
x++; |
ولا
تنسى عداد الزياده او النقصان ليتحقق الشرط لانهاء تنفيذ الحلقة |
|
} |
قوس نهاية بلوك الاوامر
المطلوب تكرارها |
لقد ذكرت لك كلمة
عداد الزيادة او النقصان نعم يمكن ان يتناقص العداد اذا كانت صيغة البرنامج كما يلي
وذلك لطبع قيمة المتغير تناقصيا من 99 الى صفر بعد ان كان في البرنامج السابق
تصاعديا من صفر الى 99 ويكون التعديل كما يلي
#include <iostream.h>
int main()
{
int x=99;
while(x>0)
{
cout<<x<<endl;
x--;
}
return 0;
}
بدء هنا
تخصيص المتغير مع الاعلان بالقيمة 99 ثم شرط التكرار ان يكون متى كانت قيمة المتغير
اكبر من الصفر ثم عداد تناقصي يظل يطرح واحد من القيمة الى ان يصل الى الصفر ثم
يطرح من الصفر 1 فتصبح قيمته –1 وبالتالي لايتحقق الشرط حيث ان قيمة –1 ليست اكبر
من الصفر وتنتهي الحلقه كما نريد لاحظ
العداد التناقصي بالخلفية الصفراء
الدوال Functions
موضوع اليوم عن
الدوال او الروتينات الفرعية وهي اجزاء من البرنامج مثل الدالة الرئيسية تقوم بعمل
مهمة معينة تتكرر في برنامجك او تستخدمها في برامج اخرى او حتى اذا كانت لا تتكرر
من فوائدها
·
تقسيم البرنامج الى اجزاء صغيرة تستدعى وقت اللزوم
·
عدم ازدحام الدالة الرئيسية للبرنامج بأوامر كثيرة
·
تقسيم البرنامج الى اجزاء يمكن اختبارها منفصلة لسرعة تحديد الخلل بالبرنامج
·
توفير المجهود والوقت والتفكير بعمل مكتبة خاصة بك تعيد استخدام الدوال التي
استخدمتها في برنامج وذلك في برنامج آخر عند اللزوم
·
تقسيم العمل بين المبرمجين عن العمل في مشروع جماعي لانتاج برنامج كبير
·
تبادل الخبرات بين مطوري البرامج بنشر اجزاء يستخدمها الآخرون في برامجهم
لتطبيق ذلك دعنا
نحضر البرنامج الذي تناولناه في الدرس الثالث
لاعطائه مزيدا من القوة والتطوير باستخدام الدوال
#include <iostream.h>
int main()
{
int x , y , z;
for(x=1;x<13;x++)
{
for(y=1;y<13;y++)
{
z
= x * y;
cout<<x<<”*”<<y<<”=”<<z<<endl;
}
}
return 0;
}
لوكنت قد تذكرت الآن فان البرنامج
كان يقوم بعمل جدول الضرب من جدول واحد الى جدول 12 واحتوى كامل التعليمات داخل
الدالة الرئيسية دعنا نستخدم الدوال ولنسمي هذه الدالة DoiT
#include <iostream.h>
void DoiT (void);
int main()
{
DoiT ();
}
// This is the new function
void DoiT (void)
{
int x , y , z;
for(x=1;x<13;x++)
{
for(y=1;y<13;y++)
{
z
= x * y;
cout<<x<<”*”<<y<<”=”<<z<<endl;
}
}
return ;
}
مايخص الدالة الجديدة مكتوب باللون الاحمر فقبل
الدالة الرئيسة main تم الاعلان عن نموذج الدالة او ما يسمى
prototype بهذا الشكل
void DoiT (void);
وفيه نخبر
الكومبايلر بشكل وما ستكون عليه الدالة كما يلي
|
الصيغة |
التفسير |
|
void |
ماهي
القيمة التي سوف تعيدها الدالة للدالة التي استدعيت منها وذلك بالامر
return
هنا استخدمنا
void
بمعنى لاشئ وبالتالي علينا استبدال
return 0
التي استخدمناها في الدرس الثالث الى
الامر return
فقط حيث اننا اعلنا ان الدالة غير
مطلوب منها اعادة شئ |
|
DoiT |
اسم تختاره لدالتك بحيث
يكون معبرا قليلا عما ستفعل انا هنا لم اختر اسم معبر
|
|
( |
قوس
لاحتواء البارامترات التي ستمرر للدالة |
|
void |
البارامترات التي ستمرر للدالة وهنا اخترنا
void
بمعنى لن نمرر لها شئ |
|
); |
قوس
اغلاق لمجموعة البارامترات يليها فاصلة منقوطة |
والآن الى باقي
سطور البرنامج لاستكمال الشرح
int main()
{
DoiT ();
}
كما سبق ولابد ان
نعلن عن الدالة الرئيسية للبرنامج وهو الزام ثم داخل بلوك الدالة الرئيسية قمنا
بالنداء على الدالة للتنفيذ وذلك بكتابة اسمها ثم قوسين لايوجد بينهما شئ هل تتذكر
لماذا لان البارامترات المطلوب تمريرها للدالة لم تعطى اي void
ولكن بالطبع لاتكتب void ولكن يكون
ذلك في الاعلان عن الدالة فقط وهو على الصورة التالية
DoiT();
تلى ذلك قوس
نهاية البلوك للدالة الرئيسة ثم جسم او هيكل الدالة نفسها ويبدء بنفس الاعلان عن
اسم الدالة او البروتوتايب ولكن بدون فاصلة منقوطة في النهاية وكما تلاحظ وسبق ان
قلنا ان الفاصلة المنقوطة لاتأتي بعد main() وبنفس
الطريقة لاتأتي في مقدمة بلوك الدالة
void DoiT (void)
{
ضع اوامر الدالة
هنا
}
ثم قوس بداية
بلوك الدالة ثم مابداخلها من اوامر وقوس النهاية ودعنا ننتهز فرصة الدوال
لاعطاءمزيد من التحسينات على البرنامج حيث ان البرنامج ينتج فقط جدول الضرب من جدول
1 الى جدول 12 فلماذا لانجعلها دالة عامة تنتج مايحلو لنا من جداول ضرب من المؤكد
انك تتفق معي في ذلك وبذلك نستفيد من قوة الدوال وتصبح دالة عامة غير موجهه لمهمة
ثابته فنحن نريد ان نحدد نحن بداية الجداول ونهايتها فتارة تطبع من جدول 7 الى جدول
20 وتارة تطبع من جدول 17 الى 40 وهكذا اليس هذا افضل سوف نمرر للدالة قيمة البداية
وقيمة النهاية مع اجراء التعديلات اللازمة لذلك.
#include <iostream.h>
void DoiT (int
Start , int End);
int main()
{
int Start , End;
cout<<"Please input start value ?: ";
cin>>Start;
cout<<"Please input end value ?: ";
cin>>End;
DoiT (Start
, End);
}
// This is the new function
void DoiT (int
Start , int End)
{
int x , y , z;
for(x=Start;x<End+1;x++)
{
for(y=Start;y<End+1;y++)
{
z
= x * y;
cout<<x<<”*”<<y<<”=”<<z<<endl;
}
}
return ;
}
لتسهيل الامر
عليك وضعت لك لون اصفر على التعديلات التي اجريتها للوصول الى الهدف المنشود لقد
وضعنا في اقواس البروتوتايب اعلان عن تمرير متغيرين صحيحين الى الدالة
void DoiT
(int Start , int End);
ثم داخل الدالة
الرئيسية اعلنا عن استخدام متغيرين جديدين من نوع الاعداد الصحيحة هما
int Start , End;
تلى ذلك امر بطبع
رسالة تطلب منك ادخال قيمة بداية الجدول وبعده امر بعملية الادخال نفسها ليعرف
البرنامج القيمة المبدئية لبداية الجدول
cout<<"Please input start value ?: ";
cin>>Start;
مثلهما تماما
للمتغير الثاني ليعرف البرنامج قيمة النهاية والتي كانت ثابتة سابقا على القيمة 12
ونحن نريد برنامج اكثر مرونة ومطوع لكل الحالات
cout<<"Please input end value ?: ";
cin>>End;
بعد ان ادخلت
قيمة البداية والنهاية فكما ذكرنا تم تعديل الدالة لتمرير متغيرين لها يتغيران مع
كل ادخال والآن لننادي الدالة ممرين لها القيمتين الذين ادخلهما مستخدم البرنامج
DoiT (Start
, End);
ثم اجرينا
تعديل على اسم الدالة نفسها ليوافق البروتوتايب او اعلان الدالة الجديد في مقدمة
البرنامج طبعا بدون فاصلة منقوطة
// This is the new function
void DoiT (int
Start , int End)
{
ثم تلى ذلك وضع
القيمة Start الممررة للدالة
كبداية عداد للحلقتين بدلا من القيمة 1 وكذلك المتغير End
الممرر الى الدالة كنهاية لعداد الحلقتين بدلا من
القيمة 13 في مثال الدرس الماضي
ويجب دائما ان
تفكر في احتمالات خطأ مدخل البيانات فمثلا ماذا لو أخطأ وادخل قيمة البداية اكبر من
قيمة النهاية بالطبع سيحدث خطأ بالبرنامج وسيحدث نفس الخطأ اذا ادخلهم كقيمتين
متساويتين وعليه يجب وضع شرط لذلك كما سيلي توضيحه كتحسين للبرنامج
#include <iostream.h>
void DoiT (int
Start , int End);
int main()
{
int Start , End;
A1:
cout<<"Please input start value ?: ";
cin>>Start;
cout<<"Please input end value ?: ";
cin>>End;
if (Start >= End) goto A1;
DoiT (Start
, End);
}
لقد وضعت
الاضافة الجديدة بخلفية حمراء للتوضيح وهي عبارة عن عنوان اختياري قبل عملية
الادخال ثم بعد الادخال شرط انه اذا كانت قيمة البداية اكبر من اوتساوي قيمة
النهاية فعليك بالذهاب الى العنوان المحدد A1
اي اعادة الادخال ولامانع من اضافة رسالة تحذير لتوضيح فيما اخطأ مدخل البيانات
الى مثالنا الاخير وهو دالة تعيد قيمة ويممر اليها بيانات
#include <iostream.h>
float Mul (float A , float
B);
int main()
{
float A , B , R;
cout<<"Please input A ?: ";
cin>>A;
cout<<"Please input end B ?: ";
cin>>B;
R = Mul (A , B);
cout<<R;
}
float Mul (float A , float B)
{
return A*B;
}
الدالة الجديدة
اسميناها Mul وتعيد هذه الدالة
قيمة عشرية وهي حاصل ضرب قيمتين عشريتين تم تمريرها اليها وكما ترى المثال بسيط
ومعظم اجزائه سبق شرحها
حالات
التبديل وأوامر القفز
قد تحتاج في برنامجك إلى قائمة
(أو حالة تشابه ذلك) تطلب من المستخدم إدخال رقم الاختيار أو الضغط على زر معين
لإنجاز مهمة ومما سبق دراسته يمكن وضع عدة شروط لتنفيذ دالة معينة حسب الاختيار
ولكننا سنعرض اليوم أمر يقوم بتسهيل مثل هذه العمليات ولندخل في الموضوع مباشرة
#include <iostream.h>
#include
<conio.h>
void Input (void);
void Display (void);
void Modify (void
int main()
{
char input;
StartMenu;
cout<<"1. Enter Data";
cout<<"2. Display Data";
cout<<"3. Modify Data";
cout<<"4. Exit";
cin>>input;
switch (input)
{
case
1:
Input();
break;
case
2:
Display();
break;
case
3: Modify();
break;
case
4:
return 0;
break;
default:
cout<<"Error,
bad input, quitting";
goto StartMenu;
}
return 0;
}
void Input (void)
{
//This the input function
;
;
;
}
void Display (void)
{
//This the display function
;
;
;
}
void Modify (void)
{
//This the modify function
;
;
;
}
الأوامر ذات اللون الأزرق سبق
شرحها أما الأوامر والتعليمات ذات الخلفية الصفراء فهي موضوعنا اليوم – بدء
البرنامج بأمر من أوامر المعالج المبدئي وذلك بضم الملف
<conio.h> وهو لازم للأمر
switch موضع دراستنا اليوم
تلي ذلك تعريف لمتغير
input
ثم
رسائل طبع على الشاشة تخبر مستخدم البرنامج بقائمة البرنامج والأزرار التي ينبغي أن
يضغطها لتحقيق عنصر القائمة الموجود ثم يتوقف ليطلب إدخال قيمة الاختيار ما بين
الأرقام من 1 إلى 4 ولندخل الآن إلى الأمر
switch (input)
{
}
وتتضح صيغته كما تعودنا من
الجدول التالي
|
الصيغة |
التفسير |
|
switch |
هو
الأمر الذي ندرسه الآن ومعناه اختبار ما بداخل القوسين
|
|
( |
قوس مفتوح لاحتواء متغير |
|
input |
متغير
سبق الإعلان عنه وادخل من المستخدم أو تم حسابه حسب فكرة البرنامج |
|
) |
إغلاق
القوس الذي يحتوي المتغير المطلوب اختباره |
|
{ |
قوس
بداية البلوك |
|
هنا
توضع الأوامر بالصيغة التي سيلي شرحها |
|
|
} |
قوس
نهاية البلوك – لا تنساه من فضلك |
وبداخل بلوك الأمر
switch توضع الأوامر بالصيغة التالية
|
الصيغة |
التفسير |
|
case |
الأمر
التابع للأمر الرئيسي switch |
|
1 |
حالة
الإدخال المطلوب دراستها كأن يكون الإدخال 1 أو 2 وهكذا أو حسب نوع المدخل
وفكرة البرنامج |
|
: |
نقطتين
تلي قيمة المتغير للتنفيذ في حالة تطابقها مع الإدخال أو الحسابات |
|
ضع هنا
ما يحلو لك من معادلات أو استدعاء لدالة أو أوامر حسب فكرة البرنامج وقد وضعت
أنا استدعاء لدالة
|
|
|
break; |
انتهاء
الأوامر ليعرف نهاية الحالة |
تكرر
الأوامر السابقة لجميع الحالات المطلوب اختيارها حتى نصل إلى جزئية هامة وهي ماذا
يجب على البرنامج أن ينفذ إذا كان الإدخال لا يتطابق مع كل الحالات السابقة
فالبرنامج طلب إدخال أي رقم من 1 إلى 4 فماذا لو ادخل المستخدم غير ذلك لابد أن
يكون للبرنامج قرار في هذه الحالة وعليك إضافة الحالة الخاصة التالية قبل قوس إغلاق
بلوك switch
بالصيغة التالية
|
الصيغة |
التفسير |
|
default |
الأمر
التابع للأمر الرئيسي switch
للحالة الخاصة بعدم تطابق
الإدخال مع الحالات التي سبق دراستها |
|
: |
نقطتين
تلي الأمر السابق |
|
ضع هنا
ما يحلو لك من معادلات أو استدعاء لدالة أو أوامر حسب فكرة البرنامج وقد وضعت
أنا أمر بطبع رسالة خطأ وأمر آخر بالقفز لبداية البرنامج لإعادة العملية لان
الإدخال خطأ
|
|
|
break; |
انتهاء
الأوامر ليعرف نهاية الحالة وهو اختياري هنا لعدم وجود أوامر بعده بل يوجد
قوس نهاية البلوك switch |
ملاحظة هامة:
لم نتعرض لأمر القفز goto في درس منفصل لبساطته ولكن سنشرحه هنا بسرعة هذا الأمر
عبارة عن الأمر نفسه يليه عنوان لايهم أين يكون هذا العنوان ولكن كل مايهم عدم
تكرار نفس العنوان بنفس الاسم في نفس الدالة ولامانع من تكرار أو استخدام نفس الاسم
ولكن في دوال أخرى حيث تعمل الدوال بصفة منفصلة وأنا اخترت العنوان StartMenu
يليه
نقطتين
ولامانع أن تختار ما يحلو لك من أسماء شرط عدم تكرارها كما سبق وذكرنا وهذه هي صيغة
كتابة الأمر
|
الصيغة |
التفسير |
|
goto |
أمر
القفز المطلوب دراسته |
|
StartMenu |
العنوان
الذي اخترته |
|
; |
الفاصلة
المنقوطة التي تلي جميع الأوامر |
|
StartMenu: |
العنوان ويليه نتطين لتعريف البرنامج بأنه عنوان وهو اختياري ولايهم أين يوضع
بل يوضع في أي
مكان حسب فكرة البرنامج والمهم أن يكون ضمن نفس الدالة |
ملاحظة أخرى
لو لاحظت أنني وضعت العنوان
StartMenu قبل بداية أوامر طبع القائمة ليعاد طبعها وإدخال المتغيرات متى كان
الإدخال خطأ وبتوجيه من الأمر goto ولكني وضعته بعد الأمر
char input;
لأنه إعلان ولا يهم البرنامج إعادة الإعلان بل قد
يعترض الكومبايلر نفسه إذا فعلت ذلك