الدليل السريع c++

Page 1


C++ 3


‫فهرس انمحتىٌاث‬ ‫مقدمة إلى البرمجة‬ ‫البداٌة مع البرمجة‬ ‫لغة البرمجة‬ ‫لمحة تارٌخٌّة عن ‪C++‬‬ ‫لمن هذا الكتاب ؟‬ ‫كٌف أقرأ هذا الكتاب ؟‬ ‫فصول الكتاب‬ ‫التعامل مع المترجم ‪visual c++ 6.0‬‬

‫القسم األول‬

‫الفصل األول‪ :‬بنٌة البرنامج فً لغة الـ ‪C++‬‬

‫‪9‬‬ ‫‪10‬‬ ‫‪10‬‬ ‫‪11‬‬ ‫‪11‬‬ ‫‪11‬‬ ‫‪23‬‬ ‫‪14‬‬ ‫‪17‬‬

‫تنسٌق الكتابة‬

‫‪18‬‬

‫التعلٌقات‬

‫‪19‬‬

‫تمارٌن‬

‫‪19‬‬

‫الفصل الثانً‪ :‬المتغ ٌّرات ( ‪( Variables‬‬

‫‪20‬‬

‫حساسٌة اللغة لحالة األحرف‬

‫‪21‬‬

‫أنواع البٌانات )‪(Data types‬‬

‫‪21‬‬

‫مقدّمة إلى السبلسل ) ‪( strings‬‬

‫‪24‬‬

‫تمارٌن‬

‫‪25‬‬

‫الفصل الثالث‪ :‬اإلدخال و اإلخراج ) ‪( Input and Output‬‬

‫‪26‬‬

‫تعلٌمة اإلخراج )‪(cout‬‬

‫‪26‬‬

‫تعلٌمة اإلدخال )‪(input cin‬‬

‫‪28‬‬

‫بعض الرموز الخاصة‬

‫‪28‬‬

‫تمارٌن‬

‫‪29‬‬

‫الفصل الرابع‪ :‬الثوابت (‪)Constants‬‬

‫‪30‬‬

‫الفصل الخامس‪ :‬المعامالت )‪(Operators‬‬

‫‪31‬‬

‫اإلسناد )=(‬

‫‪31‬‬

‫المعامبلت الرٌاضٌّة ) ‪( + , - , * , / , %‬‬

‫‪31‬‬

‫معامبلت اإلسناد المركبة ) =| ‪( += , -= , *= , /= , %= , &= , ^= ,‬‬

‫‪32‬‬

‫معامبلت الزٌادة والنقصان )‪(++ , --‬‬

‫‪32‬‬

‫معامبلت المقارنة ) => ‪( == , != , < , > , <= ,‬‬

‫‪32‬‬

‫المعامبلت المنطق ٌّة ) || ‪( ! , && ,‬‬

‫‪33‬‬

‫المعامل الشرطً ) ؟ (‬

‫‪33‬‬

‫معامل تحوٌل البٌانات‬

‫‪34‬‬

‫‪4‬‬


‫المعامل )(‪sizeof‬‬

‫‪34‬‬

‫أولوٌات تنفٌذ المعامبلت‬

‫‪34‬‬

‫تمارٌن‬

‫‪36‬‬

‫الفصل السادس‪ :‬بنى التحكم (‪)Control Structures‬‬

‫‪37‬‬

‫بنٌة الشرط ‪condition structure‬‬

‫‪37‬‬

‫بنى التكرار ‪loops or repetition structures‬‬

‫‪39‬‬

‫التعلٌمة ‪break‬‬

‫‪42‬‬

‫التعلٌمة ‪continue‬‬

‫‪42‬‬

‫التعلٌمة ‪goto‬‬

‫‪43‬‬

‫التعلٌمة ‪switch‬‬

‫‪43‬‬

‫الحلقات المتداخلة ‪nested loops‬‬

‫‪46‬‬

‫تمارٌن محلولة‬

‫‪48‬‬

‫تمارٌن‬

‫‪56‬‬

‫الفصل السابع‪ :‬التوابع (‪)Functions‬‬

‫‪58‬‬

‫التوابع التً ال تعٌد قٌمة ) استخدام الكلمة ‪( void‬‬

‫‪60‬‬

‫تمر ٌر الوسطاء بالقٌمة وبالمرجع )العنوان(‬

‫‪61‬‬

‫المدى ‪Scope‬‬

‫‪63‬‬

‫المتغٌرات الشاملة ‪ Global variables‬و المتغٌرات الموضعٌة ‪Local variables‬‬

‫‪63‬‬

‫المتغٌرات الثابتة ‪static‬‬

‫‪64‬‬

‫تعٌ​ٌن القٌمة االفتراضٌة للوسطاء‬

‫‪64‬‬

‫إعادة تحمٌل التوابع ‪functions overloading‬‬

‫‪65‬‬

‫التعرٌف المبدبً للتوابع ‪functions prototype‬‬

‫‪65‬‬

‫الفصل الثامن‪ :‬التعاودٌة (‪)Recursion‬‬

‫‪67‬‬

‫تمارٌن محلولة‬

‫‪72‬‬

‫تمارٌن‬

‫‪86‬‬

‫القسم الثانً‬

‫الفصل التاسع‪ :‬المصفوفات (‪)Arrays‬‬

‫‪78‬‬

‫التعامل مع المصفوفات‬

‫‪79‬‬

‫المصفوفات المتعددة األبعاد‬

‫‪80‬‬

‫المصفوفات كمعامبلت )وسطاء( للتوابع‬

‫‪82‬‬

‫األعداد العشوابٌة‬

‫‪83‬‬

‫تمارٌن محلولة‬

‫‪85‬‬

‫تمارٌن‬

‫‪90‬‬ ‫‪5‬‬


‫الفصل العاشر‪ :‬سالسل الرموز (‪)Strings of Characters‬‬ ‫التعامل مع السبلسل‬ ‫الفصل الحادي عشر‪ :‬المؤشرات (‪)pointers‬‬

‫‪92‬‬ ‫‪92‬‬ ‫‪95‬‬

‫معامل العنوان ) & (‬

‫‪95‬‬

‫معامل المرجع ) * (‬

‫‪95‬‬

‫التصرٌح عن المإ ّ‬ ‫شرات‬

‫‪:7‬‬

‫المإ ّ‬ ‫شرات والمصفوفات‬

‫‪:8‬‬

‫تبدبة المإ ّ‬ ‫شرات‬

‫‪:9‬‬

‫مصفوفة المإ ّ‬ ‫شرات‬

‫‪:9‬‬

‫العملٌات الحسابٌة على المإ ّ‬ ‫شرات‬

‫‪99‬‬

‫شرات على المإ ّ‬ ‫المإ ّ‬ ‫شرات‬

‫‪100‬‬

‫المإ ّ‬ ‫شرات الخالٌة ‪void pointers‬‬

‫‪100‬‬

‫المإ ّ‬ ‫شرات على التوابع‬

‫‪101‬‬

‫الفصل الثانً عشر‪ :‬الذاكرة الدٌنامٌكٌة (‪)Dynamic Memory‬‬

‫‪103‬‬

‫المعامل ‪new‬‬

‫‪103‬‬

‫المعامل ‪delete‬‬

‫‪104‬‬

‫الفصل الثالث عشر‪ :‬التراكٌب (‪)Structures‬‬

‫‪105‬‬

‫تراكٌب المعطٌات‬

‫‪105‬‬

‫مصفوفة التراكٌب‬

‫‪107‬‬

‫التراكٌب و المإ ّ‬ ‫شرات‬

‫‪108‬‬

‫التراكٌب المتداخلة‬

‫‪109‬‬

‫الفصل الرابع عشر‪ :‬األنواع المعرفة من قبل المستخدم‬

‫‪113‬‬

‫تعرٌف أنواع خاصّة ) ‪( typedef‬‬

‫‪113‬‬

‫الوحدات ) ‪( Unions‬‬

‫‪113‬‬

‫المر ّقمات ) ‪Enumerations ( enum‬‬

‫‪114‬‬

‫الفصل الخامس عشر‪ :‬اإلدخال و اإلخراج فً الملفات‬

‫‪114‬‬

‫فتح ملف‬

‫‪115‬‬

‫إغبلق ملف‬

‫‪116‬‬

‫الملفات النصٌّة‬

‫‪116‬‬

‫التحقق من الحالة‬

‫‪117‬‬

‫مإ ّ‬ ‫شرا التدفق ) ‪ put‬و ‪( get‬‬

‫‪117‬‬

‫الفصل السادس عشر‪ :‬معالجة االستثناءات ( ‪) Exceptions handling‬‬

‫‪119‬‬ ‫‪6‬‬


‫القسم الثالث‬

‫التوجه (‪)OOP‬‬ ‫الفصل السابع عشر‪ :‬البرمجة كائن ٌّة‬ ‫ّ‬

‫‪122‬‬

‫مقدّمة‬

‫‪122‬‬

‫معرّ فات الوصول ‪Access modifieres‬‬

‫‪123‬‬

‫معامل المدى ‪::‬‬

‫‪125‬‬

‫التوابع األعضاء ‪inline‬‬

‫‪125‬‬

‫المشٌّدات ‪Constructors‬‬

‫‪128‬‬

‫الهادمات ‪Destructors‬‬

‫‪129‬‬

‫إعادة تحمٌل المشٌّدات ‪Overloading Constructors‬‬

‫‪129‬‬

‫المإ ّ‬ ‫شرات على الصفوف ‪Pointers to classes‬‬

‫‪132‬‬

‫الكلمة المفتاحٌّة ‪this‬‬

‫‪133‬‬

‫الصفوف المعرّ فة باستخدام الكلمة المحجوزة ‪struct‬‬

‫‪135‬‬

‫إعادة تحمٌل المعامبلت ‪Overloading operators‬‬

‫‪135‬‬

‫األعضاء الثابتة من النوع ‪static‬‬

‫‪138‬‬

‫التوجه (‪)OOP principles‬‬ ‫الفصل الثامن عشر‪ :‬مبادئ البرمجة كائن ٌّة‬ ‫ّ‬

‫‪140‬‬

‫مبدأ التغلٌف ‪Encapsulation‬‬

‫‪140‬‬

‫التوابع ‪ friend‬الكلمة المفتاحٌّة ) ‪( friend‬‬

‫‪142‬‬

‫الصفوف من النوع ‪friend‬‬

‫‪143‬‬

‫الوراثة بٌن الصفوف ‪Inheritance between classes‬‬

‫‪144‬‬

‫الوراثة المتعددة ‪Multiple inheritance‬‬

‫‪147‬‬

‫تعدد األشكال ‪Polymorphism‬‬

‫‪148‬‬

‫المإ ّ‬ ‫شرات على الصفّ األساسً ‪Pointers to base class‬‬

‫‪148‬‬

‫األعضاء من النوع ‪virtual‬‬

‫‪149‬‬

‫الصفوف األساسٌّة المجردة ‪Abstract base classes‬‬

‫‪152‬‬

‫الفصل التاسع عشر‪ :‬القوالب (‪)Templates‬‬

‫‪155‬‬

‫تابع القوالب‬

‫‪155‬‬

‫صفّ القوالب‬

‫‪157‬‬

‫تخصٌص القالب ‪Template specialization‬‬

‫‪158‬‬

‫الفصل العشرون‪ :‬فضاءات األسماء (‪)Namespaces‬‬

‫‪061‬‬

‫التعلٌمة ‪using namespace‬‬

‫‪272‬‬

‫الفضاء ‪std‬‬

‫‪273‬‬

‫حلول التمارٌن غٌر المحلولة‬

‫‪061‬‬

‫‪7‬‬


‫املقدّمة‪:‬‬

‫الحمد هلل ربّ العالمٌن الرحمن الرحٌم مالك ٌوم الدٌن‪ ,‬والصبلة والسبلم على س ٌّد األوّ لٌن واآلخرٌن مح ّمد النبًّ‬ ‫األمٌن وعلى آله وصحبه ال ُغرِّ المٌامٌن ومن اهتدى بهدٌهم واستنَّ بسنتهم أجمعٌن‪.‬‬ ‫قال هللا تعالى‪" :1‬وقل ربِّ ِزدنً علما"‪ .‬قال ابنُ كثٌر فً تفسٌره‪" :‬أي‪ :‬زدنً منك علما"‪.‬‬ ‫قال ابن ُع ٌَ ٌْ َن َة رحمه هللا‪" :‬ولم ٌزل رسول هللا صلى هللا علٌه وسلم فً زٌادة ] من العلم [ ح ّتى تو ّفاه هللا ع ّز‬ ‫وج ّل"‪.‬‬ ‫وعن أبً هرٌرة ‪ ,‬رضً هللا عنه‪ ,‬أنّ رسول هللا‪ ,‬صلى هللا علٌه وسلم‪ ,‬قال‪" :‬ومن سلك طرٌقا ٌلتمس فٌه علما‪,‬‬ ‫س ّهل هللا له به طرٌقا إلى الجنة"‪.‬‬ ‫ٌ‬ ‫ملعونة‪ ,‬ملعونٌ ما فٌها‪ ,‬إال ذكر هللا تعالى‪ ,‬وما‬ ‫وعنه قال‪ :‬سمعت رسول هللا‪ ,‬صلى هللا علٌه وسلم‪ٌ ,‬قول‪" :‬الدنٌا‬ ‫‪2‬‬ ‫وااله‪ ,‬وعالما‪ ,‬أو متعلما"‪.‬‬ ‫وعن أنس‪ ,‬رضً هللا عنه قال‪ :‬قال رسول هللا‪ ,‬صلى هللا علٌه وسلم‪" :‬من خرج فً طلب العلم‪ ,‬فهو فً سبٌل‬ ‫‪3‬‬ ‫هللا ح ّتى ٌرجع"‪.‬‬ ‫خٌر‬ ‫وعن أبً سعٌ ٍد الخدري‪4 ,‬رضً هللا عنه‪ ,‬عن رسول هللا‪ ,‬صلى هللا علٌه وسلم‪ ,‬قال‪" :‬لن ٌشبع مإمنٌ من ٍ‬ ‫ح ّتى ٌكون منتهاه الجنة"‪.‬‬ ‫وعن أبً أمامة‪ ,‬رضً هللا عنه‪ ,‬أنّ رسول هللا‪ ,‬صلى هللا علٌه وسلم‪ ,‬قال‪" :‬فضل العالم على العابد كفضلً‬ ‫على أدناكم ث ّم قال رسول هللا‪ ,‬صلى هللا علٌه وسلم‪ :‬إن هللا ومبلبكته وأهل السموات واألرض حتى النملة فً‬ ‫‪5‬‬ ‫جحرها وحتى الحوت لٌصلون على معلمً الناس الخٌر"‪.‬‬ ‫علم فكتمه‪ ,‬ألجم ٌوم‬ ‫وعن أبً هرٌرة‪,‬‬ ‫رضً هللا عنه‪ ,‬قال‪ :‬قال رسول هللا صلى هللا علٌه وسلم‪" :‬من سبل عن ٍ‬ ‫‪6‬‬ ‫ار"‪.‬‬ ‫ن‬ ‫القٌامة‬ ‫بلجام من ٍ‬ ‫ٍ‬ ‫إنّ ما تق ّدم من اآلٌات واألحادٌث إ ّنما ٌ ّدل على فضل العلم و ّ‬ ‫صل األجر‬ ‫طبلبه فً الدنٌا واآلخرة ولكً ُتح ّ‬ ‫العظٌم من هللا تعالى علٌك أن تعلم أنّ ن ٌّتك فً طلب العلم مه ّمة فقد روى إماما المح ِّدثٌن البخاريّ ومسلم رضً‬ ‫حفص عمر بن الخطاب‬ ‫هللا عنهما فً صحٌحٌهما ‪-‬اللذٌن هما أص ّح الكتب المص ّنفة‪ -‬عن أمٌر المإمنٌن أبً‬ ‫ٍ‬ ‫ئ ما‬ ‫رضً هللا عنه‪ ,‬قال‪" :‬سمعت رسول هللا صلى هللا علٌه وسلم ٌقول‪ :‬إ ّنما األعمال بالن ٌّات‪ ,‬وإ ّنما لك ّل امر ٍ‬ ‫نوى فمن كانت هجرته إلى هللا ورسوله فهجرته إلى هللا ورسوله‪ ,‬ومن كانت هجرته لدنٌا ٌصٌبها‪ ,‬أو امرأ ٍة‬ ‫‪7‬‬ ‫ٌن ِك ُحها فهجرته إلى ما هاجر إلٌه"‪.‬‬ ‫إ ّنما ُجعِل هذا الكتابُ لٌكون مساعدا للذٌن ٌو ّدون تعلّم شًء من علوم البرمجة )برمجة الحاسب( وفً محاول ٍة‬ ‫ك أح ٌد بإهمٌته للبشرٌة جمعاء ولؤل ّمة اإلسبلم ٌّة على وجه‬ ‫لزٌادة الكتب العرب ٌّة التً تهت ّم بهذا العلم الذي ال ٌش ُّ‬ ‫ْ‬ ‫ُ‬ ‫ُ‬ ‫الخصوص تلك األمّة التً خاطبها هللا تعالى فقال‪ُ " :‬ك ْن ُت ْم َخٌ َْر أ َّم ٍة أ ْخ ِر َج ْ‬ ‫ُون ِب ْال َمعْ رُوفِ َو َت ْن َه ْو َن َع ِن‬ ‫اس َتؤ ُمر َ‬ ‫ت لِل َّن ِ‬ ‫‪8‬‬ ‫ان َخٌْرا لَ ُه ْم"‪.‬‬ ‫اهلل َولَ ْو آ َم َن أَهْ ُل ْال ِك َتا ِ‬ ‫ب لَ َك َ‬ ‫ون ِب َّ ِ‬ ‫ْال ُم ْن َك ِر َو ُت ْإ ِم ُن َ‬ ‫سابلٌن المولى ّ‬ ‫عز وج ّل أن تعود هذه األ ّمة إلى عهدها قابدة ورابدة فً كل المجاالت ومشكاة للنور ومنبعا للفكر‬ ‫العذب الصافً‪.‬‬ ‫تعفو عمّا كان من الخطؤ أو‬ ‫إنّ الذ ٌْ ِن كتبا هذا الكتاب هما من البشر لذلك نرجو منك أٌُّها القار ُ‬ ‫ئ الفاض ُل أن َ‬ ‫ُ‬ ‫ٌ‬ ‫النسٌان وأن تذكر أنّ الكمال هلل وحده‪ .‬أخٌرا هذا الكتاب لٌس مجانٌّا بالكامل وثمنه دعوة بالغٌب لنا وللمسلمٌن‬ ‫فبل تنسونا من دعابكم‪.‬‬ ‫‪ 1‬سورة طه اآلٌة ‪114 :‬‬ ‫ٌ‬ ‫‪ 2‬رواه الترمذي وقال‪ :‬حدٌث حسنٌ ‪ .‬قوله وما وااله أي‪ :‬طاعة هللا‪.‬‬ ‫ٌ‬ ‫حدٌث حسنٌ ‪.‬‬ ‫‪ 3‬رواه الترمذي وقال‪:‬‬ ‫ٌ‬ ‫حدٌث حسنٌ ‪.‬‬ ‫‪ 4‬رواه الترمذي وقال‪:‬‬ ‫ٌ‬ ‫‪ 5‬رواه الترمذي وقال‪ :‬حدٌث حسنٌ ‪.‬‬ ‫ٌ‬ ‫‪ 6‬رواه أبو داود والترمذي وقال‪ :‬حدٌث حسنٌ ‪.‬‬ ‫‪7‬‬ ‫ٌ‬ ‫متفق على صحته‪.‬‬ ‫‪ 8‬سورة آل عمران اآلٌة ‪221 :‬‬

‫‪8‬‬


‫إهداء‬ ‫محمد صلى اهلل عليو وسلم‪.‬‬ ‫األول ّ‬ ‫إلى المعلّم ّ‬ ‫عّا ‪.‬‬ ‫إلى والدينا األ ّ‬ ‫إلى أصحاب الفضل علينا من إخواننا ومعلّمينا الفضال ‪.‬‬ ‫كل المسلمين‪.‬‬ ‫إلى ّ‬ ‫إلى من كان السبب في إخراج ىذا الكتاب‬

‫المؤلفان‬ ‫السبت ‪ 81‬ذي القعدة سنة ‪ 8341‬هجريّة‬ ‫األول سنة ‪ 1188‬ميالديّة‬ ‫‪ 81‬تشرين ّ‬

‫‪9‬‬


‫مق ّدمة إلى البرمجة‬ ‫تحت ّل علوم الحاسب اإللكترونًّ فً أٌامنا هذه مكانة عالٌة بٌن العلوم وهً ترتبط بشكل وثٌق ج ّدا مع ك ّل العلوم‬ ‫األخرى بدء بالعلوم الرٌاض ٌّة والفٌزٌاب ٌّة مرورا بعلوم اللغات والعلوم الطب ٌّة وغٌرها‪.‬‬ ‫وم ّما هو معلوم عند الناس أنّ الحاسبات تإ ّدي العدٌد من الوظابف المه ّمة فً حٌاتنا الٌومٌة بسرعة وكفاءة‬ ‫عالٌتٌن وبدقة كبٌرة فً النتابج األمر الذي ساعد العلماء على اختراع الكثٌر من اإلبداعات العلمٌة بسرعة كبٌرة‬ ‫تفوق تصوّ رات الكثٌرٌن من البشر ابتداء باآلالت المٌكانٌكٌة كالسٌارات إلى عالم اإلنترنت الملًء بالمفاجآت‬ ‫وصوال إلى القمر حٌث استطاع البشر الوصول إلٌه بإذن هللا تعالى ث ّم بما أبدعته عقول العلماء وبمساعدة هذه‬ ‫الحاسبات‪.‬‬ ‫ّإال أنّ الحاسب ال ٌستطٌع أن ٌفعل أي شًء مالم ٌقم اإلنسان بتعلٌمه وتدرٌبه على القٌام به هذا األمر من خبلل‬ ‫صٌصا لٌرافقك عزٌزي القارئ فً رحلة‪-‬‬ ‫برمجة الحاسب على القٌام بما نرٌده أن ٌقوم به وهذا الكتاب ُ‬ ‫ص ِنع ِخ ّ‬ ‫نرجو من هللا أن تكون ممتعة بالنسبة لك– فً رحاب إحدى أه ّم وأقوى لغات البرمجة لتتم ّكن بعدها من قٌادة‬ ‫حاسبك وجعلِه ٌفعل كل األشٌاء التً ترٌدها منه‪.‬‬ ‫ٌشبه هذا األمر الطرٌقة التً ٌ ّتبعها الناس فً تربٌة وتعلٌم أبنابهم حٌث ٌُول ُو َنهم الحبّ والرحمة وٌحاولون‬ ‫جاهدٌن أن ٌجعلوا من أوالدهم أفضل ما ٌمكن‪ ,‬وما نرٌده منك فً هذه الرحلة أن تعزم على أن تقرأ هذا الكتاب‬ ‫فالصبر‬ ‫كامبل وأن تتحلى بالصبر قال هللا تعالى ‪" :‬واستعٌنوا بالصبر والصبلة وإ ّنها لكبٌرة إال على الخاشعٌن"‪,‬‬ ‫َ‬ ‫الصبر‪.‬‬ ‫قد ٌبدو األمر صعبا فً أوّ له ولك ّنه سٌسهل شٌبا فشٌبا مع تق ّدمك فً صفحات هذا الكتاب وتمرّ نك على ما فٌه‬ ‫من التمارٌن واألسبلة وال تكتفِ بذلك بل اكتب كل ما ٌخطر ببالك من برامج وإن لم تتم ّكن من ذلك بسهولة‪ ,‬و‬ ‫حاول أن تح ّل ك ّل المشاكل التً تواجهها باستخدام البرمجة لٌتث ّنى لك ما ترٌد ‪ ,‬وتذ ّكر دابما ما قاله أجدادنا‬ ‫الحكماء‪" :‬إهمال ساعة ٌفسد رٌاضة دهر" فإ ٌّاك واإلهمال وواصل العمل بج ّد فمن ج ّد وجد ومن سار على‬ ‫الدرب وصل‪ ,‬ولكً تكون على الدرب علٌك أوّ ال أن تعرف الدرب وهذا ال ٌكون ّإال بالتخطٌط وتحدٌد األهداف‬ ‫ث ّم األسباب ث ّم تضع الخطة وتبدأ بتنفٌذها وتذ ّكر هدفك دوما –الغاٌة األسما لكل مسلم إرضاء هللا عز وجل–‬ ‫واعمل له ك ّل ساعة‪.‬‬ ‫أخٌرا أقول لك‪ِ " :‬اعمل لدنٌاك كؤ ّنك تعٌش أبدا واعمل آلخرتك كؤ ّنك تموت غدا"‪.‬‬

‫‪:‬‬


‫البداٌة مع البرمجة‬ ‫نقصد بالبرمجة صناعة البرامج ولٌس شرطا أن تكون برامجا تعمل فقط على الحاسبات أو على اآلالت‬ ‫اإللكترونٌة‪ .‬البرامج هً مجموعة من التعابٌر المنطقٌّة والرٌاض ٌّة الخاصة المرتبطة مع بعضها لتكوّ ن حلوال‬ ‫لمشاكل معٌنة‪.‬‬ ‫ولكً نكتب برنامجا ما علٌنا أن نقوم بخطوات مح ّددة قبل ذلك وهذه الخطوات تبدأ أوّ ال بتحلٌل المشكلة المعطاة‬ ‫إلى مشاكل أبسط ث ّم نقوم بوضع خطوات الحل وذلك وفق ترتٌب مع ٌّن ٌبلبم التحلٌل الذي حصلنا علٌه وهذا‬ ‫الترتٌب لخطوات الحل ٌدعى بالخوارزمٌة‪ ,‬ث ّم كتابة البرنامج بلغة البرمجة‪.‬‬ ‫الخوارزمٌة‪ :‬هً خطوات منطق ٌّة مر ّتبة ترتٌبا صحٌحا لح ّل مشكلة مع ٌّنة‪.‬‬ ‫ال ب ّد فً كل برنامج من مرحلتً التحلٌل وكتابة الخوارزمٌة بعد ذلك ٌؤتً دور الحاسب‪ .‬حٌث ٌتبقّى أن تقوم‬ ‫بترجمة الخوارزمٌة التً صغتها إلى برنامج مكتوب بإحدى لغات البرمجة ث ّم ٌقوم الحاسب بعمله لٌعطٌك‬ ‫البرنامج الذي قمت بكتابه‪.‬‬ ‫مثبل ّ لنفترض أ ّننا نرٌد أن نقوم بحساب مساحة مستطٌل‪.‬‬ ‫ّأوالا‪ :‬لنحلّل هذه المشكلة‬ ‫ما هو المستطٌل و كٌف نحسب مساحته ؟ المسطٌل هو شكل هندسً له أربعة أضبلع اثنان منها ٌمثبلن الطول‬ ‫واالثنان اآلخران ٌمثبلن العرض أ ّما مساحته فهً تنتج من ضرب الطول بالعرض‪.‬‬ ‫الخوارزمٌة‪:‬‬ ‫‪ -1‬اقرأ الطول ث ّم العرض‬ ‫‪ -2‬اضرب الطول بالعرض‬ ‫‪ -3‬أعطنً الناتج‬ ‫هذه الخطوات ّ‬ ‫تمثل خوارزم ٌّة لحل مشكلتنا السابقة‪ .‬سنعتمد فً هذا الكتاب على كتابة الخوارزمٌات بنفس‬ ‫صصة فً هذا المجال أ ّما هذا الكتاب‬ ‫الطرٌقة السابقة‪ .‬ولن نكثر من الشرح حول الخوارزم ٌّات فهناك كتب متخ ّ‬ ‫فهو ٌناقش البرمجة وبعض البرامج وما ٌه ّمنا هو توضٌح الفكرة من الخوارزمٌات فقط ولن نحتاج إلٌها كثٌرا‬ ‫خبلل هذه الرحلة وٌمكنك التو ّسع فً ذلك المجال بقراءة بعض الكتب المختصة‪ .‬اآلن بعد أن قمنا بوضع‬ ‫الخوارزم ٌّة بقٌت المرحلة األخٌرة لكتابة البرنامج أال وهً ترجمتها إلى لغة برمجة ٌعرفها الحاسب‪.‬‬ ‫لغة البرمجة‬ ‫ٌواجه المبرمجون المشكلة ذاتها التً ٌواجهها المسافرون إلى بلدان أجنب ٌّة وهً مشكلة اختبلف لغة التخاطب‬ ‫بٌن المسافر والبلد الذي سافر إلٌه فكان من المناسب إٌجاد ح ّل لهذه المشكلة وهو الٌوم اتقان اللغة األكثر شهرة‬ ‫مثل اللغة اإلنكلٌز ٌّة مثبل فمعظم الناس ٌستطٌعون التح ّدث بهذه اللغة‪ ,‬وكذلك األمر عند المبرمجٌن ت ّم إٌجاد‬ ‫صة للتخاطب بٌن البشر)المبرمجٌن( والحاسب والتً تعرف بلغات البرمجة ‪programming‬‬ ‫لغات خا ّ‬ ‫‪ languages‬وهذه اللغات صنعت لهذا الغرض ولن نطٌل الكبلم حول هذا الموضوع فالكبلم فٌه طوٌل ولٌس‬ ‫له أهم ٌّة كبٌرة فً تعلّم البرمجة وتستطٌع عزٌزي القارئ الحصول على المعلومات الكاملة حول هذا الموضوع‬ ‫من خبلل اإلنترنت ففٌه الكثٌر م ّما ٌجب علٌك أن تتعلّمه أ ّما ما ٌه ّمنا هنا هو أنّ ما ٌكتب باستخدام لغة البرمجة‬ ‫ٌسمى شٌفرة‪.‬‬ ‫لكً ٌستطٌع الحاسب معرفة هذه اللغة ت ّم تصنٌع برامج أخرى س ّمٌت مترجمات ‪ compilers‬تقوم هذه‬ ‫المترجمات بترجمة الشٌفرة التً تكتب بلغة البرمجة إلى لغة أخرى هً لغة اآللة إذ أنّ الحاسب ٌمتلك لغة‬ ‫صة حٌث ّ‬ ‫ٌمثل كل البٌانات والمعلومات فٌه على شكل سبلسل من األرقام الثناب ٌّة )‪ 0‬و ‪ (1‬ما ٌجعل‬ ‫خا ّ‬ ‫التخاطب معه بلغته أمرا فً غاٌة الصعوبة والتعقٌد‪.‬‬

‫‪21‬‬


‫لمحة تارٌخ ٌّة عن ‪C++‬‬ ‫طوّ رت ‪ C++‬من لغة ‪ C‬التً طوّ رت بدورها من لغتٌن سابقتٌن هما ‪ BCPL‬و ‪. B‬‬ ‫قام مارتٌن رٌكارد ‪ Martin Richards‬عام ‪2:78‬م بتطوٌر ‪ BCPL‬كلغة لكتابة أنظمة التشغٌل والتطبٌقات و‬ ‫المترجمات‪.‬‬ ‫وأضاف كِن ثومبثون ‪ Ken Thompson‬العدٌد من المٌزات الجدٌدة إلى لغته ‪ B‬التً تشبه ‪ BCPL‬إلى ح ّد كبٌر‬ ‫واستخدمها فً إنتاج النسخ األولى من نظام التشغٌل ‪ Unix‬الشهٌر وذلك فً مختبرات ‪ Bell‬عام ‪2:81‬م‬ ‫باستخدام الحاسب المعروف بـ ‪ DEC DPD-7‬كلتا اللغتٌن كانتا عدٌمتً األنواع فً البداٌة‪.‬‬ ‫طوّ ر دٌنِس رٌتشً ‪ Dennis Retchie‬لغة ‪ C‬من لغة ‪ B‬فً مختبرات ‪ Bell‬باستخدام الحاسب ‪DEC DPD-‬‬ ‫‪ 11‬عام ‪2:83‬م‪.‬‬ ‫حٌث استخدمت ‪ C‬العدٌد من األفكار الموجودة فً اللغتٌن ‪ B‬و ‪ BCPL‬و أضافت إلٌهما أنواع البٌانات وبعض‬ ‫المٌزات األخرى‪.‬‬ ‫ومن هذه اللغة التً تل ّقت العدٌد من التعدٌبلت والتطوٌرات ح ّتى نالت درجة القٌاسٌة العالمٌة‬ ‫)‪ ISO(International Standards Organaizatoion‬ت ّم تطوٌر لغة ‪ C++‬فً مختبرات ‪ Bell‬من خبلل‬ ‫‪ Bjarne Stroustrup‬فً مطلع الث ّمانٌنات‪.‬‬ ‫زوّ دت ‪ C++‬بمجموعة من المزاٌا ّإال أنّ أه ّمها كان دعمها لمبادئ البرمجة كابن ٌّة التوجه ‪OOP(Object-‬‬ ‫)‪Oriented Programming‬‬ ‫لمن هذا الكتاب ؟‬ ‫هذا الكتاب لك ّل من ٌرٌد أن ٌتعلّم البرمجة وال ٌفترض هذا الكتاب وجود أيّ معرفة لدى القارئ لذلك لٌس مه ّما إن كانت‬ ‫هذه أوّ ل مرّ ة تقرأ فٌها كتابا فً هذا المجال أو إن كانت المرّ ة األولى التً تقرّ ر فٌها تعلّم البرمجة ‪ ,‬وكذلك لؤلشخاص‬ ‫الذٌن ٌو ّدون االنتقال من لغات أخرى إلى هذه اللغة ٌمكن أن ٌق ّدم هذا الكتاب المبادئ األساس ٌّة للبرمجة باستخدام لغة‬ ‫‪ C++‬ولكنّ هذا الكتاب ال ٌعطً لؤلشخاص المتق ّدمٌن فً البرمجة سوى مراجعة لبعض معلوماتهم السابقة وقد ٌضٌف‬ ‫بعض األفكار البسٌطة إن لم ٌكونوا قرإوها من قبل‪.‬‬ ‫كٌف أقرأ هذا الكتاب ؟‬ ‫إن كنت مبتدبا ولم ٌسبق لك أن كتبت برنامجا من قبل فعلٌك أن تبدأ من حٌث أنت أ ّما إن كان لدٌك تصوّ ر كا ٍ‬ ‫ف عن‬ ‫البرمجة بهذه اللغة فٌمكنك أن تختار الموضوع الذي تو ّد البدء منه فالكتاب مق ّسم إلى ثبلثة أقسام ربٌس ٌّة القسم األول و‬ ‫الذي ٌحتوي على المبادئ األساسٌة لكل المبتدبٌن فً البرمجة والقسم الثانً الذي ٌحتوي على مواضٌع أكثر تقدّما‬ ‫كالمصفوفات والذاكرة الدٌنامٌك ٌّة والمإ ّ‬ ‫شرات أ ّما القسم الثالث فقد ت ّم تخصٌصه للحدٌث عن البرمجة الكابن ٌّة التوجه وهً‬ ‫مرحلة متق ّدمة بعض الشًء لذلك إن لم تتقن الفصول التً تسبقها فستواجه العدٌد من المشاكل‪.‬‬

‫‪22‬‬


‫فصول الكتاب‬ ‫األول ‪ :‬بنٌة البرنامج فً لغة ‪C++‬‬ ‫الفصل ّ‬ ‫نتح ّدث فً هذا الفصل عن البنٌة األساس ٌّة للبرنامج وفق قواعد اللغة ونتناول أه ّم العناصر المش ّكلة للبرنامج ونشرح ك ّل‬ ‫واحدة منها من خبلل البرنامج األوّ ل لنا فً هذا الكتاب‪.‬‬

‫الفصل الثانً‪ :‬المتغ ٌّرات‬ ‫نطرح فً هذا الفصل فكرة المتغٌّرات التً تشبه خبلٌا الذاكرة فً دماغ اإلنسان فهً خبلٌا فً ذاكرة الحاسب‬ ‫ٌستخدمها الحاسب لتخزٌن القٌم التً ٌحتاجها أثناء تنفٌذ البرنامج وسنناقش كٌفٌة التعامل معها أٌضا‪.‬‬ ‫الفصل الثالث ‪ :‬اإلدخال و اإلخراج‬ ‫هذا الفصل هو بداٌتك لكً تكون قادرا على التواصل مع الحاسب بشكل مباشر حٌث ستتم ّكن من الطباعة على‬ ‫الشاشة و القراءة من لوحة المفاتٌح وهذا هو التخاطب الذي نبحث عنه بٌن المبرمج والحاسب‪.‬‬ ‫الفصل الرابع ‪ :‬الثوابت‬ ‫فً هذا الفصل سنشرح فكرة استخدام الثوابت و الفرق بٌنها و بٌن المتغٌّرات‪.‬‬ ‫الفصل الخامس ‪ :‬المعامالت‬ ‫صة تقوم بوظابف من‬ ‫نقصد بها الرموز التً تعنً للحاسب عمل ٌّات معٌّنة إما رٌاض ٌّة أو منطق ٌّة أو عمل ٌّات خا ّ‬ ‫أنواع أخرى والمعامبلت ضرور ٌّة ج ّدا وال ٌخلو برنامج منها أبدا لذلك ننصحك بالتم ّعن أثناء قراءتها و التمرّ ن‬ ‫علٌها بشكل ج ٌّد‪.‬‬ ‫الفصل السادس ‪ :‬بنى التحكم‬ ‫صة تقوم بوظابف معٌنة منها ما ٌدعى ببنى الشرط و منها ما‬ ‫نق ّدم هنا أه ّم البنى البرمج ٌّة وهً تعلٌمات خا ّ‬ ‫ٌدعى ببنى التكرار وهً أنواع نتع ّرف علٌها فً حٌنها ث ّم نشرح فٌه بعض الكلمات المستخدمة مع هذه البنى‬ ‫لمساعدتنا فً إدارة برامجنا بشكل كامل‪.‬‬ ‫الفصل السابع ‪ :‬التوابع‬ ‫تمثل التوابع البنٌة الربٌس ٌّة للبرنامج ولها فوابد أخرى حٌث تس ّهل التوابع كتابة البرامج وتق ّسم البرامج إلى أقسام ّ‬ ‫ّ‬ ‫منظمة‬ ‫واضحة للمبرمج ولقارئ الشٌفرة‪.‬‬

‫الفصل الثامن ‪ :‬التعاودٌة‬ ‫أسلوب خاصّ لكتابة التوابع ّ‬ ‫ٌتمثل بتكرار التابع عددا منتهٌا من المرّ ات دون استخدام بنى التكرار وهذا الفصل‬ ‫من أكثر الفصول صعوبة وفٌه من المتعة الشًء الكثٌر وتجدر اإلشارة إلى أنّ هذا الفصل غٌر مه ّم كثٌرا أل ّنه‬ ‫ٌستغنى عنه باستخدام البنى التكرارٌة‪.‬‬ ‫الفصل التاسع ‪ :‬المصفوفات‬ ‫بنى معطٌات تسهّل التعامل مع البٌانات التً لها نفس النوع كالبحث والترتٌب والتخزٌن‬ ‫الفصل العاشر ‪ :‬سالسل الرموز‬ ‫نناقش هنا كٌفٌة التعامل مع النصوص حٌث ٌت ّم تمثٌل الكلمات والنصوص بسبلسل من األحرف )الرموز(‪.‬‬ ‫‪23‬‬


‫الفصل الحادي عشر ‪ :‬المؤ ّ‬ ‫شرات‬ ‫تعتبر المإ ّ‬ ‫شرات من أقوى مٌزات لغة الـ ‪ C++‬حٌث تسمح لنا بالتعامل مع الذاكرة مباشرة وتم ّكننا من إنشاء‬ ‫بنى معطٌات دٌنامٌكٌة‪ .‬أحٌانا تكون المإ ّ‬ ‫شرات صعبة الفهم ولكنّ مفهومها بسٌط وٌصبح التعامل معها سهبل‬ ‫كلّما زاد التمرّ ن وكتابة األكواد المتعلقة بها‪.‬‬ ‫الفصل الثانً عشر ‪ :‬الذاكرة الدٌنامٌكٌة‬ ‫شرات حٌث ٌت ّم حجز الذاكرة أثناء تنفٌذ البرنامج باستخدام المإ ّ‬ ‫مفهوم الذاكرة الدٌنامٌك ٌّة مرتبط جدّا بالمإ ّ‬ ‫شرات‬ ‫الفصل الثالث عشر ‪ :‬التراكٌب‬ ‫هً بنى معطٌات خاصّة تسمح لنا بجمع ع ّدة أنواع من المعطٌات تحت نوع واحد وهً مهمّة فً قواعد البٌانات‬ ‫المعرفة من قبل المستخدم‬ ‫الفصل الرابع عشر ‪ :‬األنواع‬ ‫ّ‬ ‫نعرّ ف هنا أنواع بٌانات جدٌدة غٌر موجودة باالعتماد على أنواع موجودة ومعرّ فة مسبقا‪.‬‬ ‫الفصل الخامس عشر ‪ :‬اإلدخال و اإلخراج فً الملفات‬ ‫نتعلم هنا كٌفٌة التعامل مع المل ّفات سواء قراءة محتوٌاتها أو الكتابة علٌها أو البحث فٌها‪.‬‬ ‫الفصل السادس عشر ‪ :‬معالجة االستثناءات‬ ‫هذا الفصل هو عبارة عن إضافة جدٌدة إلى لغة ‪ C++‬نتع ّرف من خبلله على طرٌقة عمل ٌّة فً منع تدمٌر‬ ‫البرنامج الناجم عن أخطاء مع ٌّنة فً العمل ٌّات داخل البرنامج كؤن ٌدخل المستخدم حرفا أو اسما بدال من أن‬ ‫ٌدخل رقما‪ .‬مثل هذه األخطاء قد تتسبب بتوقف البرنامج وتدمٌره لذلك سٌكون من األفضل التخلّص منها‬ ‫بطرٌقة آمنة‪.‬‬ ‫الفصل السابع عشر ‪ :‬مقدمة إلى البرمجة كائنٌة التوجه‬ ‫ٌعتبر هذا الفصل مدخبل إلى الصّفوف والكابنات وٌق ّدم بعض المفاهٌم التً تخصّ هذا النمط من البرمجة‬ ‫صفوف )األنواع( الجدٌدة وأشٌاء أخرى تتعلّق بها‪.‬‬ ‫وٌتح ّدث عن أسلوب بناء ال ّ‬ ‫الفصل الثامن عشر ‪ :‬مبادئ البرمجة كائنٌة التوجه‬ ‫نتعرّ ض فً هذا الفصل إلى المبادئ الثبلث للبرمجة كابن ٌّة التوجّ ه ونشرحها بشكل سهل و مختصر ونق ّدم بعض‬ ‫األمثلة علٌها فً محاولة لتقدٌم فكرة بسٌطة عن هذا النمط من البرمجة وال ٌعتبر هذا الكتاب كافٌا فً هذا‬ ‫المجال‪.‬‬ ‫الفصل التاسع عشر ‪ :‬القوالب‬ ‫أسلوب قويّ ج ّدا للتعامل مع الصفوف والتوابع واختصار الوقت والجهد األمر الذي ستتعرّ ف علٌه عندما تنهً‬ ‫آخر صفحة من صفحات البرمجة الكابن ٌّة‪.‬‬ ‫الفصل العشرون ‪ :‬فضاءات األسماء‬ ‫مكتبات قٌاس ٌّة موجودة فً لغة ‪ C++‬القٌاس ٌّة تحتوي على الكثٌر من المزاٌا و التوابع التً تو ّفر علٌك الوقت و‬ ‫الجهد فهً تحوي المبات من التوابع الجاهزة والتً ستحتاجها فً ك ّل برامجك‪ .‬سن ّتعلم بسرعة كٌف ٌمكننا أن‬ ‫صة بنا‪.‬‬ ‫نصنع فضاءات األسماء الخا ّ‬

‫‪24‬‬


‫التعامل مع المترجم ‪visual c++ 6.0‬‬ ‫نقوم بفتح البرنامج بعد تنصٌبه على الحاسب فتظهر النافذة التالٌة‬

‫نختار ‪ New‬من القائمة ‪ File‬ث ّم نختار التبوٌب ‪ Files‬ث ّم نختار ‪ C++ Source File‬ث ّم نحدد اسم الملف‬ ‫ومكان الحفظ‪ 9‬ث ّم نضغط الزر ‪OK‬‬

‫‪9‬‬

‫أحٌانا ٌجب تغٌ​ٌر مكان الحفظ عند العمل على ‪Windows 7‬‬

‫‪25‬‬


‫نكتب البرنامج فً المحرّ ر الذي ٌظهر ونضغط الزر‬ ‫الشكل‬

‫نضغط الزر‬

‫)‪ (compile‬أو ‪ ctrl+f7‬لترجمة الشٌفرة كما فً‬

‫أو ‪ ctrl+f5‬لتنفٌذ البرنامج كما فً الصورة‬

‫‪26‬‬


‫القسم األول‬ ‫ضل‬ ‫ما ال َف ُ‬ ‫در ُك ِّل‬ ‫َوقَ ُ‬ ‫فَه ُفز بِعِم ٍِ‬

‫إِّل ِأل ِ‬ ‫َهل العِم ِ إَِّه ُ​ُ ُِ‬ ‫ِ‬ ‫ِ‬ ‫ام ِر ٍئ ما كاَن ُ​ُيسنُهُ‬ ‫َول تَطمُب بِ​ِه بَ َدلً‬

‫ِ ِ‬ ‫ِ‬ ‫َعمى اهلُدى ل َم ِن استَُدى أَدّلءُ‬ ‫ِ‬ ‫ِ ِ‬ ‫َولم ِرجال َعمى األَفعال امساءُ‬ ‫ِ​ِ‬ ‫الناس َموتى َو ُأه ُل العم أَحياءُ‬ ‫فَ ُ‬ ‫كرم اهلل وجهو‬ ‫علي ّ‬ ‫اإلمام ّ‬

‫‪27‬‬


‫الفصل األوّل ‪:‬‬

‫لع ّل أفضل ما نبدأ به رحلتنا مع هذه اللغة هو البرنامج الشهٌر الذي ٌتم ّتع ببساطته إضافة الحتوابه على‬ ‫المكوّ نات الربٌس ٌّة التً الب ّد منها فً كل برنامج‪ ,‬ولٌس علٌك اآلن لكً تكون مبرمجا سوى أن تضع أناملك‬ ‫الناعمة تلك على لوحة المفاتٌح‪ .‬اآلن هل أنت مستع ّد لكتابة أوّ ل برنامج لك؟ إذن ه ٌّا بنا‪.‬‬ ‫افتح المترجم واكتب فٌه النصّ الذي على ٌسار الشكل ث ّم اضغط على أزرار التشغٌل‬ ‫!‪Hello World‬‬

‫‪// my first program in C++‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;"!‪cout << "Hello World‬‬ ‫;‪return 0‬‬ ‫}‬

‫واتح التىفيذ( الخزج )‬

‫الشيفزة‬

‫تهانٌنا! كان هذا أوّ َل برنامج لنا فً ‪ ,C++‬واآلن دعنا نبدأ بشرح هذه العبارات‬ ‫‪// my first program in C++‬‬ ‫هذا السطر ٌدعى تعلٌقا‪ ,‬فكل السطور التً تبدأ بـ ‪ //‬تعتبر تعلٌقات وهذه التعلٌقات لٌس لها أي تؤثٌرعلى‬ ‫البرنامج‪.‬لقد جرت عادة المبرمجٌن على استخدام التعلٌقات لتوضٌح ومراقبة عمل الشٌفرة من داخل ملف‬ ‫المصدر‪.‬‬ ‫>‪#include <iostream‬‬ ‫ّ‬ ‫الجمل التً تبدأ بالرمز)‪ (#‬هً عبارات تقوم بتوجٌه المترجم وال ٌت ّم تنفٌذها أثناء تنفٌذ الشٌفرة التً نكتبها لكنها‬ ‫تعمل كدلٌل للمترجم‪ ,‬ففً مثالنا الجملة >‪ #include <iostream‬تخبر المترجم بؤن ٌقوم بتضمٌن الملف‬ ‫المصدري ‪ iostream‬وهو ملف مع ّرف سابقا ٌحتوي على تصرٌحات للمكتبة القٌاسٌة الخاصة باإلدخال‬ ‫واإلخراج فً لغة ‪ C++‬وقد استدعٌنا هذه المكتبة أل ّننا سنستخدمها الحقا فً برنامجنا‪ ,‬وكؤننا نقول للمترجم‪:‬‬ ‫"إننا سوف نستخدم التوابع المعرفة فً هذا الملف المصدري لذلك اذهب وأحضره"‪ ,‬وسنؤتً على شرح ذلك‬ ‫الحقا‪.‬‬ ‫;‪using namespace std‬‬ ‫جمٌع مكوّ نات المكتبة القٌاسٌة للغة ‪ C++‬معرّ فة فٌما ٌدعى بفضاء االسم )‪ (namespace‬الذي سنشرحه الحقا‪.‬‬ ‫ومن أجل الوصول إلى العدٌد من التعلٌمات واألوامر الجاهزة فإنّ هذا السطر ٌتكرّ ر كثٌرا فً البرامج التً‬ ‫تستخدم المكتبة القٌاسٌة حٌث سترى هذا السطر فً معظم البرامج الموجودة فً هذا الكتاب‪.‬‬ ‫)(‪int main‬‬ ‫ٌمثل هذا السطر بداٌة التصرٌح عن التابع الربٌسً ‪.main‬‬ ‫إنّ التابع ‪ main‬هو النقطة األولى لبداٌة أي برنامج مكتو ٍ‬ ‫ب بلغة ‪ .C++‬وهذا الٌعتمد على كون هذا التابع مكتوبا‬ ‫فً أوّ ل الشٌفرة أو فً وسطها أو فً آخرها فؤٌنما كان هذا التابع مكتوبا فإنّ التنفٌذ سٌبدأ منه أي أ ّنه ضروريّ‬ ‫ج ّدا لٌعمل البرنامج ومن دونه ال ٌوجد برنامج‪.‬‬ ‫فً التصرٌح عن التابع ‪ main‬وضعنا القوسٌن ) ( بعد اسم التابع وذلك ألنّ الصٌغة العا ّمة للتصرٌح عن التوابع‬ ‫تقضً بذلك كما سٌرد معنا فٌما بعد‪.‬‬ ‫ك ّل التعلٌمات التً سٌقوم التابع ‪ main‬بتنفٌذها محصورة بٌن القوسٌن} { كما هو مبٌن فً المثال السابق‪.‬‬

‫‪28‬‬


‫;"!‪cout << "Hello World‬‬ ‫هذه التعٌلمة هً األكثر أهمٌة فً هذا البرنامج‪ .‬تعتبر ‪ cout‬تعلٌمة قٌاسٌة فً ‪ C++‬وهً تقوم بطباعة الجملة‬ ‫‪ Hello World‬على الشاشة‪.‬‬ ‫ومن الجٌد التنوٌه إلى أن التعلٌمة ‪ cout‬معرّ فة فً الملف المصدري ‪ iostream‬وقد قمنا بتضمٌنه فً بداٌة‬ ‫برنامجنا كً نتمكن من استخدامها‪.‬‬ ‫مالحظة‪ :‬من المه ّم أن تعرف أنّ ك ّل تعلٌمة فً ‪ٌ C++‬جب أن تنتهً بفاصلة منقوطة );(‪.‬‬ ‫)من األخطاء الشابعة بٌن مبرمجً ‪ C++‬أ ّنهم ٌن َسون وضع الفاصلة المنقوطة فً نهاٌة بعض‬ ‫التعلٌمات م ّما ٌُحدث خطؤ ٌمنع البرنامج من العمل‪ ,‬فانتبه لذلك(‪.‬‬ ‫;‪return 0‬‬ ‫تقوم التعلٌمة ‪ return‬بإنهاء التابع )(‪ main‬وتعٌد التعلٌمة التً تؤتً بعدها كقٌمة للتابع‪ ,‬فً حالتنا هذه تعٌد ‪.0‬‬ ‫هذه هً الطرٌقة المعتادة إلنهاء البرنامج فعندما ٌعٌد التابع )(‪ main‬القٌمة ‪ 0‬نعلم أنّ البرنامج انتهى دون أ ٌّة‬ ‫أخطاء أثناء ال ّتنفٌذ‪.‬‬ ‫ومن ث ّم البد أ ّنك قد الحظت أنّ كل سطر فً هذا البرنامج قام بعمله‪ ,‬فالتعلٌق الذي بدأ بالرمز )‪ (//‬الذي وجّ ه‬ ‫المترجم ألن ٌتجاهل هذا السطر‪ ,‬وهناك السطر الذي بدأ بالرمز)‪ (#‬الذي وجّ ه المترجم كً ٌجلب الملف‬ ‫المصدري ‪ ,iostream‬وكان هناك السطر الذي صرّ حنا به عن التابع )(‪ ,main‬وأخٌرا التعلٌمة ‪ cout‬التً‬ ‫صٌن بالتابع ‪.main‬‬ ‫وضعناها بٌن القوسٌن } { الخا ّ‬

‫تنسٌق الكتابة‬ ‫ٌمكننا أن نكتب‪:‬‬ ‫} ;‪int main () { cout << " Hello World "; return 0‬‬ ‫ك ّل تعلٌمة فً ‪ C++‬تنتهً بالفاصلة المنقوطة كما ذكرنا‪ .‬لذلك ال فرق فً أن تكتب ال ّتعلٌمات على سطر واحد‬ ‫أو فً ع ّدة أسطر‪ ,‬فطالما أ ّنك لم تضع فاصلة منقوطة فهذا ٌعنً أنّ ال ّتعلٌمة لم تنت ِه بعد‪.‬‬ ‫لك ّننا كتبناه كما فً الجدول لكً تسهل قراءته‪.‬‬ ‫واآلن سنكتب المثال التالً بطرٌقة أخرى ممكنة‬ ‫‪Hello World! I'm a C++ program‬‬

‫‪// my second program in C++‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫<< ‪cout‬‬ ‫;" !‪"Hello World‬‬ ‫<< ‪cout‬‬ ‫;"‪"I'm a C++ program‬‬ ‫;‪return 0‬‬ ‫}‬

‫وٌجب االنتباه إلى أنّ الموجِّ هات )األسطر التً تبدأ بـ ‪ُّ (#‬‬ ‫تشذ عن هذه القاعدة أل ّنها فً واقع األمر ال ّ‬ ‫تمثل‬ ‫تعلٌمات حقٌق ٌّة فهً أسطر ٌقرإها المترجم لك ّنها ال ّ‬ ‫تمثل أيّ جزء من شٌفرة البرنامج‪ ,‬فهذه األسطر ٌجب أن‬ ‫تكتب فً مكانها الخاص فً أعلى البرنامج وهً ال تحتاج إلى فواصل منقوطة فً نهاٌاتها‪.‬‬

‫‪29‬‬


‫التعلٌقات‬ ‫ال ّتعلٌق هو قطعة من الشٌفرة مهملة من قبل المترجم‪ .‬إذن التعلٌقات ال تقوم بؤ ٌّة وظٌفة برمجٌة‪ ,‬وإ ّنما هً‬ ‫موجودة فقط لتذ ّكر المبرمج ببعض المبلحظات حول شٌفرته‪.‬‬ ‫تق ّدم ‪ C++‬نوعٌن من التعلٌقات هما كاآلتً‪:‬‬ ‫تعلٌق على نفس السطر‬ ‫تعلٌق على سطر أو أكثر‬

‫‪// line comment‬‬ ‫‪/* block comment */‬‬

‫واآلن لنضف بعض التعلٌقات إلى برنامجنا السابق‬ ‫‪Hello World! I'm a C++ program‬‬

‫‪/* my second program in C++‬‬ ‫‪With more comments */‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫‪//says hello world‬‬

‫;" !‪cout<<"Hello World‬‬ ‫‪//says I'm a C++ program‬‬

‫;"‪cout<<"I'm a C++ program‬‬ ‫;‪return 0‬‬ ‫}‬

‫تنس استخدام أحد الرمزٌن ‪ //‬أو ‪/* */‬‬ ‫مالحظة‪ :‬عندما ترٌد أن تضٌف تعلٌقا َ ما فعلٌك ّأال َ‬ ‫ألنّ ذلك سٌتسبب بؤخطاء‪ .‬إذ أنّ المترجم سٌعتبر هذه األسطر تعلٌمات بدال من أن‬ ‫ٌعتبرها تعلٌقات وهذا ما ال ترٌده أنت وال المترجم طبعا‪.‬‬

‫‪ .2‬امؤل الفراغات التالٌة ‪:‬‬ ‫‪ ‬كل برنامج فً ‪ٌ C++‬بدأ من التابع ______‪.‬‬ ‫‪ ‬كل عبارة فً ‪ C++‬تنتهً بـ ______‪.‬‬ ‫‪ ‬الرمز ‪ٌ //‬دل على أن هذا السطر ______‪.‬‬ ‫‪ ‬التعلٌقات هً ________________________‪.‬‬ ‫‪ ‬التعلٌمة ;‪ return 0‬تعمل على __________________‪.‬‬ ‫‪ ‬التعلٌمات الخاصة بالتابع ‪ main‬موجودة بٌن ______‪.‬‬ ‫‪ ‬التعلٌمة >‪ #include<iostream.h‬تعنً __________________‪.‬‬ ‫‪ .3‬اجعل البرنامج السابق ٌطبع العبارة التالٌة ‪:‬‬ ‫!‪In the name of Allah. The peace upon you, Hello world‬‬

‫‪2:‬‬


‫الفصل الثاني‪:‬‬

‫إنّ الفابدة من برنامج ‪ hello world‬الذي قمنا بإنشابه فً الدرس السابق هً أن نعرض نصّا ما على شاشة‬ ‫الحاسب‪ ,‬لكن هل البرمجة محدودة إلى هذه الدرجة؟‬ ‫لنفترض أ ّننً طلبت منك أن تحتفظ بالرقم ‪ 4‬فً ذهنك ث ّم طلبت منك أن تحتفظ بالرقم ‪ ,1‬اآلن رجاء أضف ‪4‬‬ ‫إلى الرقم األوّ ل‪ ,‬ث ّم اجمع الرقم األوّ ل إلى الرقم الثانً وأعطنً الناتج‪.‬‬ ‫ٌمكن أن نعبِّر برمجٌا عن ذلك كما ٌلً‪:‬‬ ‫;‪a=4‬‬ ‫;‪b=1‬‬ ‫;‪a=a+3‬‬ ‫; ‪result = a + b‬‬ ‫إنّ الحاسب ٌقوم بإجراء هذه العملٌات تماما كما تقوم أنت بها‪ ,‬لكنه ٌتم ٌّز عنك بؤ ّنه قادر على االحتفاظ بآالف‬ ‫قصٌر جدّا وهذا ٌت ّم من خبلل إدخال القٌم إلى الحاسب‬ ‫القٌم وإجراء عشرات العملٌات الحسابٌة المع ّقدة فً وقت‬ ‫ٍ‬ ‫وتخزٌنها فً أماكن مخصّصة فً الذاكرة ندعوها بالمتغٌّرات‪.‬‬ ‫المتغ ٌّرات‪ :‬هً أماكن )خبلٌا( فً الذاكرة المإ ّقتة ّ‬ ‫تخزن فٌها البٌانات‪ ,‬وٌت ّم الوصول إلٌها من خبلل اسم المتغٌّر‬ ‫الذي ٌم ٌّزه عن باقً المتغٌّرات فً الذاكرة‪.‬‬ ‫كٌف نسمً المتغ ٌّرات؟‬ ‫إنّ االسم الصحٌح للمتغٌّر ٌتؤلف من سلسلة م ّتصلة مكوّ نة من محرف أو أكثر‪ ,‬و ٌمكن أن تحوي أرقاما أو‬ ‫الرمز) _ (‪ .‬شرٌطة أن ٌبدأ اسم المتغٌّر بحرف أو بـ ) _ (‪ّ ,‬‬ ‫وأال ٌبدأ برقم أو ٌحوي على فراغات أو رموز‬ ‫صة مثل‪....$ # .- @ :‬‬ ‫خا ّ‬ ‫هل هناك طول معٌن السم المتغ ٌّر؟‬ ‫اسم المتغٌّر لٌس محدودأ‪ ,‬ولكنّ بعض المترجمات تقبل فقط الـ ‪ 23‬حرفا األولى من اسم المتغٌّر‬ ‫إنّ طو َل ِ‬ ‫وتهمل باقً األحرف‪.‬‬ ‫قاعذة أخزِ يجب عليل أن تضعٍا في حسباول‪ :‬اسم المتغيّز ال يمنه أن ينُن إحذِ النلماث‬ ‫المحجُسة في لغت ‪ٌ َ C++‬ذي النلماث ٌي‪:‬‬

‫‪asm, auto, bool, break, case, catch, char, class, const,‬‬ ‫‪const_cast,‬‬ ‫‪continue,‬‬ ‫‪default,‬‬ ‫‪delete,‬‬ ‫‪do,‬‬ ‫‪double,‬‬ ‫‪dynamic_cast, else, enum, explicit, extern, false, float, for,‬‬ ‫‪friend, goto, if, inline, int, long, mutable, namespace, new,‬‬ ‫‪operator,‬‬ ‫‪private,‬‬ ‫‪protected,‬‬ ‫‪public,‬‬ ‫‪register,‬‬ ‫‪reinterpret_cast, return, short, signed, sizeof, static,‬‬ ‫‪static_cast, struct, switch, template, this, throw, true, try,‬‬ ‫‪typedef, typeid, typename, union, unsigned, using, virtual,‬‬ ‫‪void, volatile, wchar_t‬‬ ‫َيضاف إليٍا مجمُعت العملياث المىطقيت التاليت‪:‬‬

‫‪and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq,‬‬ ‫‪xor, xor_eq‬‬

‫‪31‬‬


‫حساسٌة اللغة لحالة األحرف‪:‬‬ ‫إنّ لغة ‪ C++‬ح ّساسة لحالة األحرف فعندما تكتب اسم المتغٌّر علٌك أن تراعً حالة ك ّل حرف من حروفه‬ ‫واألمثلة التالٌة كفٌلة بشرح هذه الفكرة إن شاء هللا‪:‬‬ ‫فً المثال السابق المتغٌّر ‪ٌ a‬ختلف تماما عن المتغٌّر ‪ ,A‬وكذلك كل المتغٌّرات التالٌة مختلفة‬ ‫… ‪Result , result , RESULT‬‬ ‫أي أ ّنه لو قمنا بالتصرٌح عن متغٌّر ما باالسم ‪ a‬فلن ٌكون بمقدورنا أن نستدعٌه إال باالسم ‪ a‬ولو استدعٌناه‬ ‫آخر وهو غٌر موجود‪.‬‬ ‫باالسم ‪ A‬فلن ٌعرفه المترجم أل ّنه سٌعتبره متغٌّرا َ‬

‫أنواع البٌانات )‪(Data types‬‬ ‫عندما نكتب برنامجا فإ ّننا سنحتاج إلى تخزٌن البٌانات فً الذاكرة باستخدام المتغٌّرات مما ٌعنً أ ّننا سنحجز‬ ‫مساحة فً الذاكرة لك ّل واح ٍد من المتغٌّرات التً سنتعامل معها‪.‬‬ ‫نخزن ّ‬ ‫لكن هل لكل ّ المتغ ٌّرات نفس الحجم فً الذاكرة؟ لتوضٌح هذه المسؤلة لنفترض أ ّننا نرٌد أن ّ‬ ‫كبل‬ ‫من القٌم التالٌة ‪ 10‬و ‪ 45.123‬و ‪.Hi Everybody‬‬ ‫إنّ ذاكرة الحاسب مقسّمة إلى وحدات تدعى باٌتات ‪ .Bytes‬والباٌت هو وحدة قٌاس الحجم الصغرى التً‬ ‫سنتعامل معها‪ .‬نستطٌع أن نخ ّزن فً الباٌت الواحد عددا صحٌحا بٌن ‪ 1‬و ‪ 366‬أو حرفا أو رمزا واحدا فقط‪.‬‬ ‫واضح تماما أ ّننا لن نستخدم فقط األرقام من ‪ 1‬إلى ‪ ,366‬ولن ندخل حرفا واحدا فقط فنحن بحاجة ألكثر من‬ ‫ذلك بكثٌر لذلك ٌو ّفر لنا الحاسب أنواعا أخرى أكثر تعقٌدا من النوعٌن السابقٌن وذلك بتجمٌع عدّة باٌتات إلى‬ ‫بعضها لت ّتسع لحجم أكبر من البٌانات‪) .‬كما هو موضح فً الشكل(‬

‫‪32‬‬


‫نعرض فً الجدول التالً عدّ ة أنواع من البٌانات المستخدمة فً ‪.C++‬‬

‫نوع المتغ ٌّر‬

‫الحجم بالباٌت‬

‫مالحظات‬

‫المدى (ٌمثل القٌم التً ٌمكن للمتغ ٌّر أن ٌأخذها)‬

‫‪char‬‬

‫‪2‬‬

‫بإشارة ]‪[-128,127‬‬ ‫دون إشارة ]‪[0,255‬‬

‫حرف واحد أو رقم طوله‬ ‫‪ 8‬بِت‬

‫‪short‬‬

‫‪3‬‬

‫بإشارة ]‪[-32768 , 32767‬‬ ‫دون إشارة ]‪[0,65535‬‬

‫رقم صحٌح طوله ‪06‬‬ ‫بِت‬

‫‪long‬‬

‫‪5‬‬

‫بإشارة ]‪[-2147483648 , 2147483647‬‬ ‫دون إشارة ]‪[0,53:5:783:6‬‬

‫رقم صحٌح طوله ‪23‬‬ ‫ِبت‬

‫‪int‬‬ ‫‪float‬‬

‫‪ 3‬أو ‪5‬‬ ‫‪5‬‬

‫إما ‪ short‬أو ‪long‬‬ ‫إلى‬

‫رقم صحٌح‬ ‫رقم عشري‬

‫‪double‬‬

‫‪9‬‬

‫‪long double‬‬

‫‪21‬‬

‫‪bool‬‬

‫‪2‬‬

‫إلى‬ ‫إلى‬ ‫‪ true‬أو ‪false‬‬

‫)‪ 8‬أرقام(‬ ‫)‪ 26‬رقم(‬ ‫)‪ 26‬رقم(‬

‫رقم ذو دقة عشرٌة‬ ‫مضاعفة عن ‪float‬‬ ‫رقم ذو دقة عشرٌة‬ ‫مضاعفة عن ‪double‬‬ ‫متغ ٌّر منطقً بإحدى‬ ‫القٌمتٌن ‪ 1‬أو ‪0‬‬

‫واآلن لنعد إلى موضوعنا الذي ك ّنا بدأنا الحدٌث عنه سابقا‪.‬‬ ‫نصرح عن المتغ ٌّرات؟‬ ‫ك ّنا نقول‪ :‬كٌف ٌمكننا أن‬ ‫ّ‬ ‫نذكر اسمه وفقا‬ ‫نذكر نوع البٌانات )…‪ (int, short, float,‬التً سٌؤخذها المتغٌّر‪ ,‬ث ّم‬ ‫تفرض علٌنا اللغة أن‬ ‫َ‬ ‫َ‬ ‫لقواعد التسمٌة التً أوردناها للتو‪ .‬أي أنّ التصرٌح عن المتغٌّرات ٌخضع للقاعدة التالٌة‪:‬‬ ‫; ‪data_type variable_Identifier‬‬ ‫أو‬

‫; ‪data_type variable_Identifier = initial_value‬‬ ‫أمثلة‪:‬‬ ‫; ‪int a‬‬ ‫; ‪float mynumber‬‬ ‫; ‪long mysecondnumber = 5‬‬ ‫كما تبلحظ بدأ التصرٌح عن المتغٌّر ‪ a‬بالنوع ‪ int‬أي أ ّننا نقول للمترجم‪" :‬إنّ المتغٌّر هو من نوع األعداد‬ ‫الثانً‪ .‬أمّا المثال ّ‬ ‫الصحٌحة ‪ int‬و اسمه ‪ ,"a‬وكذلك األمر فً المثال ّ‬ ‫الثالث فقد تابعنا الخطوات بؤن قمنا‬ ‫بتبدبته )أي إسناد قٌمة ابتدابٌة للمتغٌر أثناء التصرٌح عنه( على القٌمة ‪.5‬‬ ‫تم ّكننا ‪ C++‬من التصرٌح عن عدّة متغٌّرات من نفس النوع وتبدبتها إن أردنا فً سطر واحد‪.‬‬ ‫مثال‪:‬‬

‫وهذا مكافا تماما لل ّشكل التالً‪:‬‬

‫; ‪int a, b = 3, c = 5‬‬ ‫; ‪int a‬‬ ‫; ‪int b = 3‬‬ ‫; ‪int c = 5‬‬

‫‪33‬‬


‫لعلّك الحظت من الجدول أنّ األنواع (‪ )int , short , long, char‬تكون بإشارة أو بدون إشارة وهذا تابع‬ ‫للمجال الذي نرغب بؤن ٌضمّه المتغٌّر ففً بعض الحاالت نكون واثقٌن بؤنّ القٌم التً سٌؤخذها متغٌّر عدديّ‬ ‫هً من ال ّنوع الصّحٌح و الموجب فقط عندها قد ال نرغب بؤن ٌكون المتغٌّر معرّ فا لٌستقبل األعداد السالبة‪.‬‬ ‫تستطٌع أن تح ّدد فٌما إذا كان المتغٌّر من األنواع األربعة السابقة ٌمتلك إشارة أو ال وذلك باستخدم إحدى‬ ‫الكلمتٌن التالٌ​ٌن‪:‬‬ ‫; ‪unsigned short NumberOfSons‬‬ ‫; ‪signed int MyAccountBalance‬‬ ‫فً الحالة األولى من المعروف أنّ عدد األبناء ال ٌمكن أن ٌكون أقل من الصفر فإمّا أن ٌكون هناك أبناء أو ال‬ ‫ٌكون لذلك صرّ حنا عن ‪ NumberOfSons‬على أ ّنه بدون إشارة سالبة‪.‬‬ ‫أمّا فً الحالة الثانٌة فبل شًء ٌضمن عدم إدخال قٌمة سالبة على المتغٌّر ‪MyAccountBalance‬‬ ‫( داللة على الخسارة مث اال ) لذلك صرّ حنا عنه على أ ّنه من النوع ‪ signed‬الذي ٌستطٌع أن ٌحمل أرقاما سالبة‪.‬‬ ‫وبشكل افتراضً إذا لم تحدد فٌما إذا كان المتغٌّر من النوع ‪ signed‬أو ‪ unsigned‬فإنّ المترجم سٌعتبره من‬ ‫النوع ‪ signed‬لذلك ٌمكن التصرٌح عن المتغٌّر فً الحالة الثانٌة من المثال السابق بالشكل‪:‬‬ ‫; ‪Int MyAccountBalance‬‬ ‫وهذا هو الشكل المعتاد لهذه الحالة‪.‬‬ ‫واآلن لنكتب المثال الذي بدأنا به درسنا‬ ‫‪16‬‬

‫‪// operating with variables‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫‪// declaring variables:‬‬ ‫;‪int a, b‬‬ ‫;‪int result‬‬ ‫‪// process:‬‬ ‫;‪a = 10‬‬ ‫;‪b = 4‬‬ ‫;‪a = a + 2‬‬ ‫;‪result = a + b‬‬ ‫‪// print out the result:‬‬ ‫;‪cout << result‬‬ ‫‪// terminate the program:‬‬ ‫;‪return 0‬‬ ‫}‬

‫مالحظة ‪ :‬إنّ الطرٌقة السابقة بتبدبة المتغٌّرات مؤخوذة من لغة ‪ ,C‬وهذا ما ٌدعى )‪ ,(C-Like‬لكنّ‬ ‫‪ C++‬تمتلك طرٌقة أخرى لفعل ذلك وهً ‪:‬‬ ‫; )‪data_type variable_Identifier (initial_value‬‬ ‫; ‪int a = 5‬‬ ‫; )‪int a (5‬‬ ‫أي أنّ ‪:‬‬

‫‪34‬‬


) strings ( ‫مق ّدمة إلى السالسل‬ C++ ‫ توجد فً لغة‬.‫ ٌعبّر عن سلسلة من الرموز المحفوظة فً حجرات متتالٌة من الذاكرة‬string ‫إنّ النوع‬ ‫ سنشرحها الحقا فً فصل‬C-style string ‫ وتدعى‬C ‫ األولى مؤخوذة من لغة‬,‫طرٌقتان للتعامل مع السبلسل‬ .STL ‫ ومكتبة القوالب القٌاسٌة‬string ّ‫سبلسل الرموز أمّا الطرٌقة الثانٌة فتعتمد على الصف‬ <string> ‫ ٌجب أن نضمّن الملف المصدري‬string ‫لكً نستطٌع أن نتعامل مع السبلسل‬ // my first string #include <iostream> #include <string> using namespace std;

enter your name: Basil Hello Basil

int main () { string name; cout<<"enter your name: "; cin>>name; cout << "Hello "<<name<<endl; return 0; }

ّ ‫ تقوم بنقل المإ‬endl ‫التعلٌمة‬ .‫شر إلى السطر التالً كما سنرى فٌما بعد‬

(<,>) ‫( والمقارنة‬+=) ‫( واإلضافة‬+) ‫ كالجمع‬string ّ‫هناك مجموعة من العمل ٌّات المعرّ فة فً الصف‬ :‫مثال‬ // my second string #include <iostream> #include <string> using namespace std; int main () { string firstName,lastName,fullName; cout<<"enter your first name: "; cin>>firstName; cout<<"enter your last name: "; cin>>lastName; fullName=firstName+" "+lastName; cout<<"Hello "<<fullName<<endl; if(firstName<lastName) cout<<firstName<<endl; return 0; }

35

enter your first name: Ahmad enter your last name: Sami Hello Ahmad Sami Ahmad


‫‪ .2‬أجب عن األسبلة التالٌة ‪:‬‬ ‫‪ ‬هل المتغٌّر ‪ Num‬هو نفس المتغٌّر ‪ num‬فً ‪ C++‬؟‬ ‫‪ ‬هل ٌجب أن ٌعطى المتغٌّر نوعا من البٌانات عند التصرٌح عنه ؟‬ ‫‪ ‬هل ٌمكن أن تكون أسماء المتغٌّرات أي مجموعة من الرموز ؟‬ ‫‪ ‬هل نستطٌع أن نعرّ ف متغٌّرا ونعطٌه قٌمة فً نفس اللحظة ؟‬ ‫‪ ‬ما الفرق بٌن المتغٌّرات ‪ signed‬و ‪. unsigned‬‬ ‫‪ .3‬امؤل الفراغات التالٌة ‪:‬‬ ‫‪ ‬المتغ ٌّرات هً ______ فً ذاكرة الحاسب ______فٌها البٌانات‪ ,‬وٌت ّم الوصول إلٌها من خبلل‬ ‫______المتغٌّر الذي ______عن باقً المتغٌّرات فً ______‪.‬‬ ‫‪ .4‬اختر اإلجابة الصحٌحة؟‬ ‫; ‪unsigned long f = -1.25‬‬ ‫; ‪int 4men‬‬ ‫;'‪double d = 'S‬‬ ‫; ‪long _2u‬‬ ‫; ‪short hi.‬‬ ‫; "‪char u = "U‬‬

‫)‪a‬‬ ‫)‪b‬‬ ‫)‪c‬‬ ‫)‪d‬‬ ‫)‪e‬‬ ‫)‪f‬‬

‫‪ .5‬ما هً األخطاء فً البرنامج التالً‪:‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫; ‪float a = 1 , b = 0‬‬ ‫;‪unsigned int result‬‬ ‫;‪a = a - 6‬‬ ‫;‪result = A + b‬‬ ‫;‪cout << result‬‬ ‫}‬

‫‪36‬‬


‫الفصل الثالث ‪:‬‬

‫تو ّفر المكتبة ‪ iostream‬التعلٌمتٌن ‪ cin‬و ‪ cout‬حٌث ت ّم تصمٌ ُم ُه َما من أجل التخاطب بٌن المستخدم والحاسب‪,‬‬ ‫وذلك أنّ العمل ٌّة ‪ cout‬تقوم بالطباعة على الشاشة بٌنما تقوم العملٌة ‪ cin‬بإدخال القٌم التً ٌحتاجها البرنامج من‬ ‫لوحة المفاتٌح‪.‬‬

‫تعلٌمة اإلخراج )‪(cout‬‬ ‫تعاملنا مع هذه التعلٌمة منذ أوّ ل درس لنا فً ‪ C++‬لذلك فؤنا واثق بؤ ّنك تدرك وظٌفتها‪ ,‬ولك َّنه من األفضل أن‬ ‫البق بصاحبة الجبللة ‪.cout‬‬ ‫شرح‬ ‫أق ّدم إلٌك تذكٌرا مع‬ ‫ٍ‬ ‫ٍ‬ ‫تعمل هذه التعلٌمة على إخراج قٌم المتغٌّرات والثوابت التً تؤتً مباشرة بعد معامل الحشر >>‪ ,‬ولها الشكل‬ ‫التالً‪:‬‬ ‫‪cout<< "Islam is a way of life" ; // print Islam is a way of life on screen‬‬ ‫‪// print number 120 on screen‬‬ ‫‪// print the content of variable x on screen‬‬

‫; ‪cout<< 120‬‬ ‫; ‪cout<< x‬‬

‫مالذي تفعله هذه التعلٌمات؟‬ ‫‪ -0‬التعلٌمة األولى ‪ :‬تطبع هذه التعلٌمة العبارة ‪ Islam is a way of life‬المحصورة بٌن عبلمتً‬ ‫التنصٌص " " على شاشة الخرج‪( .‬عندما نرغب بطباعة نص ما فعلٌنا أن نضعه بٌن قوسً التنصٌص وكذلك األمر عند‬ ‫إسناد نص إلى متغٌّر نصً لذلك فالعبارتٌن اآلتٌتٌن مختلفتٌن تماماا)‪.‬‬

‫رطجغ اٌؼجبسح ث‪ ٓ١‬ل‪ٛ‬ع‪ ٟ‬اٌزٕظ‪١‬ض ‪ ٟ٘ٚ‬اٌىٍّخ ‪cout<< "Hello" ; // Hello‬‬ ‫رطجغ ل‪ّ١‬خ اٌّزغ‪ّ١‬ش ‪cout<< Hello ; // Hello‬‬ ‫‪ -3‬التعلٌمة الثانٌة‪ :‬تطبع الرّ قم ‪ 031‬على شاشة الخرج‪.‬‬ ‫ّ‬ ‫المخزنة فً المتغٌّر ‪ x‬على شاشة الخرج‪.‬‬ ‫‪ -2‬التعلٌمة الثالثة‪ :‬تطبع القٌمة‬ ‫تستطٌع أن تستخدم أكثر من معامل حشر واحد << فً نفس التعلٌمة‪:‬‬ ‫; " ‪cout<< "The peace upon you, " << "I am " << "a C++ sentence.‬‬ ‫هذه العبارة تطبع الجملة التالٌة‪:‬‬

‫‪The peace upon you, I am a C++ sentence.‬‬ ‫تكمن الفابدة من استخدام أكثر من معامل حشر فً نفس التعلٌمة فً طباعة عبارة مر ّكبة من قٌم ثابتة‬ ‫ومتغٌّرات كما فً المثال التالً‪:‬‬ ‫; ‪cout<<"I am "<< age << " years old and my zipcode is "<< zipcode‬‬

‫‪37‬‬


‫ عندها فإنّ ناتج التعلٌمة‬42296 ‫ ٌحمل القٌمة‬zipcode ‫ والمتغٌّر‬32 ً‫ ه‬age ‫لو افترضنا أن قٌمة المتغٌّر‬ :‫السابقة سٌكون‬ I am 20 years old and my zipcode is 60094 ‫\) فهً تطبع على سطر‬new line( \n ‫ ال تقوم بإضافة رمز انتهاء السطر‬cout ‫ٌجب أن تعلم أنّ التعلٌمة‬ ‫ لتوضٌح هذه‬.‫ لذلك عندما ترغب فً الطباعة على سطر جدٌد فعلٌك أن تضٌف هذا الرّ مز بنفسك‬.‫واحد‬ :‫المسؤلة‬ :ً‫لنقل إ ّننا نرٌد أن نطبع الشكل التال‬ Go forward young Muslims, wherever you are In the shadow of the sun or by the light of a star :ً‫عندها قد نكتب التال‬ cout<< "Go forward young Muslims, wherever you are"; cout<< " In the shadow of the sun or by the light of a star"; :ً‫لكنّ المفاجؤة عندما نشغل البرنامج فشكل الطباعة سٌكون كاآلت‬ Go forward young Muslims, wherever you are In the shadow of the sun or by the light of a star

‫ والحل ٌكمن كما قلنا‬,‫وهذا ما ال نرٌده فالعبارتان على سطر واحد بٌنما نرٌد أن تكون كل واحدة على سطر‬ :‫\ فً نهاٌة التعلٌمة األولى لتصبح بالشكل‬n ‫للتوّ بإضافة الرمز‬ cout<< " Go forward young Muslims, wherever you are\n"; :‫ ث ّم ٌقو َم بتنفٌذ التعلٌمة الثانٌة‬,‫عندها سٌعلم المترجم أ ّنك ترٌد منه أن ٌبدأَ سطرا جدٌدا‬ cout<< " In the shadow of the sun or by the light of a star"; ‫) وعندها سٌكون شكل البرنامج‬end line( endl ‫\ وهً التعلٌمة‬n ‫هناك تعلٌمة بدٌلة عن رمز االنتهاء‬ :ً‫كاآلت‬ cout<< " Go forward young Muslims, wherever you are"<<endl; cout<< " In the shadow of the sun or by the light of a star"; :‫سنقدّم مثاال نذكر من خبلله بعض الطرق الممكنة الستخدام هاتٌن التعلٌمتٌن‬ #include<iostream> using namespace std; int main() { /* **** 1 **** */ cout<< "Welcome to you\n"; cout<<"C++ You are elegant"<< endl; /* **** 2 **** */ cout<< "Welcome to you "<< endl; cout<<"C++ You are elegant\n"; /* **** 3 **** */ cout<< "Welcome to you\nC++ You are elegant"<< endl; /* **** 4 **** */ cout<< "Welcome to you"<< endl <<"C++ You are elegant\n"; /* … */ return 0; } Welcome to you C++ You are elegant

38


‫تعلٌمة اإلدخال )‪input (cin‬‬ ‫تستخدم هذه التعلٌمة إلدخال القٌم المطلوبة من لوحة المفاتٌح‪ ,‬ونستخدم لذلك معامبل ٌدعى معامل اإلدخال <<‬ ‫ث ّم نتبعه باسم المتغٌّر الذي نرغب بإعطابه القٌمة المقروءة من لوحة المفاتٌح‪ ,‬وذلك كما ٌلً‪:‬‬ ‫; ‪int age‬‬ ‫; ‪cin>> age‬‬ ‫مثال‪:‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int i‬‬ ‫;" ‪cout << "Please enter an integer value:‬‬ ‫;‪cin >> i‬‬ ‫;‪cout << "The value you entered is " << i‬‬ ‫;"‪cout << " and its double is " << i*2 << ".\n‬‬ ‫;‪return 0‬‬ ‫}‬ ‫‪Please enter an integer value: 702‬‬ ‫‪The value you entered is 702 and its double is 1404.‬‬

‫مالحظة ‪ :2‬قد ٌكون المستخدم أحد أه ّم العوامل التً تسبب فشل برنامجك ففً المثال السابق طلبنا‬ ‫من المستخدم أن ٌدخل رقما صحٌحا‪ ,‬ولكن ماذا لو أدخل المستخدم اسمه؟‬ ‫بالطبع لن تكون مسرورا لذلك‪.‬‬ ‫طبعاً ٌىاك حل لمثل ٌذي المشامل َلنىّىا له وتحذث عىً ٌىا َإو ّما أردوا التىبيً لمثل‬ ‫ٌذي المشامل حتّ تضعٍا في حسباول‪.‬‬

‫مالحظة ‪ٌ :3‬مكن أن نستخدم التعلٌمة ‪ cin‬إلدخال أكثر من قٌمة كما ٌلً‪:‬‬ ‫; ‪cin >> a >> b‬‬

‫بعض الرموز الخاصة‬ ‫سطر جدٌد‬ ‫ٌكافا الضغط على زر‬ ‫مسافة جدولة أفقٌة‬ ‫تراجع‬ ‫ٌصدر صوتا‬ ‫تطبع الرمز‬ ‫تطبع الرمز‬

‫‪New line‬‬ ‫‪Enter‬‬ ‫‪Tabulation‬‬ ‫‪Back space‬‬ ‫‪Beep‬‬

‫'‬ ‫"‬

‫‪\n‬‬ ‫‪\r‬‬ ‫‪\t‬‬ ‫‪\b‬‬ ‫‪\a‬‬ ‫'\‬ ‫"\‬

‫‪39‬‬


‫‪ .2‬مالذي تطبعه التعلٌمة التالٌة‪:‬‬ ‫; " *****‪cout<<"*\n**\n***\n****\n‬‬ ‫‪ .3‬اكتب برنامج ٌقرأ درجة الحرارة بالسٌلٌسوس )‪ ,(c‬ث ّم ٌحولها إلى الفهرانهاٌت وفق العبلقة‬ ‫‪ .2‬اكتب برنامج ٌقرأ درجة الحرارة بالفهرانهاٌت )‪ ,(f‬ث ّم ٌحولها إلى مبوٌة وفق العبلقة‬ ‫–‬ ‫‪ .6‬اكتب برنامجا ٌقرأ تسارع جسم ما ‪ a‬و الزمن ‪ t‬الذي استغرقه فً الحركة ث ّم ٌحسب‪:‬‬ ‫المسافة المقطوعة‬ ‫و السرعة النهابٌة‬ ‫‪ .5‬اكتب برنامجا ٌحسب قٌمة التابع التالً‬ ‫‪ .4‬إذا علمت أن مجموع األعداد من ‪ 1‬إلى العدد ‪ٌ n‬عطى بالعبلقة التالٌة‬ ‫∑‬ ‫اكتب برنامجا باستخدام هذه العبلقة لحساب مجموع األعداد من ‪ 1‬إلى ‪ n‬التً ٌدخلها المستخدم ث ّم‬ ‫احسب المتوسط الحسابً لها‬ ‫‪ .7‬اكتب برنامجا ٌطبع العبارة‪Just remember "Allah created You'. :‬‬ ‫‪ .8‬اكتب برنامجا ٌحسب المتوسط الحسابً لثبلثة أعداد ٌدخلها المستخدم‪.‬‬

‫‪3:‬‬


โ ซุงู ู ุตู ุงู ุฑุงุจุน โ ช:โ ฌโ ฌ

โ ซู ู ู ุซู ุฑ ู ู ุงุฃู ุญู ุงู ู ุญุชุงุฌ ุฅู ู ุฃุฑู ุงู ุฃู ู ุตู ุต ุซุงุจุชุฉ ุงู ุณุชุฎุฏุงู ู ุง ู ู ุจุฑุงู ุฌู ุงโ ช .โ ฌู ุฏ ุงู ู ู ู ู ุฐู ู ู ุงุถุญุง ู ู โ ฌ โ ซุงู ุจุฑุงู ุฌ ุงู ุนุงุฏู ุฉ ุฃู ุงู ุจุณู ุทุฉ ู ู ู ู ู ู ู ุชุถุญ ู ู ุงู ุจุฑุงู ุฌ ุงู ู ุจู ุฑุฉ ุงู ุชู ุชุชุนุงู ู ู ุน ุงู ุฏู ุง ู ู ุงู ุฑู ุงุถู ู ุฉ ู ุงู ุฑุณู ู ู ุบู ุฑู ุงโ ช.โ ฌโ ฌ โ ซู ู ู ุคุฎุฐ ู ู ุซุงู ุงู ุฑู ู ุงู ู ุนุฑู ู ๐ ุงู ุฐู ู ุซู ุฑุง ู ุง ู ู ุณุชุฎุฏู ู ู ุงู ุญุณุงุจุงุช ุงู ุฑู ุงุถู ุฉโ ช .โ ฌู ุนู ู ุฃ ู ู ู ู ู ู ู ุง ุฒุงุฏุช ุฏ ู ู ุฉ ุงุฃู ุฑู ุงู โ ฌ โ ซุงู ุนุดุฑู ู ุฉ ุฒุงุฏุช ุฏ ู ู ุฉ ุงู ุญุณุงุจุงุชโ ช ,โ ฌู ู ู ู ุชุฑุถ ุฃ ู ู ู ุง ุณู ุณุชุฎุฏู ุงู ุฑู ู ๐ ู ู ุจุฑู ุงู ุฌู ุง ุนุฏู ุฉ ู ุฑู ุงุช ู ู ู ุณู ู ู ู ู ุถุทุฑู ู ู โ ฌ โ ซู ู ุชุงุจุฉ ู ุฐุง ุงู ุฑู ู ู ุนุฏู ุฉ ู ุฑู ุงุชโ ช .โ ฌุฅู ู ู ุฐู ุงู ุทุฑู ู ุฉ ุชุนู ู ุฒู ุงุฏุฉ ุงุญุชู ุงู ู ู ู ุน ุฃุฎุทุงุก ู ู ุฏ ู ุฎุทุง ุจู ุชุงุจุฉ ุงู ุฑู ู ู ู ู ู ุง ู ุนู ู โ ฌ โ ซุฎุทุค ุญุณุงุจู ุง ู ุฏ ู ุชุณุจุจ ุจู ุงุฑุซุฉ ู ุจู ุฑุฉ ู ู ุงู ุจุฑุงู ุฌ ุงู ู ู ุฏุณู ู ุฉ ุฃู ุงุฅู ู ุดุงุจู ู ุฉ ู ุฐู ู ู ู ุฑู ุช ู ุบุงุช ุงู ุจุฑู ุฌุฉ ู ุง ู ุณู ู ู โ ฌ โ ซุจุงู ุซู ุงุจุช ู ุคู ุช ุชุตุฑุญ ุนู ุงู ุซุงุจุช ู ุชุนุทู ู ุงู ู ู ู ุฉ ุงู ุชู ุณู ุคุฎุฐู ุง ู ุงู ุชู ุงู ู ู ู ู ุฃู ุชุชุบู ุฑ ุทู ุงู ู ุชุฑุฉ ุงู ุชู ู ู ุฐ ุซ ู ู โ ฌ โ ซุชู ู ู ุจุงุณุชุฏุนุงุก ุงู ุซุงุจุช ู ู ู ู ู ุฑู ุฉ ุชู ู ุฏ ุงุณุชุฎุฏุงู ู ู ู ู ุงโ ช.โ ฌโ ฌ

โ ซู ู ู ู ุตุฑุญ ุนู ุงู ุซู ุงุจุชุ โ ฌ โ ซู ู ุงู ุทุฑู ู ุชุงู โ ช:โ ฌโ ฌ โ ซโ ช ๏ ผโ ฌุงุฃู ู ู ู โ ช:constโ ฌโ ฌ โ ซ; โ ชconst float pi = 3.14159265โ ฌโ ฌ โ ซ; 'โ ชconst char tab = '\tโ ฌโ ฌ โ ซโ ช ๏ ผโ ฌุงู ุซุงู ู ุฉ โ ช:#defineโ ฌโ ฌ โ ซโ ช#define pi 3.14159265โ ฌโ ฌ โ ซ'โ ช#define NewLine '\nโ ฌโ ฌ โ ซู ู ู ุฐู ุงู ุญุงู ุฉ ู ุณุชุฎุฏู ุงู ุชุนู ู ู ุฉ โ ช #defineโ ฌุซ ู ู ู ุฐู ุฑ ุงุณู ุงู ุซุงุจุช ุซ ู ู ุงู ู ู ู ุฉ ุงู ุชู ุณู ุคุฎุฐู ุงโ ช .โ ฌุงู ุชุจู โ ช :โ ฌู ู ู ุฐู ุงู ุทุฑู ู ุฉ ุงู โ ฌ โ ซู ู ุฌุฏ ู ุงุตู ุฉ ู ู ู ู ุทุฉ ู ู ู ู ุงู ุฉ ุงู ุชุนู ู ู ุฉโ ช.โ ฌโ ฌ โ ซู ุนู ู ู ุงู ุญุธุช ุฃ ู ู ู ุง ู ู ู ู ู ุจุชุญุฏู ุฏ ู ู ุน ุงู ุซุงุจุช ู ู ุงู ุญุงู ุฉ ุงู ุซุงู ู ุฉ ู ู ุง ู ุนู ู ุง ู ู ุงู ุญุงู ุฉ ุงุฃู ู ู ู โ ช.โ ฌโ ฌ โ ซุงู ุญุงู ุฉ ุงุฃู ู ู ู โ ฌ โ ซ>โ ช#include<iostreamโ ฌโ ฌ โ ซ;โ ชusing namespace stdโ ฌโ ฌ โ ซ;โ ชconst double pi = 3.14159265โ ฌโ ฌ โ ซ)(โ ชint mainโ ฌโ ฌ โ ซ{โ ฌ โ ซ; โ ชfloat rโ ฌโ ฌ โ ซโ ชr = 0 ;//initial to 0โ ฌโ ฌ โ ซ;" โ ชcout<<"enter circle radius plz:โ ฌโ ฌ โ ซ; โ ชcin>> rโ ฌโ ฌ โ ซ" = โ ชcout<< "circle areaโ ฌโ ฌ โ ซ;โ ช<< 0.5 * pi * r * r << endlโ ฌโ ฌ โ ซ; โ ชreturn 0โ ฌโ ฌ โ ซ}โ ฌ

โ ซุงู ุญุงู ุฉ ุงู ุซุงู ู ุฉโ ฌ

โ ซโ ช0โ ฌโ ฌ โ ซ;" โ ชradius plz:โ ฌโ ฌ โ ซ" =โ ฌ โ ซ;โ ช* r << endlโ ฌโ ฌ

โ ซ>โ ช#include<iostreamโ ฌโ ฌ โ ซ;โ ชusing namespace stdโ ฌโ ฌ โ ซโ ช#define pi 3.14159265โ ฌโ ฌ โ ซ)(โ ชint mainโ ฌโ ฌ โ ซ{โ ฌ โ ซ; โ ชfloat R ,rโ ฌโ ฌ โ ซโ ชr = 0 ;//initial toโ ฌโ ฌ โ ซโ ชcout<<"enter circleโ ฌโ ฌ โ ซ; โ ชcin>> rโ ฌโ ฌ โ ซโ ชcout<< "circle areaโ ฌโ ฌ โ ซโ ช<< 0.5 * pi * rโ ฌโ ฌ โ ซ; โ ชreturn 0โ ฌโ ฌ โ ซ}โ ฌ

โ ซโ ช41โ ฌโ ฌ


‫الفصل اخلامس ‪:‬‬

‫تعرّ فنا فً الدرس السابق على المتغٌّرات والثوابت وقلنا‪" :‬إنّ المتغٌّرات هً األماكن التً ّ‬ ‫ٌخزن الحاسب فٌها‬ ‫البٌانات وهً مستعدّة لتغٌ​ٌر قٌمتها أثناء تنفٌذ البرنامج‪ ,‬بٌنما الثوابت فهً أماكن فً الذاكرة تحتفظ بقٌمة وحٌدة‬ ‫ال ٌمكن تغٌ​ٌرها طوال فترة تشغٌل البرنامج"‪ ,‬وتعرّ فنا أٌضا على كٌفٌة ال ّتصرٌح عن ك ّل منهما‪ ,‬ولكن كٌف‬ ‫ٌمكننا التحكم بالقٌم التً تحتفظ بها المتغ ٌّرات؟‬ ‫من أجل هذا تزوّ دنا ‪ C++‬بالمعامبلت‪ .‬والتً ُت َّ‬ ‫مثل فً هذه اللغة بمجموعة من الكلمات المفتاحٌة المحجوزة‬ ‫والرموز الخاصة وهذه المعامبلت تعتبر من أساس ٌّات اللغة لذلك الب ّد لك عزٌزي القارئ من التعرف علٌها و‬ ‫التعامل معها بشكل جٌد‪.‬‬

‫‪ .1‬اإلسناد (=)‬ ‫نستخدم معامل اإلسناد = كً نعطً المتغٌّر قٌمة من نوع‬

‫ٌقبله(كأن نضع رقم صحٌح فً متغٌّر من النوع العشري مثالا)‬

‫; ‪float a = 3‬‬ ‫أسند العدد الصحٌح ‪ 4‬إلى المتغٌّرالعشري ‪ٌ .a‬قوم معامل اإلسناد بإسناد القٌمة على ٌمٌنه إلى المتغٌّر الذي على‬ ‫ٌساره حٌث أنّ القٌمة على الٌمٌن ٌمكن أن تكون متغٌّرا أو عددا ثابتا أو نتٌجة لعدد من العملٌات على قٌم‬ ‫موافقة لنوع المتغٌّر على ٌسارمعامل اإلسناد‪ .‬واإلسناد المعاكس لٌس ممكنا‪.‬‬ ‫أمثلة‪:‬‬ ‫?‪b:‬‬ ‫?‪b:‬‬ ‫‪b:4‬‬ ‫‪b:4‬‬ ‫‪b:7‬‬ ‫; ‪a = 2 + b ; 3) a = 7‬‬

‫? ‪// a :‬‬ ‫‪// a : 10‬‬ ‫‪// a : 10‬‬ ‫‪// a : 4‬‬ ‫‪// a : 4‬‬ ‫)‪b = 5 ; 2‬‬

‫; ‪int a , b‬‬ ‫; ‪a = 10‬‬ ‫;‪b=4‬‬ ‫;‪a=b‬‬ ‫;‪b=7‬‬ ‫)‪a = 2 + ( b = 5 ) ; // 1‬‬

‫أسند القٌمة ‪ 6‬إلى المتغٌّر ‪ b‬ث ّم أسند المجموع )‪ (2 + b‬إلى المتغٌّر ‪.a‬‬ ‫; ‪a = b = c = 5 ; //1( c =5 ; 2( b = c ; : c = 5 3) a = b ; : b = 5‬‬ ‫أسند القٌمة ‪ 6‬إلى المتغٌّرات الثبلثة ‪a , b , c‬‬

‫‪ .2‬المعامالت الرٌاضٌة (‪)+, -, *, /, %‬‬ ‫تدعم ‪ C++‬خمس معامبلت رٌاض ٌّة وهً‪:‬‬ ‫العملٌة‬ ‫‪+ Addition‬‬ ‫‪ subtraction‬ــ‬ ‫‪* multiplication‬‬ ‫‪/ division‬‬ ‫‪% module‬‬

‫الوظٌفة‬ ‫ٌقوم بجمع القٌمتٌن على طرفٌه‬ ‫ٌقوم بطرح القٌمتٌن على طرفٌه‬ ‫ٌقوم بضرب القٌمتٌن على طرفٌه‬ ‫ٌقوم تقسٌم القٌمة التً علً ٌساره على القٌمة التً التً على ٌمٌنه‬ ‫ٌعٌد باقً قسمة القٌمة على ٌمٌنه على القٌمة على ٌساره‬

‫‪42‬‬


‫‪ .3‬معامالت اإلسناد المركبة (=| ‪)+=, -=, *=, /=, %=, &=, ^=,‬‬ ‫;‪value += increase‬‬ ‫;‪a -= 5‬‬ ‫;‪a /= b‬‬ ‫;‪price *= units + 1‬‬

‫;‪value = value + increase‬‬ ‫;‪a = a - 5‬‬ ‫;‪a = a / b‬‬ ‫;)‪price = price * (units + 1‬‬ ‫وكذلك باقً المعامبلت‪.‬‬

‫‪ .4‬معامالت الزٌادة و النقصان (‪)++, --‬‬ ‫;‪a=a+1‬‬ ‫;‪a=a-1‬‬

‫; ‪a+= 1‬‬ ‫; ‪a-= 1‬‬

‫; ‪a++‬‬ ‫; ‪a--‬‬

‫مالحظة‪:‬‬ ‫ٌمكن استخدام هذٌن المعاملٌن بطرٌقتٌن مختلفتٌن و المثال التالً ٌبٌن ذلك‪:‬‬ ‫الطرٌقة األولى‬ ‫;‪b = 3‬‬ ‫; ‪a = b++‬‬ ‫‪// a = 3 , b = 4‬‬

‫الطرٌقة الثانٌة‬ ‫;‪b = 3‬‬ ‫;‪a = ++b‬‬ ‫‪// a = 4 , b = 4‬‬

‫ُتسند ‪ b‬إلى ‪ a‬ث ّم تزداد ‪ b‬بمقدار ‪ 1‬تزداد ‪ b‬بمقدار ‪ 1‬ث ّم ُتسند ‪ b‬إلى ‪a‬‬

‫الفرق‬ ‫فً كبل الطرٌقتٌن بدأنا مع ‪b = 3‬‬ ‫فً الطرٌقة‪ 0‬تصبح ‪ a = 3‬ث ّم‬ ‫تزداد قٌمة ‪ b‬فتصبح ‪ b = 4‬أما فً‬ ‫الطرٌقة‪ 2‬تزداد قٌمة ‪ b‬ث ّم تصبح‬ ‫‪a=b=4‬‬

‫‪ .5‬معامالت المقارنة ( =< ‪) ==, !=, >, <, >=,‬‬ ‫تستخدم هذه المعامبلت عادة للمقارنة بٌن عبارتٌن برمجٌتٌن‪ ,‬وتعٌ ُد إحدى القٌمتٌن ‪ true‬أو ‪ false‬وذلك‬ ‫حسب نتٌجة المقارنة‪.‬‬ ‫المعامل‬ ‫==‬ ‫=!‬ ‫<‬ ‫>‬ ‫=<‬ ‫=>‬

‫وصفه‬ ‫ٌساوي‬ ‫ال ٌساوي‬ ‫أصغر من‬ ‫أكبر من‬ ‫أصغر أو ٌساوي‬ ‫أكبر أو ٌساوي‬

‫مثال‬ ‫) ‪ ( 6 == 8‬ستعٌد ‪false‬‬ ‫)‪ (3 != 4‬ستعٌد ‪true‬‬ ‫) ‪ ( 9 > 5‬ستعٌد ‪false‬‬ ‫) ‪ ( 9 > 5‬ستعٌد ‪true‬‬ ‫)‪ (7 >= 7‬ستعٌد ‪true‬‬ ‫)‪ (7 <= 7‬ستعٌد ‪true‬‬

‫طبعا نستطٌع استخدام متغٌّرات أو تعابٌر للمقارنة بٌنها عوضا عن استخدام أرقام ثابتة فقط‪.‬‬ ‫لنفترض أنّ لدٌنا‬ ‫‪a = 2, b = 3, c = 6‬‬ ‫تعٌد ‪false‬‬ ‫) ‪( a == 5‬‬ ‫تعٌد ‪true‬‬ ‫) ‪( a * b >= c‬‬ ‫تعٌد ‪false‬‬ ‫)‪(b+4>a*c‬‬ ‫تعٌد ‪true‬‬ ‫) ‪( ( b = 2 ) == a‬‬ ‫‪43‬‬


‫كن حذراا‪ :‬استخدام المعامل = مرّ ة واحدة فقط ٌعنً اإلسناد أمّا استخدامه مرّ تٌن == فٌعنً المقارنة والسطر‬ ‫الرابع من المثال السابق ٌوضح ذلك‪.‬‬ ‫فً العدٌد من المترجمات كما فً لغة ‪ C‬مثبل تعٌد المعامبلت المنطقٌّة قٌما عددٌّة صحٌحة حٌث تعٌد القٌمة ‪1‬‬ ‫بدال من ‪ false‬وتعٌد قٌما مختلفة عن ‪ 1‬بدال من ‪( true‬فً الحالة العامة تعٌد القٌمة ‪.)0‬‬

‫‪ .6‬المعامالت المنطقٌة (|| ‪)!, &&,‬‬ ‫المعامل ‪: ! not‬‬ ‫) ‪!( 5 == 5‬‬ ‫) ‪!( 6 <= 4‬‬ ‫‪!true‬‬ ‫‪!false‬‬

‫ٌعٌد ‪ false‬ألن ‪ 6‬تساوي ‪6‬‬ ‫ٌعٌد ‪ true‬ألن ‪ 7‬لٌست أصغر من أو تساوي الـ ‪5‬‬ ‫ٌعٌد ‪false‬‬ ‫ٌعٌد ‪true‬‬

‫المعامالن && و || ‪:‬‬ ‫&& ّ‬ ‫ٌمثل معامل الربط المنطقً ) َو ( ‪and‬‬ ‫|| ّ‬ ‫ٌمثل معامل الربط المنطقً ) أو ( ‪or‬‬ ‫‪a‬‬ ‫‪true‬‬ ‫‪true‬‬ ‫‪false‬‬ ‫‪false‬‬

‫‪b‬‬ ‫‪true‬‬ ‫‪false‬‬ ‫‪true‬‬ ‫‪false‬‬

‫‪a && b‬‬ ‫‪true‬‬ ‫‪false‬‬ ‫‪false‬‬ ‫‪false‬‬

‫‪a || b‬‬ ‫‪true‬‬ ‫‪true‬‬ ‫‪true‬‬ ‫‪false‬‬

‫مثال ))‪((a ) && ( b)) , (( a) || ( b‬‬ ‫)) ‪(( 5 == 5 ) && ( 3 < 6 )), (( 5 == 5 ) || ( 3 < 6‬‬ ‫)) ‪(( 5 == 5 ) && ( 3 > 6 )), (( 5 == 5 ) || ( 3 > 6‬‬ ‫)) ‪(( 5 != 5 ) && ( 3 < 6 )), (( 5 != 5 ) || ( 3 < 6‬‬ ‫)) ‪(( 5 != 5 ) && ( 3 > 6 )), (( 5 != 5 ) || ( 3 > 6‬‬

‫‪ .7‬المعامل الشرطً (?)‬ ‫ٌعمل هذا المعامل على تقٌ​ٌم تعبٌر ما وٌعٌد إحدى قٌمتٌن وفقا لتقٌ​ٌم التعبٌر‪ .‬وله الشكل اآلتً‪:‬‬ ‫‪condition ? result1 : result2‬‬ ‫وهو ٌكافا التعلٌمة التالٌة‬ ‫) ‪if (condition == true‬‬ ‫;‪return result1‬‬ ‫‪else‬‬ ‫;‪return result2‬‬ ‫أي‪ :‬إذا كان الشرط محققا ا فإنّ المعامل سٌعٌد النتٌجة األولى و ّإال سٌعٌد النتٌجة الثانٌة‪.‬‬ ‫مثال‪:‬‬ ‫;‪a = 7, b = 3‬‬ ‫; ‪(a == b) ? return 1 : 2‬‬ ‫سٌعٌد العدد ‪ 3‬ألن الشرط غٌر محقق )‪ 7‬ال تساوي ‪.(2‬‬

‫‪44‬‬


‫‪ .8‬معامل تحوٌل البٌانات‬ ‫ٌسمح لك هذا المعامل بتحوٌل متغٌّر من نوع إلى آخر وهناك عدّة طرق لفعل ذلك واألكثر شهرة منها هو‬ ‫المعامل التالً‪ )type( :‬أو )‪type (value‬‬ ‫مثال‪:‬‬ ‫; ‪Int i‬‬ ‫; ‪float pi = 3.14‬‬ ‫‪i = (int)pi ; // pi = 3.14 , i = 3‬‬ ‫السطر الثالث من المثال السابق ٌقوم بتحوٌل قٌمة المتغٌّر العشري إلى عدد صحٌح‪ ,‬و ٌمكن أن ٌكتب بالشكل‪:‬‬ ‫; )‪i = int(pi‬‬

‫‪ .9‬المعامل )(‪sizeof‬‬ ‫ٌقبل هذا المعامل وسٌطا واحدا إ ّما أن ٌكون نوعا من أنواع البٌانات المؤلوفة أو متغٌّرا بح ّد ذاته‪ ,‬وهو ٌعٌد حجم‬ ‫الوسٌط بالباٌت‪.‬وله الشكل‪:‬‬ ‫; )‪int a = sizeof(char‬‬ ‫سٌعٌد هذا المعامل القٌمة ‪ 2‬ألن النوع ‪ٌ char‬ؤخذ ‪ 2‬باٌت فً الذاكرة كما فً الجدول فً الدرس السابق‪.‬‬

‫أولو ٌّات تنفٌذ المعامالت‬ ‫لٌكن لدٌنا العبارة البرمجٌة التالٌة‪:‬‬ ‫;‪a=5+8%2‬‬ ‫ما هً نتٌجة هذا التعبٌر برأٌك؟ طبعا جوابك هو ‪ 7‬ولكن لماذا؟‬ ‫ٌخضع ترتٌب تنفٌذ المعامبلت للجدول التالً‪:‬‬ ‫األولوٌة‬ ‫‪0‬‬ ‫‪3‬‬

‫‪2‬‬

‫‪1‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬ ‫‪9‬‬ ‫‪01‬‬

‫العملٌة‬ ‫‪ ::‬معامل المدى‬ ‫) ( األقواس ‪sizeof() ,‬‬ ‫*‪%,/,‬‬ ‫‪++ , -‬‬‫~‬ ‫!‬ ‫*‪& ,‬‬ ‫)‪(type‬‬ ‫‪+,‬‬‫> ‪<= , >= , < ,‬‬ ‫== ‪!= ,‬‬ ‫&‪|,^,‬‬ ‫&& ‪|| ,‬‬ ‫‪?:‬‬ ‫= ‪&= , ^= , |= %= , /= , *= , -= , += ,‬‬ ‫‪,‬‬

‫جهة األولو ٌّة‬ ‫من الٌسار‬ ‫من الٌسار‬ ‫من الٌسار‬ ‫من الٌمٌن‬

‫من الٌسار‬ ‫من الٌسار‬ ‫من الٌسار‬ ‫من الٌمٌن‬ ‫من الٌمٌن‬ ‫من الٌسار‬

‫‪45‬‬


‫مثال‪:‬‬

‫‪46‬‬


:‫ ما هً قٌمة العبارات التالٌة‬.2 int a = 0 ; long b = 1, c = 2, d = 3 ; bool e = true , r = true , t = false ; a) a += (b = c = d - 5) ; b) d %= 2 * c / ++b ; c) a = d – ( b += ( c * ( 1 – a ) ) ) ; d) e = !e ; e) r = e || t ; f) t = e && r ; g) e = !( (e && r ) || (e && t ) ) ; :‫ فً كل مرة‬x ‫ حدد أولوٌات العملٌات فً التعابٌر التالٌة ث ّم أوجد قٌمة‬.3 a) x = 7 + 3 * 6 / 2 – 1 ; b) x = 2 % 2 + 2 * 2 – 2 / 2 ; c) x = ( 3 * 9 * ( 3 + ( 9 * 3 / ( 3 ) ) ) ) ; d) c = 2*b – 3/d + a++; :‫ اكتب ناتج الجمل التالٌة‬.4 a) b) c) d)

47

cout<< ++a ; cout<< a++ ; cout<< a++ / 2 ; cout<< ++a / 2 ;


‫الفصل السادس ‪:‬‬

‫إنّ البرنامج لٌس عبارة عن مجموعة من تعلٌمات اإلسناد أو المقارنات أو اإلدخال واإلخراج التً تعلّمناها ح ّتى‬ ‫اآلن‪ ,‬فنحن وكما تعلم نتحدّث عن البرمجة التً إ ّنما نستخدمها كً تساعدنا فً حل مشاكلنا الٌومٌة ومن األشٌاء‬ ‫المهمّة التً نحتاج إلٌها هً اتخاذ القرارت المناسبة إلجراء عملٌات مع ٌّنة دون أخرى‪ .‬توفّر ‪ C++‬مجموعة‬ ‫بُنى برمجٌة نسمٌها بنى التحكم‪ ,‬و البنٌة البرمجٌة هً عبارة عن مجموعة من التعلٌمات ٌفصل بٌن كل‬ ‫تعلٌمتٌن متتالٌتٌن فٌها فاصلة منقوطة‪ ,‬وتكون هذه المجموعة محصورة بٌن قوسً البنٌة } {‪ .‬معظم البنى التً‬ ‫سنتعرّ ف علٌها اآلن تحتاج إلى عبارة عا ّمة كوسٌط ٌت ّم تمرٌره إلٌها‪ .‬فً حال كانت البنٌة تحوي تعلٌمة واحدة‬ ‫فقط فإ ّنها ال تحتاج إلى القوسٌن } { أ ّما إذا كانت البنٌة تحوي أكثر من تعلٌمة فإ ّنها تحتاج إلٌهما‪.‬‬

‫‪ )1‬بنٌة الشرط ‪condition structure‬‬ ‫كثٌرا ما ن ّتخذ قراراتنا باستخدام الشرط فعندما تقول‪" :‬إذا حصل هذا الشًء عندها سؤفعل كذا وكذا"‪ .‬فإ ّنك‬ ‫تستخدم شرطا تبنً على تح ّققه قرارا فً تنفٌذ مجموعة من األشٌاء أو عدم تنفٌذها‪ .‬لنتعرّ ف كٌف نستطٌع أن‬ ‫نفعل ذلك باستخدام ‪C++‬‬ ‫) ‪if ( condition‬‬ ‫تعلٌمة واحدة فقط ‪statement ; //‬‬ ‫أ‪ٚ‬‬ ‫) ‪if ( condition‬‬ ‫{‬ ‫أكثر من تعلٌمة ‪statements… //‬‬ ‫}‬ ‫حٌث أنّ التعلٌمات التً داخل هذه البنٌة ال ٌت ّم تنفٌذها ّإال إذا كان الشرط الذي بٌن القوسٌن )‪(condition‬‬ ‫مح ّققا‪.‬‬ ‫مثال‪ :‬نرٌد من المستخدم أن ٌدخل رقما ما‬ ‫فإذا كان (الرقم ٌساوي ‪ )011‬عندها سنطبع العبارة‪" x is 100 " :‬‬ ‫) ‪if ( x == 100‬‬ ‫; " ‪cout << " x is 100‬‬ ‫فً هذا المثال لدٌنا تعلٌمة واحدة فقط لذلك لم نستخدم القوسٌن }{‪ ,‬و لو أردنا أن نضٌف تعلٌمات أخرى إلى‬ ‫هذه البنٌة عندها ٌجب أن نستخدم القوسٌن }{ أي‪:‬‬ ‫) ‪if ( x == 100‬‬ ‫{‬ ‫; " ‪cout << " x is‬‬ ‫; ‪cout << x‬‬ ‫… ‪statements‬‬ ‫}‬

‫‪48‬‬


‫هناك نوع آخر من الشرط نستخدمه فً حٌاتنا فكثٌرا ما نقول‪ ":‬إذا حصل هذا الشًء عندها سؤفعل هذه األشٌاء‬ ‫و إال سؤفعل أشٌاء أخرى "‪.‬‬ ‫) ‪if ( x == 100‬‬ ‫; ‪statement1‬‬ ‫‪else‬‬ ‫; ‪statement2‬‬ ‫فً المثال السابق نرٌد من المستخدم أن ٌدخل رقما ما‬ ‫فإذا كان (الرقم ٌساوي ‪ )011‬عندها سنطبع العبارة‪" x is 100 " :‬‬ ‫و ّإال سنطبع العبارة ‪" x is not 100 " :‬‬ ‫)‪if (x == 100‬‬ ‫;"‪cout << "x is 100‬‬ ‫‪else‬‬ ‫;"‪cout << "x is not 100‬‬ ‫الٌزال هناك حالة أخٌرة للشرط وسنحتاجها بكثرة أٌضا وهً من الشكل‪:‬‬ ‫( شرط‪ ) 0‬عندها ِافعل األشٌاء‪1‬‬ ‫إذا كان‬ ‫و إال إذا كان ( شرط‪ ) 2‬عندها ِافعل األشٌاء‪2‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫وإال ِافعل األشٌاء‪n‬‬

‫)‪if (condition 1‬‬ ‫{‬ ‫; ‪statements 1‬‬ ‫}‬ ‫)‪else if (condition 2‬‬ ‫; ‪statement 2‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪else‬‬ ‫;‪statement n‬‬

‫مثال‪:‬‬ ‫)‪if (x > 0‬‬ ‫;"‪cout << "x is positive‬‬ ‫)‪else if (x < 0‬‬ ‫;"‪cout << "x is negative‬‬ ‫‪else‬‬ ‫;"‪cout << "x is 0‬‬

‫‪49‬‬


‫‪ )2‬بنى التكرار ‪loops or repetition structures‬‬

‫ٌ‬ ‫شرط ما(‬ ‫أثناء كتابة برامجنا قد نحتاج إلى تكرار مجموعة من التعلٌمات )عددا من المرات أو ح ّتى ٌتح ّقق‬ ‫فعندما ترٌد أن تطبع األرقام من ‪ 12‬إلى ‪ 1‬تنازل ٌّا فما الذي ستصنعه هل ستكتب ‪ 12‬مرّ ات التعلٌمة ‪cout‬‬ ‫لتخرج كل مرّة رقما أق ّل من سابقه ماذا لو أردت طباعة ‪ 1222‬رقم أو أكثر‪ .‬إنّ استخدام البنى التكرارٌة‬ ‫سٌسهّل هذا األمر كثٌرا‪ .‬هناك ثبلثة أشكال من البنى التكرارٌة سنتعرف علٌها تباعا وهً‪:‬‬ ‫‪while ( condition ) statements‬‬ ‫البنٌة األولى ‪ :‬مادام ) الشرط محققا ا ( نفذ التعلٌمات التالٌة‬ ‫البرنامج التالً ٌستخدم هذه الحلقة لطباعة األرقام من ‪ 12‬إلى ‪ 1‬تنازل ٌّا كما هو موضح‪:‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬

‫‪// custom countdown using while‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫; ‪int n = 10‬‬ ‫)‪while (n>0‬‬ ‫{‬ ‫;" ‪cout<< n << ",‬‬ ‫;‪n--‬‬ ‫}‬ ‫;"!‪cout<< "FIRE‬‬ ‫;‪return 0‬‬ ‫}‬

‫بدأ البرنامج من التابع )(‪ ,main‬ث ّم صرّ حنا عن المتغٌّر ‪ n‬الذي حمل القٌمة ‪ ,12‬ث ّم استخدمنا البنٌة ‪while‬‬ ‫التً تفحص الشرط ‪ n > 0‬أوالا‬ ‫‪ ‬فإذا كان الشرط محققا فإ ّنها تقوم بما ٌلً‪:‬‬ ‫‪ -1‬تطبع العدد ‪.n‬‬ ‫‪ -3‬تنقص العدد ‪ n‬بمقدار ‪.1‬‬ ‫‪ -2‬نهاٌة البنٌة ث ّم العودة للتح ّقق من الشرط مرّ ة أخرى فإذا كان مح ّققا عادت إلى الخطوة ‪.1‬‬ ‫‪ ‬و إال سٌنتقل المترجم إلى التعلٌمات التً تقع بعد هذه البنٌة وهً طباعة العبارة !‪.FIRE‬‬ ‫ث ّم نهاٌة البرنامج‪.‬‬ ‫البنٌة الثانٌة‪ :‬ن ّفذ التعلٌمات التالٌة مادام ) الشرط محققا ا (‬ ‫;)‪do statements while (condition‬‬ ‫البرنامج التالً ٌستخدم هذه الحلقة لطباعة األرقام من ‪ 12‬إلى ‪ 1‬تنازل ٌّا كما هو موضح‪:‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬

‫‪// custom countdown using while‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫; ‪int n = 10‬‬ ‫‪do‬‬ ‫{‬ ‫;" ‪cout << n << ",‬‬ ‫;‪n--‬‬ ‫;)‪} while (n>0‬‬ ‫;"!‪cout << "FIRE‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪4:‬‬


‫بدأ البرنامج من التابع )(‪ ,main‬ث ّم صرّ حنا عن المتغٌّر ‪ n‬الذي حمل القٌمة ‪ ,12‬ث ّم استخدمنا البنٌة ‪ do‬التً‬ ‫تنفذ التعلٌمات أوالا وهً تقوم باآلتً‪:‬‬ ‫‪ .1‬تطبع العدد ‪.n‬‬ ‫‪ .3‬تنقص العدد ‪ n‬بمقدار ‪.1‬‬ ‫‪ .2‬نهاٌة البنٌة ث ّم التحقق من الشرط‬ ‫ّ‬ ‫ّ‬ ‫محققا فإنها تعود إلى الخطوة ‪.1‬‬ ‫‪ ‬فإذا كان الشرط‬ ‫سٌنتقل المترجم إلى خارج هذه البنٌة وٌطبع عبارة !‪.FIRE‬‬ ‫‪ ‬و إال‬ ‫ث ّم نهاٌة البرنامج‪.‬‬

‫تنبٌهات حول البنٌتٌن السابقتٌن‬ ‫‪ٌ -1‬جب أن تضع شرطا قاببل للتحقق كً تضمن انتهاء الحلقة )البنٌة( التكرارٌة ألنّ عدم تحقق الشرط ٌعنً‬ ‫الدخول فً حلقة ال نهابٌة وبالتالً لن ٌتوقف البرنامج عن العمل‪.‬‬ ‫فمثبل لو وضعنا ;‪ n++‬بدال من ;‪ n--‬فً أحد المثالٌن السابقٌن فإنّ الحلقة لن تنتهً أبدا‪.‬‬ ‫‪ -3‬هاتان البنٌتان ال تمتلكان عدّادات زٌادة أو نقصان فً داخلهما لذلك فهما تقببلن الشروط المنطقٌة و‬ ‫العددٌة وٌجب علٌك أن تجد طرٌقة تستطٌع من خبللها أن تعرف فٌما إذا تحقّق الشرط )المنطقً أو العددي(‬ ‫أوّ ال‪ ,‬فً المثال السابق استخدمنا المتغٌّر ‪ n‬لهذه المهمة الذي أخذ ٌتناقص مع كل تكرار ح ّتى تحقق شرط‬ ‫‪.‬‬ ‫التوقف‬ ‫ّ‬ ‫ّ‬ ‫ا‬ ‫‪ -2‬البنٌة ‪ while‬تقوم باختبار الشرط ّأوال ث ّم تنفذ التعلٌمات التً بداخلها لو كان الشرط محققا‪ .‬أي أنه قد‬ ‫محقق‪ .‬بٌنما تعمل البنٌة ‪ do‬بعكس‬ ‫غٌر‬ ‫ال ٌت ّم تنفٌذ تعلٌمات هذه البنٌة وال مرّ ة فً حال كان الشرط‬ ‫َ‬ ‫ٍ‬ ‫مر اة أولى ث ّم تتح ّقق من الشرط فإذا تح ّقق أعادت تكرار العملٌات التً‬ ‫أختها فهً تن ّفذ تعلٌمات بنٌتها ّ‬ ‫بداخلها و إال خرجت من البنٌة و تابعت البرنامج‪.‬‬ ‫البنٌة الثالثة‪:‬‬ ‫)‪for (initialization ; condition ; increase‬‬ ‫;‪statement‬‬

‫تتمتع هذه البنٌة بشهرة كبٌرة ألنها من أسهل و أكثر الحلقات التكرارٌة استخداما‪ ,‬فهً تعمل على تكرار‬ ‫التعلٌمات التً بداخلها ابتداء من قٌمة مع ٌّنة وح ّتى قٌمة االنتهاء التً ٌجب أن تكون محدّدة‪ ,‬وهً تحتوي على‬ ‫عدّاد بداخلها ٌستطٌع المبرمج أن ٌتح ّكم بمقدار زٌادته أو نقصانه‪.‬‬ ‫البرنامج التالً ٌستخدم هذه الحلقة لطباعة األرقام من ‪ 12‬إلى ‪ 1‬تنازل ٌّا كما هو موضح‪:‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬

‫‪// custom countdown using for‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫) ‪for ( int n=10 ; n>0 ; n--‬‬ ‫{‬ ‫;" ‪cout << n << ",‬‬ ‫}‬ ‫;"!‪cout << "Fire‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪51‬‬


‫ٌمكن أن تض ّم هذه الحلقة عدّادٌن بنفس الوقت فتؤخ َذ الشكل التالً‪:‬‬

‫‪Initialization‬‬ ‫‪Condition‬‬

‫)‬

‫‪; n++ , i--‬‬

‫‪; n!=i‬‬

‫‪n=0 , i=100‬‬

‫‪Increase‬‬

‫( ‪for‬‬ ‫{‬

‫‪// whatever here...‬‬ ‫}‬ ‫ْ‬ ‫الحلقة ستتوقف‬ ‫تبدأ هذه الحلقة بالقٌم االبتدابٌة التالٌة ‪ n = 0‬و ‪ i = 100‬وتستمرّ مادام ‪ n != i‬أي أنّ‬ ‫بعد ‪ 52‬تكرارا ألنّ ‪i = n = 50‬‬

‫كما ٌمكن أن تكتب هذه الحلقة باألشكال التالٌة أٌضا‪:‬‬ ‫لم نعطً العداد قٌمة ابتدابٌة ولم نحدد مقدار خطوة الزٌادة ‪//‬‬

‫);‪for (;n<10‬‬

‫لم نعطً العداد قٌمة ابتدابٌة فقط ‪for (;n<10;n++) //‬‬ ‫حلقة ال نهابٌة ٌمكن الخروج منها باستخدام التعلٌمة ; ‪// break‬‬

‫); ;(‪for‬‬

‫ٌمكن أن نستخدم الحالة األخٌرة عندما ال نستطٌع أن نعرف قٌمة التوقف أو عندما نرغب باستخدام شرط‬ ‫منطقً بدال من العدّاد كما فً المثال التالً‪:‬‬

‫مثال‪:‬‬ ‫البرنامج التالً ٌقوم بقراءة رقم من لوحة المفاتٌح وطباعته على الشاشة وٌكرّ ر هذه العملٌة حتى ٌدخل‬ ‫المستخدم الرقم ‪2‬‬ ‫‪Enter number (0 to end): 5‬‬ ‫‪You entered: 5‬‬ ‫‪Enter number (0 to end): 0‬‬ ‫‪You entered: 0‬‬

‫‪// number echoer‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪unsigned long n‬‬ ‫;" ‪cout << "Enter number (0 to end):‬‬ ‫;‪cin >> n‬‬ ‫;"‪cout << "You entered: " << n << "\n‬‬ ‫)‪while(n != 0‬‬ ‫{‬ ‫;" ‪cout << "Enter number (0 to end):‬‬ ‫;‪cin >> n‬‬ ‫;"‪cout << "You entered: " <<n<< "\n‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫‪52‬‬


// number echoer #include <iostream> using namespace std; int main () { unsigned long n; do { cout << "Enter number (0 to end): "; cin >> n; cout << "You entered: " << n<< "\n"; } while (n != 0); return 0; }

Enter number (0 to end): 5 You entered: 5 Enter number (0 to end): 0 You entered: 0

// number echoer #include <iostream> using namespace std; int main () { unsigned long n; for (; ;) { cout << "Enter number (0 to end): "; cin >> n; cout << "You entered: " << n << "\n"; if (n== 0) break; } return 0; }

Enter number (0 to end): 5 You entered: 5 Enter number (0 to end): 0 You entered: 0

‫ تستخدم هذه التعلٌمة للخروج من البنٌة التً ُكتِبت فٌها كما فً الحالة الثالثة من‬:break ‫) التعلٌمة‬3 (n == 0) ‫ فنحن نرٌد أن نخرج من الحلقة)البنٌة(التكرارٌة بمجرّ د أن ٌتح ّقق الشرط‬,‫المثال السابق‬ ً‫ تستخدم هذه التعلٌمة عندما نرغب بؤن ٌتجاهل البرنامج التعلٌمات التً تل‬:continue ‫) التعلٌمة‬4 .‫ والعودة إلى بداٌة البنٌة البرمجٌة التً كتبت فٌها هذه التعلٌمة‬continue ‫التعلٌمة‬ :ً‫ باستخدام هذه التعلٌمة فسنكتب اآلت‬5 ‫ ماعدا الرقم‬12 ‫ و‬1 ‫فلو أردنا أن نكتب برنامجا ٌطبع األعداد بٌن‬ #include <iostream> using namespace std; int main() { for (int n=10; n>0;n--) { if (n==5) continue; cout << n << ", "; } cout << "FIRE!\n"; return 0; }

53

10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE!


‫البداٌة من التابع )(‪ٌ .main‬دخل المترجم الحلقة التكرارٌة وعندها تكون قٌمة العدّاد ‪ n = 12‬ث ّم ٌختبر‬ ‫الشرط )‪ (n == 5‬وبالطبع لن ٌكون الشرط مح ّققا ألنّ ‪ 10 != 5‬وعندها ٌتجاهل التعلٌمة الموجودة داخل‬ ‫بنٌة الشرط ‪ if‬ث ّم ٌنتقل إلى التعلٌمة التالٌة وهً تعلٌمة طباعة العدد ‪ n‬وبعدها تنتهً الحلقة للمرّ ة األولى‬ ‫فٌعود المترجم إلى معامل النقصان فً الحلقة وٌغٌر قٌمة العداد ‪ n‬بحسب قٌمة النقصان المطلوبة )فً حالتنا ‪ (1‬ث ّم‬ ‫ٌختبر الشرط ‪ n>0‬فإن كان محققا فسٌعود إلى داخل الحلقة مرّ ة أخرى وٌستمر فً هذه العملٌات حتى تصبح‬ ‫قٌمة ‪ n = 5‬عندها سٌختبرالشرط ‪ n == 5‬والذي أصبح محققا لذلك سٌن ّفذ التعلٌمة الموجودة داخل تعلٌمة‬ ‫الشرط وهً التعلٌمة ‪ continue‬والتً ستجبر المترجم على تجاهل التعلٌمات التً تلٌها مما ٌعنً تجاهل‬ ‫التعلٌمة ;" ‪ cout << n << ",‬والعودة إلى بداٌة الحلقة إلنقاص الع ّداد واختبار الشرط ث ّم الدخول فً‬ ‫الحلقة من جدٌد وهكذا حتى نهاٌة الحلقة‪.‬‬ ‫‪ )5‬التعلٌمة ‪ :goto‬بهذه التعلٌمة تستطٌع إجبار المترجم على القفز من السطر الذي هو فٌه إلى السطر‬ ‫الذي ترٌده لٌكمل التنفٌذ من المكان الذي أرسلته إلٌه‪ .‬الستخدام هذه التعلٌمة نحتاج إلى الفتة ‪label‬‬ ‫الستعمالها كدلٌل على السطر الذي سنرسل المترجم إلٌه‪ ,‬وهذه البلفتة ٌجب أن تتبع بالنقطتٌن ) ‪.( :‬‬ ‫مثال‪:‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬

‫‪// goto loop example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int n=10‬‬ ‫‪loop:// goto label‬‬ ‫;" ‪cout << n << ",‬‬ ‫;‪n--‬‬ ‫)‪if (n>0‬‬ ‫;‪goto loop‬‬ ‫;"‪cout << "FIRE!\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫فً المثال السابق استطعنا أن نطبع األعداد من ‪ 12‬إلى ‪ 1‬دون استخدام حلقات تكرارٌة وذلك باستخدام ‪.goto‬‬ ‫كالمعتاد بدأ البرنامج من التابع )(‪ ,main‬ث ّم صرّ حنا عن المتغٌّر ‪ n‬الذي أخذ القٌمة ‪ 12‬ث ّم بعد ذلك صرّ حنا‬ ‫عن البلفتة ‪ loop:‬وبعدها طبعنا قٌمة ‪ n‬ث ّم أنقصناها بمقدار ‪ 1‬بعد ذلك وضعنا شرطا لنعرف إذا ما كانت‬ ‫‪ n>0‬أو ال فإذا كانت ‪ n > 0‬عندها سنعٌد المترجم إلى السطر الذي ٌحوي البلفتة ‪ loop:‬لٌعٌد العملٌات‬ ‫السابقة كلّها حتى تصبح ‪ n = 0‬عندها لن ٌرجع المترجم إلى البلفتة وسٌكمل البرنامج لٌطبع العبارة‬ ‫!‪ FIRE‬ث ّم ٌنتهً البرنامج‪.‬‬ ‫‪ )6‬التعلٌمة ‪ :switch‬تشبه هذه التعلٌمة فً وظٌفتها التعلٌمة ‪ if‬فهً تختبر قٌمة المتغٌّر الذي ٌت ّم‬ ‫تمرٌره لها كوسٌط ث ّم تحدد العمل الذي ستقوم به من خبلل قٌمة المتغٌّر‪.‬‬ ‫ولها الشكل التالً‪:‬‬ ‫)‪switch(variable‬‬ ‫{‬ ‫‪case value1:‬‬ ‫;‪statements‬‬ ‫;‪break‬‬ ‫…‪//other cases here‬‬ ‫‪default: //optional‬‬ ‫;‪statements‬‬ ‫;‪break‬‬ ‫}‬ ‫‪54‬‬


.‫ نرٌد برنامجا ٌخبر المستخدم عن الٌوم الذي ٌقابل الرقم الذي أدخله المستخدم‬:‫مثال‬ ّ (7 - 1 ‫ونخزنه فً متغٌّر عددي صحٌح و موجب)ألن األرقام هً بٌن‬ ‫أوال ٌجب أن نقرأ الرقم‬ ...‫ وهكذا‬Friday ‫ ٌقابل ٌوم الجمعة‬1 ‫ثانٌا سنختبر قٌمة المتغٌّر ث ّم نقابله بالنصّ المناسب فالرقم‬ .‫ثالثا سنطبع اسم الٌوم المناسب على شاشة الخرج‬ // switch #include<iostream> using namespace std; int main() { unsigned short dnum ; cout<< "Enter number of day(1-7): "; cin>> dnum; cout<< "\n"; switch(dnum){ case 1: // if dnum = 1 cout << "the day is Friday"; break; case 2: // if dnum = 2 cout << "the day is Saturday"; break; case 3: // if dnum = 3 cout << "the day is Sunday"; break; case 4: // if dnum = 4 cout << "the day is Monday"; break; case 5: // if dnum = 5 cout << "the day is Tuesday"; break; case 6: // if dnum = 6 cout << "the day is Wednesday"; break; case 7: // if dnum = 7 cout << "the day is Thursday"; break; default: // if dnum < 1 or dnum> 7 cout << "Sorry we're closed "; break; } cout<< "\n"; return 0; }

55

// if #include<iostream> using namespace std; int main() { unsigned short dnum ; cout<< "Enter number of day(1-7): "; cin>> dnum; cout<< "\n"; if(dnum == 1) cout << "the day is Friday"; else if(dnum == 2) cout << "the day is Saturday"; else if(dnum == 3) cout << "the day is Sunday"; else if(dnum == 4) cout << "the day is Monday"; else if(dnum == 5) cout << "the day is Tuesday"; else if(dnum == 6) cout << "the day is Tuesday"; else if(dnum == 7) cout << "the day is Thursday"; else cout << "Sorry we're closed "; cout<<'\n'; return 0; }


‫لنشرح ما حصل فً التعلٌمة ‪switch‬‬ ‫ّ‬ ‫وخز ّناه فً‬ ‫كما عوّ دتنا ‪ c++‬بدأ البرنامج من التابع )(‪ main‬ث ّم صرّحنا عن المتغٌّر ‪ ,dnum‬ث ّم قرأنا الرقم‬ ‫المتغٌّر ‪ ,dnum‬واآلن جاء دور التعلٌمة ‪ switch‬التً أخذت المتغٌّر ‪ dnum‬وسٌطا‪ .‬بعد ذلك قمنا بذكر‬ ‫الحاالت التً ٌمكن للمتغٌّر أن ٌحملها وهً األرقام }‪ {1,2,..,7‬وذكرنا كل عنصر منها لوحده بعد الكلمة‬ ‫‪ case‬ث ّم وضعنا التعلٌمة التً تناسب كل حالة على حدة وفً نهاٌة كل حالة كتبنا التعلٌمة ‪ break‬التً‬ ‫شرحناها سابقا والتً لها أهمٌّة كبٌرة فً التعلٌمة ‪ switch‬فعندما ٌقارن المترجم قٌمة المتغٌّر الوسٌط مع‬ ‫الحالة األولى و تكون القٌمتٌن متساوٌتٌن عندها سٌنفذ التعلٌمات الخاصة بهذه الحالة وعندما سٌنتهً منها نرٌد‬ ‫منه أن ٌخرج من التعلٌمة ‪ّ switch‬‬ ‫وأال ٌختبر باقً الحاالت لذلك وضعنا التعلٌمة ‪ break‬ولو لم نضعها‬ ‫الخبتر المترجم كل الحاالت الباقٌة وهذا ٌعنً مضٌعة للوقت وبطؤ للبرنامج ال نرٌده أن ٌحصل طبعا‪ .‬أمّا‬ ‫التعلٌمة ‪ default‬فهً تخصّ باقً االحتماالت الممكنة إذ قد ٌدخل المستخدم رقما غٌر األرقام المذكورة‬ ‫لذلك نرٌد من البرنامج أن ٌخبر المستخدم أ ّنه أدخل رقما خاطبا‪ .‬جرّ ب البرنامجٌن‪ ,‬وستجد أن لهما نفس الناتج‬ ‫تماما كما فً الشكل‪:‬‬ ‫‪Enter number of day: 5‬‬ ‫‪the day is Tuesday‬‬

‫باستخدام إحدى البنى التكرارٌة أو باستخدام التعلٌمة ‪ goto‬عدّل البرنامج السابق لٌكرّ ر اإلدخال ح ّتى ٌدخل‬ ‫المستخدم رقما من خارج المجال ‪ 1‬إلى ‪ 7‬حٌث ٌخرج من البرنامج‪.‬‬

‫‪56‬‬


‫‪)7‬‬

‫الحلقات المتداخلة ‪ :nested loops‬قلنا عند الحدٌث عن البنى التكرارٌة‪" :‬إ ّنها تم ّكننا من‬ ‫تكرار مجموعة من التعلٌمات عددا من المرّ ات"‪ .‬أي أ ّنه ٌمكننا أن نطبع الشكل التالً باستخدام حلقة‬ ‫تكرارٌة كما بٌّنا من قبل‪:‬‬ ‫‪1 2 3 4 5‬‬ ‫‪1 2 3 4 5‬‬

‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫)‪for(int j = 1 ; j<=5 ; j++‬‬ ‫;" " << ‪cout << j‬‬ ‫;‪return 0‬‬ ‫}‬

‫لكن ماذا لو أردنا أن نطبع الشكل التالً و الذي ٌمثل عناصر مصفوفة ثنابٌة األبعاد‪.‬‬ ‫‪1 2 3 4 5‬‬ ‫‪1 2 3 4 5‬‬ ‫‪1 2 3 4 5‬‬ ‫ٌمكن فهم هذا الشكل على أ ّنه طباعة األعداد من ‪ 1‬إلى ‪ 5‬ثبلث مرّ ات متتالٌة على ثبلثة أسطر متتالٌة أٌضا أي‬ ‫أ ّننا سنقوم بتكرار عمل الحلقة السابقة ثبلث مرّات كما فً الشكل التالً‪:‬‬ ‫‪1 2 3 4 5‬‬ ‫‪1 2 3 4 5‬‬ ‫‪1 2 3 4 5‬‬

‫‪// nested loop‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫{)‪for( int i = 1 ; i<=3 ; i++‬‬ ‫)‪for(int j = 1 ; j<=5 ; j++‬‬ ‫;" " << ‪cout << j‬‬ ‫;"‪cout<<"\n‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫تبدأ الحلقة األولى عندما ‪ i = 1‬وبما أنّ ‪ 1<3‬سٌ ّتجه المترجم إلى داخل الحلقة األولى لٌن ّفذ ما فٌها من‬ ‫تعلٌمات فٌجد أنّ أول تعلٌمة أما َمه هً الحلقة الثانٌة التً تبدأ من ‪ j = 1‬وتطبع األرقام من ‪ 1‬إلى ‪ 5‬على‬ ‫نفس السطر حٌث ٌعلق المترجم فً هذه الحلقة ح ّتى ٌنتهً منها عندما ‪ ,j = 6‬ث ّم ٌ ّتجه المترجم إلى التعلٌمة‬ ‫الثانٌة فً الحلقة األولى وهً ;"‪ cout<<"\n‬والتً تعنً ِابدأ سطرا جدٌدا‪ ,‬ث ّم ٌنتهً التكرار األول لهذه‬ ‫الحلقة‪ ,‬وتت ّم زٌادة العدّاد ‪ i‬بمقدار ‪ 1‬لٌصبح ‪ i = 2‬وٌت ّم اختبار الشرط مرّ ة أخرى وبما أنّ ‪ 2<3‬فإنّ‬ ‫المترجم سٌعود وٌدخل الحلقة األولى لٌقوم بنفس الخطوات السابقة‪ ,‬فٌعٌد قٌمة ‪ j‬إلى ‪ 1‬لٌعلق مرّ ة أخرى فً‬ ‫الحلقة الثانٌة فٌقوم بطباعة األرقام من جدٌد على السطر الجدٌد الذي جاء من التعلٌمة ;"‪ ,cout<<"\n‬وعندما‬ ‫ٌنتهً من الحلقة الثانٌة ٌكمل الحلقة األولى فٌطبع سطرا جدٌدا‪ ,‬ث ّم ٌكرّ ر ذلك مرّ ة أخٌرة حٌث تكون ‪i = 3‬‬ ‫وبعدها تصبح ‪ i = 4‬م ّما ٌعنً أنّ المترجم سٌغادر الحلقة دون أن ٌنفذها مرّ ة رابعة وعندها نحصل على‬ ‫الشكل السابق‪.‬‬

‫‪57‬‬


.ً‫اكتب برنامجا ٌطبع الشكل التال‬:‫مثال‬ * * * * *

* * * * * * * * * *

// nested loop #include <iostream> using namespace std; int main () { for( int i = 1 ; i<=5 ; i++) { for(int j = 1 ; j<=i ; j++) cout << "* "; /* for(int j = 1 ; j<=5 ; j++) if(j<=i) cout << "* "; */

* * * * *

* * * * * * * * * *

cout<<"\n"; } return 0; }

for ‫ مع الحلقة‬while ‫المثال السابق باستخدام الحلقة‬ // nested loop #include <iostream> using namespace std; int main () { int j = 1; for( int i = 1 ; i<=5 ; i++) { j = 1 ; while( j<=i ) { cout <<"* " ; j++; } cout<<"\n" ; } return 0; }

58

* * * * *

* * * * * * * * * *


‫‪ .1‬اكتب برنامجا ٌطلب من المستخدم أن ٌدخل رقما ث ّم عملٌّة حسابٌّة من العملٌّات األربع المعروفة ث ّم ٌطلب‬ ‫آخر ث ّم ٌظهر النتٌجة وفقا للعملٌّة التً أدخلها المستخدم )باستخدام ‪.(switch‬‬ ‫رقما َ‬

‫‪.0‬‬

‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫‪.2‬‬

‫الخوارزمٌة‬ ‫‪ (a‬اقرأ الرقم األول ‪.n1‬‬ ‫‪ (b‬اقرأ العملٌة ‪.op‬‬ ‫‪ (c‬اقرأ الرقم الثانً ‪.n2‬‬ ‫‪ (d‬افحص العملٌة ‪op‬‬ ‫'‪ op = '+‬اطبع المجموع‬ ‫إذا كانت‬ ‫وإال إذا كانت '–' = ‪ op‬اطبع الفرق‬ ‫وإال إذا كانت '*' = ‪ op‬اطبع الجداء‬ ‫وإال إذا كانت '‪op = '/‬‬ ‫‪ ‬إذا كان الرقم الثانً ال ٌساوي الصفر‬ ‫اطبع القسمة‬ ‫‪ ‬و ّإال اطبع عبارة ‪. Infinite‬‬ ‫الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪float n1 , n2‬‬ ‫;'‪char op = '+‬‬ ‫;‪cout<<"Enter n1:"; cin>> n1‬‬ ‫;" ‪cout<<"\nEnter Operator of {+,-,/,*}:‬‬ ‫;‪cin>>op‬‬ ‫;‪cout<<"\nEnter n2: "; cin>> n2‬‬ ‫)‪switch(op‬‬ ‫‪{case '+':‬‬ ‫;‪cout<< n1<<op<<n2<<" = "<<n1+n2‬‬ ‫;‪break‬‬ ‫‪case '-':‬‬ ‫;‪cout<< n1<<op<<n2<<" = "<<n1-n2‬‬ ‫;‪break‬‬ ‫‪case '*':‬‬ ‫;‪cout<< n1<<op<<n2<<" = "<<n1*n2‬‬ ‫;‪break‬‬ ‫‪case '/':‬‬ ‫)‪if(n2 != 0‬‬ ‫;‪cout<< n1<<op<<n2<<" = "<<n1/n2‬‬ ‫;"‪else cout<<"Infinite‬‬ ‫;‪break‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫‪59‬‬


‫‪ .3‬اكتب برنامجا ٌحسب أصغر األعداد التً ٌدخلها المستخدم وعددها ‪ٌ n‬حدّده المستخدم‪.‬‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ ‪.n‬‬ ‫‪ (b‬اقرأ الرقم األول ‪.‬‬ ‫‪ (c‬اعتبر أنّ أصغر عدد هو الرقم األول‬ ‫)وذلك لكً نقارن كل األعداد التً سنقرأها به ) ‪ ( min‬فإن وجدنا )‬

‫( أصغر منه اعتبرناه هو األصغر (‪.‬‬

‫‪ (d‬من أجل ‪ i = 2‬حتى ‪) i = n‬قرأنا الرقم األول سابقا لذلك بدأنا من ‪(3‬‬

‫‪ ‬اقرأ‬ ‫‪ ‬إذا كان‬ ‫‪ (e‬اطبع أصغر عدد ‪min‬‬ ‫‪ .2‬الشٌفرة‬

‫فاعتبر أن‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪int n, a, min‬‬ ‫;" ‪cout<<"Enter n:‬‬ ‫;‪cin>>n‬‬ ‫;" ‪cout<<"\nEnter number 1:‬‬ ‫;‪cin>>a‬‬ ‫;‪min = a‬‬ ‫)‪for(int i =2 ; i <=n;i++‬‬ ‫{‬ ‫;" ‪cout<<"\nEnter number "<<i<<":‬‬ ‫;‪cin>>a‬‬ ‫)‪if(a<min‬‬ ‫;‪min = a‬‬ ‫}‬ ‫;‪cout<<"\nmin = "<< min << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪ .2‬اكتب برنامجا ٌقرأ اسم طالب وعدد العبلمات التً ٌرغب بحساب المتوسط الحسابً لها ث ّم ٌقرأ ك ّل عبلمة‬ ‫منها وفً النهاٌة ٌطبع اسم الطالب ومتوسطه الحسابً فً ك ّل المواد‪.‬‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ اسم الطالب ثم عدد العبلمات‪.‬‬ ‫‪ (b‬من أجل ‪ i = 1‬حتى ‪ i = n‬بزٌادة قدرها ‪1‬‬ ‫‪ ‬اِقرأ العبلمة رقم ‪i‬‬ ‫‪ ‬أضف العبلمة رقم ‪ i‬إلى المجموع‬ ‫‪ (c‬اطبع اسم الطالب ثم المتوسط الحسابً )المجموع ÷ ‪.(n‬‬

‫‪5:‬‬


‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫>‪#include<string‬‬ ‫;‪using namespace std‬‬ ‫)(‪void main‬‬ ‫;‪{ string name‬‬ ‫;‪int n,mark,i = 0,sum = 0‬‬ ‫‪//important to initial sum and i to 0 here (it's local var).‬‬ ‫;" ‪cout<< "Enter student name:‬‬ ‫;‪cin>>name‬‬ ‫;‪cout<< "Enter number of marks: "; cin>>n‬‬ ‫)‪while(i++ < n‬‬ ‫{‬ ‫;" ‪cout<< "Enter mark ("<<i<<") [between 0 and 100]:‬‬ ‫;‪cin>> mark‬‬ ‫;‪sum += mark‬‬ ‫‪}; // you can do that‬‬ ‫;'‪cout<< name << " Average = " << (float)sum/n <<'\n‬‬ ‫}‬

‫‪ .6‬اكتب برنامجا لحساب السلسلة التالٌة حٌث تدخل ‪ n‬من لوحة المفاتٌح‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ ‪.n‬‬ ‫‪ (b‬من أجل القٌم بٌن الـ ‪ i=1‬حتى ‪i=n‬‬

‫فإن‬

‫المجموع ‪ = a‬المجموع ‪+ a‬‬ ‫‪ (c‬اطبع المجموع‪.‬‬ ‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫; ‪int n‬‬ ‫‪float a = 0.0f ;//Initial a to 0 where f means float value‬‬ ‫;" ‪cout<<"Enter n:‬‬ ‫;‪cin>>n‬‬ ‫)‪for(int i=1;i<=n;i++‬‬ ‫;‪a+=1.0f/i;//like a = a + (float)1/i‬‬ ‫;‪cout<< a << endl‬‬ ‫;‪return 0‬‬ ‫}‬ ‫ّ‬ ‫المخزنة فً المتغٌّر ‪ a‬هً من النوع‬ ‫مالحظة‪ :‬التعلٌمة ; ‪ float a = 0.0f‬تعنً أنّ القٌمة‬

‫العشري و لٌس الصحٌح‪ .‬وكذلك األمر فً التعلٌمة ;‪ a+=1.0f/i‬وكان بإمكاننا أن نكتبها كالتالً‪:‬‬ ‫; ‪a += (float)1 / i‬‬

‫ألنّ ناتج عمل ٌّة القسمة الموجودة على ٌمٌن المساوة السابقة لٌس بالضرورة عددا صحٌحا فمثبل العدد‬ ‫‪ 1/2 = 0.5‬وهو عشريّ لذلك قمنا بتعرٌف المجموع على أ ّنه عشريّ ث ّم قمنا بتحوٌل الطرف‬ ‫األٌمن من المساواة إلى النوع العشريّ لنضمن عدم ضٌاع البٌانات ألنّ قسمة عددٌن صحٌحٌن هً‬ ‫عدد صحٌح فً ‪ .c++‬ولو لم نفعل ذلك فإن ناتج التعلٌمة سٌكون كاآلتً‪:‬‬ ‫‪61‬‬


a +=

1 / i ;

a = 0.0 + 1 / 1 = 0.0 + 1 = 1.0 a = 1.0 + 1 / 2 = 1.0 + 0 = 1.0

‫ عندها‬i = 1 ‫ عندها‬i = 2 ... ‫ عندها‬i = n

a = 1.0 + 1 / n = 1.0 + 0 = 1.0

‫ اكتب برنامجا ٌحسب السلسلة التالٌة من أجل أي عدد ٌدخله المستخدم‬.5

=

‫ الخوارزمٌة‬.0 .n ‫( اقرأ‬a ّ‫ فإن‬i=n ‫ حتى‬i=0 ‫( من أجل القٌم بٌن الـ‬b  : =i! ‫ احسب‬ * j ‫ فإن‬j=i ‫ حتى‬j=1 ‫ من أجل‬+ e ‫ = المجموع‬e ‫المجموع‬

.‫( اطبع المجموع‬c ‫ الشٌفرة‬.2 #include<iostream> using namespace std; int main() { int n; double e = 0.0f; //Initial a to 0 where f means float value double fact = 1; cout<<"Enter n: "; cin>>n; for(int i=0;i<n;i++) { fact = 1; //initial fact to 1 for each calculation of i! for(int j = 1; j<=i;j++) fact *= j; e += 1.0f/fact; //like e = e + (float)1/i; } cout<< e << endl; return 0; }

62


‫مالحظة‪ٌ :‬جب علٌك أن تقوم بتبدبة متغٌّرات المجامٌع والجداءات إلى القٌمة الحٌادٌّة فً العملٌّة فمثبل المتغٌّر‬ ‫‪ّ e‬‬ ‫ٌمثل مجموع السلسلة ونعلم أنّ الجمع ٌؤخذ ‪ 2‬كقٌمة حٌادٌّة أي أنّ إضافة ‪ 2‬إلى المجموع لن ٌغٌّر من النتٌجة‬ ‫شٌبا‪.‬‬ ‫أمّا المتغٌّر ‪ fact‬فهو ّ‬ ‫ٌمثل جداءات أي أنّ القٌمة الحٌادٌّة هً ‪ 1‬ألنّ ضربها بؤيّ عدد لن ٌغٌّر من النتٌجة‬ ‫شٌبا‪ .‬و لو جعلناها ‪ 2‬فإنّ القٌمة التً سنحصل علٌها من أجل المتغٌّر ‪ fact‬هً ‪ 2‬ألنّ ‪:‬‬ ‫‪ fact = 0‬وهذا ٌعنً أنّ ناتج التعلٌمة التالٌة هو كاآلتً‪:‬‬ ‫; ‪fact = 0‬‬

‫;‪fact = 0 * j‬‬

‫;‪fact = fact * j‬‬

‫‪ .4‬اكتب برنامجا ٌحسب السلسلة التالٌة من أجل أي عددٌن ‪ٌ x,n‬دخلهما المستخدم‪.‬‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ ‪.x,n‬‬ ‫‪ (b‬من أجل القٌم بٌن الـ ‪ i=0‬حتى ‪ i=n‬فإن‬ ‫إلى ‪(1‬‬ ‫)كل مرة نعٌد قٌمة‬ ‫‪‬‬ ‫‪:‬‬ ‫‪ ‬احسب !‪=i‬‬ ‫من أجل ‪ j=1‬حتى ‪ j=i‬فإن‬ ‫=‬ ‫‪* j‬‬ ‫‪‬‬

‫المجموع‬

‫= المجموع‬

‫‪+‬‬

‫‪ (c‬اطبع المجموع‪.‬‬ ‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫عند استخدام التوابع الرٌاضٌة مثل ‪#include<cmath> // pow‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫; ‪int n,x‬‬ ‫‪double e = 0.0f ;//Initial a to 0 where f means float value‬‬ ‫;‪double fact = 1‬‬ ‫;" ‪cout<<"Enter n,x:‬‬ ‫;‪cin>>n>>x‬‬ ‫)‪for(int i=0;i<n;i++‬‬ ‫{‬ ‫!‪fact = 1;//initial fact to 1 for each calculation of i‬‬ ‫)‪for(int j = 1; j<=i;j++‬‬ ‫;‪fact *= j‬‬ ‫;‪e += pow(x,i)/fact‬‬ ‫}‬ ‫;‪cout<< e << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪63‬‬


‫‪ .7‬اكتب برنامجا لحساب العبلقتٌن التالٌتبن‪:‬‬

‫∑‬

‫∑‬

‫̅‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ ‪.n‬‬ ‫‪ (b‬من أجل القٌم بٌن الـ ‪ i=1‬حتى ‪i=n‬‬ ‫‪ ‬اقرأ‬ ‫‪+‬‬ ‫= المجموع‬ ‫‪ ‬المجموع‬ ‫‪ ‬المتو ّسط الحسابً لؤلعداد = المجموع ÷ ‪ .n‬أي‬ ‫‪ (c‬اطبع المتوسّط الحسابً‪.‬‬ ‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪float sum =0 , average=0 , a=0‬‬ ‫;‪int n‬‬ ‫;" ‪cout<<"Enter n:‬‬ ‫;‪cin>>n‬‬ ‫)‪for(int i =1 ; i<=n;i++‬‬ ‫{‬ ‫;" ‪cout<<"Enter a"<<i<<" :‬‬ ‫;‪cin>>a‬‬ ‫;‪sum += a‬‬ ‫}‬ ‫;‪average = sum / n‬‬ ‫;‪cout<<"\nAverage = "<<average‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (a‬اقرأ ‪.n‬‬ ‫‪ (b‬من أجل القٌم بٌن ‪ i = 1‬حتى ‪i = n‬‬ ‫‪+‬‬ ‫= المجموع‬ ‫المجموع‬ ‫‪ (c‬اطبع المجموع‪.‬‬

‫‪64‬‬


‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪float sum =0‬‬ ‫;‪int n‬‬ ‫;" ‪cout<<"Enter n:‬‬ ‫;‪cin>>n‬‬ ‫)‪for(int i =1 ; i<=n;i++‬‬ ‫;‪sum += i*i*i‬‬ ‫;‪cout<<"\nSum = "<<sum‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪ .8‬اكتب برنامجا إلٌجاد جذور معادلة من الدرجة الثانٌة معتمدا على المعلومات التالٌة‪:‬‬ ‫√‬ ‫√‬

‫√‬

‫{‬

‫‪ .0‬الخوارزمٌة‬ ‫‪ (1‬اقرأ ‪a,b,c‬‬ ‫‪a‬‬ ‫‪ (3‬أ( إذا كان ‪0‬‬ ‫‪b‬‬ ‫ إذا كان ‪0‬‬‫‪c‬‬ ‫‪ ‬إذا كان ‪0‬‬ ‫‪‬‬ ‫√‬ ‫‪ ‬إذا كان ‪ <2‬فإن‪:‬‬ ‫√‬ ‫‪ ‬و ّإال إذا كان ‪=2‬‬

‫√‬ ‫فإن‪:‬‬

‫‪ ‬و ّإال اطبع المعادلة مستحٌلة الحل‪.‬‬ ‫أو‬ ‫‪ ‬و ّإال)‪ (c=0‬فإنّ ‪ :‬إما‬ ‫‪-‬‬

‫و ّإال)‪ (b=0‬فإنّ‬ ‫‪‬‬ ‫‪‬‬

‫فإذا كان‬ ‫فإنّ √‬ ‫و إال‬

‫فاطبع المعادلة مستحٌلة الحل‪.‬‬

‫ب( و إال)‪(a=0‬‬

‫إذا كان ‪0‬‬

‫‪ b‬فإنّ‬

‫‪.‬‬

‫وإال اطبع ‪.it's not equation‬‬

‫‪65‬‬


‫ الشٌفرة‬.2 #include<iostream> #include<cmath> // or <math.h> using namespace std; int main() { float a , b , c; float delta=0.0 , x1=0.0 , x2=.0; float dsqrt=.0; cout<<"Enter a , b , c:"; cin>>a>>b>>c; cout<<"\n"; if(a!=0) //1 { if(b!=0) //2 { if(c!=0) //3 { delta =((b*b) - (4*a*c)); cout<<"delta = "<<delta<<"\n"; if(delta > 0) //4 { x1 = (float)(-1*b + sqrt(delta)) / 2*a; x2 = (float)(-1*b - sqrt(delta)) / 2*a; cout<<"x1 = "<< x1<<"\nx2 = "<< x2 << endl; } else if(delta == 0) { x1 = x2 = (float)-1*b / 2*a ; cout<<"x1 = x2 = "<<x1<<" Doublicated root!\n"; } else cout<<"Impossible in R\n"; } else { x1 = 0; x2 = (float)-1*b/a; cout<<"Either x = "<<x1<<"\nOr x = "<<x2<<endl; } } else { float t = (float)-1*c/a; if(t>=0) cout<<"x = "<<sqrt(t)<<endl; else cout<<" Impossible in R\n"; } } else{ if(b!= 0) cout<<"x = "<< (float) -c/b<<endl; else cout<<"it\'s not equation.\n"; } return 0; }

66


‫‪ .1‬اكتب الشٌفرة الموافقة للخوارزمٌّة التالٌة‪) :‬باستخدام التعلٌمة ‪(if‬‬

‫‪ .i‬أدخل المعدّل‬ ‫‪ .ii‬إذا كان المعدّل أكبر من ‪ 89‬و أصغر أو ٌساوي ‪ 122‬اطبع ‪Excellent‬‬ ‫‪ .iii‬إذا كان المعدّل أكبر من ‪ 79‬و أصغرأو ٌساوي ‪ 89‬اطبع ‪Very Good‬‬ ‫‪ .iv‬إذا كان المع ّدل أكبر من ‪ 49‬و أصغرأو ٌساوي ‪ 79‬اطبع ‪Good‬‬ ‫‪ .v‬إذا كان المعدّل أكبر من ‪ 59‬و أصغرأو ٌساوي ‪ 49‬اطبع ‪Passed‬‬ ‫وإال اطبع ‪failed‬‬ ‫‪.vi‬‬ ‫‪ .3‬صحّ ح البرامج التالٌة‪:‬‬

‫*‬ ‫* *‬ ‫* * *‬ ‫* * * *‬

‫) ‪a) while ( c <= 5‬‬ ‫{‬ ‫;‪product *= c‬‬ ‫;‪++c‬‬ ‫) ‪b) if ( gender == 1‬‬ ‫; "‪cout<< "Woman‬‬ ‫;‪else‬‬ ‫;"‪cout<<"man‬‬ ‫) ‪c) while ( z >= 0‬‬ ‫;‪sum += z‬‬ ‫)‪d‬‬ ‫‪// nested loop‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int j = 1‬‬ ‫)‪for( int i = 1 ; i<=3 ; i++‬‬ ‫{‬ ‫) ‪while( j<i‬‬ ‫{‬ ‫; " *"<< ‪cout‬‬ ‫;‪j++‬‬ ‫}‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫*‬ ‫*‬ ‫*‬ ‫*‬ ‫*‬

‫‪ .2‬اكتب برنامجا ٌقرأ ثبلثة أعداد ث ّم ٌر ّتبها تصاعدٌّا‪.‬‬ ‫‪ .6‬اكتب برنامجا لك ّل شكل من األشكال التالٌة‪:‬‬ ‫‪6‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬ ‫‪9‬‬

‫‪3 4 5‬‬ ‫‪4‬‬ ‫‪5‬‬ ‫‪6 7 8‬‬

‫‪5‬‬ ‫‪3 4 5 6‬‬ ‫‪4 5 6‬‬ ‫‪5 6‬‬ ‫‪6‬‬

‫‪4‬‬ ‫‪6‬‬ ‫‪6 7‬‬ ‫‪6 7 8‬‬ ‫‪6 7 8 9‬‬

‫‪3‬‬ ‫‪3 4 5 6‬‬ ‫‪5 6 7‬‬ ‫‪7 8‬‬ ‫‪9‬‬

‫‪2‬‬ ‫‪3‬‬ ‫‪4 5‬‬ ‫‪5 6 7‬‬ ‫‪6 7 8 9‬‬

‫‪1‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬ ‫‪9‬‬

‫‪5‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬

‫‪4‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪7‬‬

‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪ .5‬اكتب برنامجا ٌقرأ عددا ث ّم ٌحدد فٌما إذا كان ٌقبل القسمة على ‪ 12‬أو ال‪.‬‬ ‫‪ .4‬اكتب برنامجا لحساب العبلقة التالٌة‪:‬‬

‫‪67‬‬


‫‪ .7‬اكتب برنامجا لحساب وطباعة مجموع األعداد الزوجٌة القابلة للقسمة على ‪ 3‬ما بٌن ‪ 1‬و ‪.99‬‬ ‫‪ .8‬اكتب برنامجا لحساب المضاعف المشترك األصغر ‪ LCM‬لعددٌن مدخلٌن من لوحة المفاتٌح‪.‬‬ ‫بطرٌقتٌن مختلفتٌن‪.‬‬ ‫‪ .9‬اكتب برنامجا لحساب العبلقة التالٌة‬ ‫‪ .12‬اكتب برنامجا ٌطلب من المستخدم أن ٌدخل حرفا ث ّم عددا‪ ,‬ث ّم ٌقوم البرنامج بطباعة مثلث قابم‬ ‫ومتساوي الساقٌن من هذا الحرف وطول ساقه هو الرقم المدخل سابقا‪.‬‬ ‫‪ .11‬اكتب برنامجا ٌطلب من المستخدم إدخال عددٌن ث ّم ٌقوم بتقسٌم األوّ ل على الثانً )إذا كان العدد الثانً‬ ‫صفرا فإن البرنامج ٌطلب من المستخدم أن ٌعٌد إدخال الرقم الثانً من جدٌد(‪ ,‬ث ّم ٌخٌر المستخدم بٌن إجراء عملٌة‬ ‫والخروج من البرنامج )و ذلك بإدخال الحرف ‪.(e‬‬ ‫جدٌدة )وذلك بإدخال الحرف ‪(n‬‬ ‫ِ‬ ‫‪ .13‬اكتب برنامجا ٌطبع جمٌع قواسم عدد مدخل من لوحة المفاتٌح‪.‬‬

‫‪68‬‬


‫الفصل السابع ‪:‬‬

‫لعلّك تذكر برنامجك األوّ ل فً هذا الكتاب ‪ Hello World‬قلنا حٌنها‪" :‬إنّ النقطة األولى لبداٌة البرنامج هً‬ ‫التابع )(‪ ."main‬لكن ما هو التابع ولماذا نستخدمه؟‬ ‫التابع‪ :‬هو بنٌة برمجٌة ٌت ّم تنفٌذها عند استدعابه من أي نقطة فً البرنامج‪.‬‬ ‫ونستخدم التوابع أل ّنها تو ّفر الكثٌر من المزاٌا ومنها‪:‬‬ ‫‪ -2‬تختصر من طول البرنامج و تو ّفر الوقت‪ ,‬فبدال من إعادة كتابة ماسٌقوم به تابع ما ع ّدة مرّ ات فإ ّننا‬ ‫نكتبه مرّ ة واحدة فً تابع ث ّم نستدعً هذا التابع كلّما دعت إلٌه الحاجة‪.‬‬ ‫‪ -3‬تسهل قراءة البرنامج وتت ّبع األخطاء‪ ,‬أل ّنه من غٌر الج ٌّد أن تكتب برنامجك كلّه داخل التابع )(‪main‬‬ ‫فٌصبح متشابكا وتصعب قراء ُته‪.‬‬ ‫‪ -4‬تصوّ ر أ ّنك كتبت برنامجا استخدمت فٌه مجموعة من التعلٌمات ع ّدة مرّ ات ث ّم قرّ رت أن تح ِّسن من‬ ‫أداء هذه التعلٌمات أو أن تصحِّ ح خطؤ ما فٌها‪ ,‬فهل ستقوم بهذا التصحٌح من أجل كل مرّ ة كتبت فٌها‬ ‫تلك التعلٌمات‪ .‬ماذا لو استخدمت تابعا ٌقوم بهذه العملٌات ث ّم استدعٌته تلك المرّ ات العدٌدة؟ عندها‬ ‫سٌكون كافٌا أن تعدّل التابع مرّ ة واحدة فقط لٌسري هذا التعدٌل فً برنامجك كلّه دون عناء ٌذكر‪.‬‬ ‫وتشبه التوابع البرمجٌة الدوال الرٌاض ٌّة فً عملها إلى ح ٍّد ما‪ ,‬فهً تقوم بمجموعة من العملٌات ث ّم تعٌد قٌمة‬ ‫وحٌدة تدعى قٌمة التابع‪.‬‬ ‫كٌف نصرح عن التوابع؟ ٌتم التصرٌح عن التوابع وفقا للقاعدة التالٌة‪:‬‬ ‫)‪return_value_type function_name( argument1, argument2,.. .‬‬ ‫{‬ ‫;‪Statements‬‬ ‫‪...‬‬ ‫;‪return function_value‬‬ ‫}‬ ‫حٌث أن‪:‬‬ ‫‪ return_value_type ‬نوع القٌمة التً سٌعٌدها التابع‪.‬‬ ‫‪ function_name ‬اسم التابع‪ ,‬وبه ٌمكننا استدعاء التابع‪.‬‬ ‫َ‬ ‫ُعالجها وٌستخر َج القٌمة المطلوبة‪ ,‬وهذه‬ ‫‪ arguments ‬الوسطاء التً ٌت ّم تمرٌرها إلى التابع لٌ َ‬ ‫الوسطاء اختٌارٌّة أي أ ّنه ٌمكن االستغناء عنها كلِّها‪ ,‬ولكن ٌجب اإلبقاء على األقواس )( بعد اسم‬ ‫ٌسبق اس َمه نو ُع البٌانات التً ٌحملها كما لو كان متغٌّرا‪ّ .‬إال أ ّنه متغٌّر‬ ‫التابع‪ ,‬وكل وسٌط ٌجب أن ِ‬ ‫شكلًّ فقط‪ ,‬وعند استدعاء التابع سٌت ّم استبدال الوسطاء بمتغٌّرات أو ثوابت من نفس النوع‪ٌ .‬فصل بٌن‬ ‫كل وسٌطٌن متتابعٌن فاصلة من الشكل ) ‪.( ,‬‬ ‫‪ statements ‬هً التعلٌمات التً تشكل جسم التابع‪ .‬قد تكون مإلّفة من تعلٌمة واحدة أو أكثر وفً‬ ‫كلتً الحالتٌن ٌجب أن توضع بٌن القوسٌن } {‪ .‬تقوم هذه التعلٌمات بإٌجاد قٌمة التابع المطلوبة‪.‬‬ ‫‪ return function_value ‬هذه التعلٌمة تعٌد القٌمة التً حُسِ َب ْ‬ ‫ت فً جسم التابع‪ ,‬وهذه القٌمة وحٌدة‪.‬‬

‫‪69‬‬


‫تابع لنا فً هذا الكتاب‪:‬‬ ‫و اآلن لنكتب أوّ َل ٍ‬ ‫‪The result is 8‬‬

‫‪// function example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int addition (int a, int b‬‬ ‫{‬ ‫;‪int r = a + b‬‬ ‫;)‪return (r‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int z‬‬ ‫;)‪z = addition (5,3‬‬ ‫;‪cout << "The result is " << z‬‬ ‫;‪return 0‬‬ ‫}‬

‫أذ ُك ُر أ ّننا قلنا فً درسنا األول‪" :‬إنّ البرنامج ٌبدأ من التابع )(‪ main‬دابما"‪ .‬لذلك سنبدأ من هناك‪.‬‬ ‫تستطٌع أن ترى كٌف أن التابع )(‪ main‬بدأ بالتصرٌح عن المتغٌّر ‪ z‬من النوع الصحٌح‪ ,‬وبعد ذلك نجد التعلٌمة‬ ‫; )‪z = addition(5,3‬‬ ‫إنّ التعلٌمة السابقة ّ‬ ‫تمثل استدعاء للتابع ‪ addition‬ولو أ ّننا انتبهنا لوجدنا تشابها كبٌرا بٌن استدعاء التابع و‬ ‫التصرٌح عنه كما فً الشكل‪:‬‬ ‫)‪int addition(int a,int b‬‬ ‫;)‬

‫‪5 ,‬‬

‫‪3‬‬

‫(‪z = adition‬‬

‫حٌث ٌت ّم استبدال الوسٌطٌن الشكلٌ​ٌن ‪ a, b‬بالقٌمتٌن ‪ 5, 3‬على الترتٌب ث ّم ٌتوجّه المترجم إلى التابع ‪addition‬‬ ‫تاركا التعلٌمات التً لم ّ‬ ‫ٌنفذها بع ُد من التابع )(‪ٌ .main‬عرِّ ف التابع ‪ addition‬متغٌّرا موضعٌّا)انظر فقرة المدى‬ ‫فً نهاٌة الدرس( جدٌدا ‪ r‬ث ّم ٌسند إلٌه مجموع الوسٌطٌن ‪.a, b‬‬ ‫; ‪a + b‬‬

‫= ‪r‬‬

‫لكنّ ‪ a = 5, b = 3‬وبالنتٌجة فإنّ ‪ r = 8‬ث ّم ٌعٌد التابع القٌمة ‪ r‬باستخدام التعلٌمة ; ‪ return r‬أي أنّ قٌمة التابع‬ ‫هً العدد ‪ 9‬بعدها ٌخرج المترجم من التابع ‪ addition‬ث ّم ٌعود إلى التعلٌمة‬ ‫;)‪z = addition(5,3‬‬

‫وبما أنّ قٌمة التابع ‪ addition‬أصبحت ‪ 8‬فهذا ٌعنً أنّ ‪ z = 8‬أٌضا‪ .‬كما فً الشكل‪:‬‬ ‫)‪int addition(int a,int b‬‬ ‫;)‬

‫‪3‬‬

‫‪5 ,‬‬

‫(‪z = adition‬‬

‫ث ّم ٌكمل المترجم ما تبقى له من تعلٌمات التابع )(‪.main‬‬

‫‪6:‬‬


‫مثال‪:‬‬ ‫‪5‬‬ ‫‪5‬‬ ‫‪2‬‬ ‫‪6‬‬

‫‪is‬‬ ‫‪is‬‬ ‫‪is‬‬ ‫‪is‬‬

‫‪result‬‬ ‫‪result‬‬ ‫‪result‬‬ ‫‪result‬‬

‫‪1st‬‬ ‫‪2nd‬‬ ‫‪3rd‬‬ ‫‪4th‬‬

‫‪The‬‬ ‫‪The‬‬ ‫‪The‬‬ ‫‪The‬‬

‫‪// function example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int sub(int a, int b‬‬ ‫{‬ ‫;)‪return (a-b‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int x=5, y=3, z‬‬ ‫;)‪z = sub(7,2‬‬ ‫;'‪cout<<"The 1st result is "<<z<<'\n‬‬ ‫;'‪cout<<"The 2nd result is "<<sub(7,2)<<'\n‬‬ ‫;'‪cout<<"The 3rd result is "<<sub(x,y)<<'\n‬‬ ‫;)‪z = 4 + sub(x,y‬‬ ‫;'‪cout << "The 4th result is " << z << '\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫التوابع التً ال تعٌد قٌمة (استخدام الكلمة ‪)void‬‬ ‫فً بعض األحٌان نحتاج إلى تابع ٌقوم بمجموعة من األشٌاء دون أن ٌعٌد قٌمة أو قد نرٌد منه أن ٌعٌد أكثر من‬ ‫قٌمة لكن وكما تعلّمنا فالتابع ٌجب أن ٌعٌد قٌمة وهذه القٌمة وحٌدة لذلك كان الحل باستخدام الطرق )الطرق‬ ‫‪ methods‬هو االسم الذي تستخدمه لغة ‪ java‬لتع ّبر به عن التوابع التً ال تعٌد قٌما(‪ .‬لكن ماهو الفرق؟ فً‬ ‫واقع األمر تشبه الطرٌقة التابع فً كل شًء ّإال أ ّنها ال تملك نوعا من البٌانات أل ّنها باألصل ال تعٌد قٌمة‪.‬‬ ‫ٌت ّم التصرٌح عن الطرٌقة بنفس األسلوب الذي صرّ حنا به عن التابع مع اختبلفٌن بسٌطٌن هما‪:‬‬ ‫‪ -1‬لن نضع نوعا للبٌانات وبدال من ذلك سنستخدم الكلمة ‪ void‬داللة على أنّ الطرٌقة التالٌة لن تعٌد شٌبؤ‪.‬‬ ‫‪ -2‬بما أنّ الطرٌقة ال تعٌد أي قٌمة فبل داعً ألن نضع التعلٌمة ‪ return‬فً نهاٌتها‪.‬‬ ‫وبذلك ٌكون شكل الطرٌقة كاآلتً‪:‬‬ ‫) ‪void method_name( void‬‬ ‫{‬ ‫; ‪statements‬‬ ‫‪. . ..‬‬ ‫}‬

‫مثال‪:‬‬ ‫!‪I'm a function‬‬

‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪void dummyfunction (void‬‬ ‫{‬ ‫;"‪cout << "I'm a function!\n‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫; )(‪dummyfunction‬‬ ‫;‪return 0‬‬ ‫}‬

‫مالحظة ‪ :‬فً ‪ C++‬عندما نصرّ ح عن تابع أو طرٌقة دون وسطاء فلٌس من الضروري استخدام‬ ‫الكلمة ‪ void‬بٌن القوسٌن )( لك ّننا نضعها لنشٌر إلى أنّ التابع ال ٌمتلك وسطاء‪.‬‬ ‫وممّا ٌجب علٌك أن تنتبه إلٌه عندما تستدعً أيّ تابع هو استخدام القوسٌن )( بعد اسم التابع‬ ‫ح ّتى ولو لم ٌمتلك وسطاء‪.‬‬

‫‪71‬‬


‫تمرٌر الوسطاء بالقٌمة و بالمرجع(العنوان)‬

‫فً األمثلة السابقة قمنا بتمرٌر الوسطاء بالقٌمة وهذا ٌعنً أ ّننا عندما نستدعً تابعا ذا وسطاء بالقٌمة فإ ّننا نمرّ ر‬ ‫قٌم المتغ ٌّرات إلى التوابع وال نمرّ ر المتغٌّرات نفسها‪ .‬كمثال افترض أ ّننا استدعٌنا التابع ‪ addition‬فً المثال‬ ‫األول كاآلتً‪:‬‬ ‫; ‪int x = 5 , y = 3 , z‬‬ ‫; )‪z = addition(x,y‬‬

‫ما فعلناه هنا هو أ ّننا استدعٌنا التابع ‪ addition‬ومرّ رنا إلٌه قٌمتً المتغٌّرٌن ‪ x‬و ‪ y‬أي أ ّننا م ّررنا إلٌه الرقمٌن‬ ‫‪ 5‬و ‪ 3‬ولم نم ّرر إلٌه المتغٌّرٌن ‪ x‬و ‪ .y‬كما فً الشكل‪.‬‬ ‫)‪int addition(int a,int b‬‬ ‫‪3‬‬

‫;)‬

‫‪5‬‬

‫‪x ,‬‬

‫‪y‬‬

‫(‪z = adition‬‬

‫إنّ استدعاء الوسطاء بالقٌمة ٌمنع حدوث أي تغٌ​ٌر على المتغٌّر الذي ت ّم تمرٌره إلى التابع خارج هذا التابع‬ ‫ولتوضٌح هذه المسؤلة نقدّم هذا المثال‪:‬‬ ‫‪// passing by values‬‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int add(int a,int b‬‬ ‫{‬ ‫;‪int result = a + b‬‬ ‫‪a--; b++; //changeing values of a and b‬‬ ‫;‪return result‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪int a=5,b=3,z‬‬ ‫;‪cout<<"a and b before calling add function is: "<<a<<", "<<b<<endl‬‬ ‫;)‪z = add(a,b‬‬ ‫;‪cout<<"value of add function is: "<<z<<endl‬‬ ‫;‪cout<<"a and b after calling add function is: "<<a<<", "<<b<<endl‬‬ ‫;‪return 0‬‬ ‫}‬ ‫‪a and b before calling add function is: 5, 3‬‬ ‫‪value of add function is: 8‬‬ ‫‪a and b after calling add function is: 5, 3‬‬

‫لعلّك الحظت أنّ قٌمتً المتغٌّرٌن ‪ a‬و ‪ b‬لم تتغٌّرا فً التابع)(‪ main‬ح ّتى بعد استدعاء التابع‬ ‫‪ addition‬الذي قام بالتعدٌل على الوسٌطٌن ‪ a‬و ‪ b‬المعرّ فٌن فٌه والذٌن تغٌّرت قٌمتاهما كما هو واضح فً‬ ‫نتٌجة البرنامج السابق‪ .‬لكن ماذا لو أردنا أن تتغٌر قٌم المتغ ٌّرات عند تمرٌرها إلى تابع ما؟ عندها لن ٌكون‬ ‫تمرٌرها بالقٌمة مجدٌا وٌتح ّتم علٌنا عندب ٍذ أن نم ّررها بالمرجع )العنوان(‪.‬‬ ‫عندما نم ّرر متغٌّرا ما بالمرجع إلى أحد التوابع فإ ّننا ال نمرّر قٌمته وحسب بل نمرّر المتغٌّر نفسه أي أنّ أيّ‬ ‫تغٌ​ٌر على المتغٌّر الوسٌط فً التابع س ٌَحْ ُد ُ‬ ‫ث على المتغٌّر ح ّتى خارج هذا التابع‪.‬‬ ‫وٌت ّم االستدعاء بالمرجع من خبلل استخدام المعامل & بعد نوع الوسٌط الذي نرغب بتمرٌره بالمرجع فً جسم‬ ‫التابع كما فً الشكل‪:‬‬ ‫)‪void duplicate (int& a, int& b, int& c‬‬

‫‪z‬‬ ‫) ‪z‬‬

‫‪y‬‬ ‫‪,‬‬

‫‪x‬‬ ‫‪y‬‬

‫‪,‬‬

‫‪x‬‬

‫( ‪duplicate‬‬

‫‪72‬‬


:‫المثال التالً ٌوضح ذلك‬ // passing parameters by reference #include <iostream> using namespace std; void duplicate (int& a, int& b, int& c) { a*=2; b*=2; c*=2; } int main () { int x=1, y=3, z=7; cout<<"x,y,z before calling duplicate"; cout <<"\nx="<<x<<", y=" << y <<", z=" <<z<<endl; duplicate (x, y, z); cout<<"x,y,z after calling duplicate\n"; cout <<"x="<<x<<", y=" << y <<", z=" <<z<<endl; return 0; }

x,y,z before calling duplicate x=1, y=3, z=7 x,y,z after calling duplicate x=2, y=6, z=14

‫ أ ُ ْت ِب َع نوعُه بالرمز & الذي ٌعنً أنّ هذا الوسٌط‬duplicate ‫ٌجب أن تنتبه إلى أنّ ك ّل وسٌط فً التابع‬ .‫سٌمرّ ر بالمرجع و لٌس بالقٌمة كما فً الحالة األولى‬ ‫ ولكنّ تمرٌر الوسطاء‬,‫كما قلنا فً بداٌة هذا الدرس إنّ التوابع تعٌد قٌمة وحٌدة بٌنما ال تعٌد الطرق أ ٌّة قٌمة‬ .‫بالمرجع ٌع ّد أداة قوٌة تستطٌع من خبللها أن تجعل التابع )الطرٌقة( ٌعٌد أكثر من قٌمة‬ :‫والمثال التالً ٌوضّح هذا‬ ‫ الذي ٌقبل ثبلثة وسطاء حٌث ٌؤخذ الوسٌط األوّ ل وٌعٌد الرقم الذي ٌسبقه كقٌمة له من‬prevnext ‫لدٌنا التابع‬ .‫خبلل الوسٌط الثانً كما ٌعٌد الرقم الذي ٌلً الوسٌط األول كقٌمة له من خبلل الوسٌط الثالث‬ // more than one returning value #include <iostream> using namespace std; void prevnext (int x,int& prev, int& next) { prev = x-1; next = x+1; } int main () { int x=100, y, z; prevnext (x, y, z); cout<<"Previous=" << y << ", Next="<< z << endl; return 0; }

Previous=99, Next=101

:‫ بالشكل‬prevnext ‫ ٌمكنك كتابة التابع‬: ‫مالحظة‬ int prevnext (int x,int& prev, int& next) { prev = x-1; next = x+1; return 0;}

73


‫المدى ‪Scope‬‬ ‫ك ّل المتغٌّرات التً سنستخدمها فً برامجنا ٌجب أن ٌت ّم التصرٌح عنها أوال‪ٌ .‬مكن التصرٌح عن المتغٌّرات فً‬ ‫ُعرفُ بمجال الرإٌا‬ ‫أيّ مكان من صفحة الشٌفرة‪ .‬لكنْ هناك شٌا ٌجب أن تعلمه عزٌزي القارئ‪ ,‬وهو ما ٌ َ‬ ‫للمتغٌّر )المدى(‪ .‬تابع الشكل التالً أوال‪:‬‬

‫‪Global Variables‬‬

‫‪Local Variables‬‬ ‫متغيراث موضعيت‬

‫‪Instructions‬‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫; ‪int Integer‬‬ ‫; ‪char aCharacter‬‬ ‫; ]‪char string[20‬‬

‫)(‪int main‬‬ ‫{‬ ‫; ‪unsigned short Age‬‬ ‫; ‪float ANumber , AnotherOne‬‬ ‫;" ‪cout << "Enter Your age:‬‬ ‫;‪cin >> Age‬‬ ‫…‬ ‫; ‪return 0‬‬ ‫}‬

‫المتغ ٌّرات الشاملة ‪ Global variables‬و المتغ ٌّرات الموضع ٌّة ‪:Local variables‬‬ ‫المتغ ٌّرت الشاملة هً المتغٌّرات التً ٌُصرّ ح عنها أعلى البرنامج خارج كل التوابع كما هو واضح فً الشكل‬ ‫السابق فالمتغٌّرات ]‪ Integer , aCharacter , string [20‬كلّها متغٌّرات شاملة‪.‬‬ ‫ٌمكن الوصول إلى هذه المتغٌّرات من أي مكان داخل الشٌفرة‪ ,‬و من أي تابع أو‬ ‫البرنامج‪.‬‬

‫طرٌقة(إجراء)‬

‫معرّ فة فً‬

‫صرح عنها داخل القوسٌن‬ ‫وهذا ماال تستطٌع المتغٌّرات الموضعٌّة أن تفعله‪ ,‬والمتغ ٌّرات الموضع ٌّة هً التً ٌ ّ‬ ‫}{ لتابع أو إجراء أو بنٌة برمجٌة ما فً البرنامج‪.‬‬ ‫فً الشكل السابق المتغٌّرات ‪ Age , ANumber , AnotherOne‬صُرِّ ح عنها فً جسم التابع )(‪ main‬أي‬ ‫أ ّننا قادرون على الوصول إلٌها من داخل التابع )(‪ main‬فقط‪ .‬وهذا ٌعنً أ ّنه لن ٌكون بمقدورنا أن نصل إلى‬ ‫أحد هذه المتغٌّرات من أي تابع آخر مع ّرف فً البرنامج‪.‬‬ ‫فً ‪ C++‬المدى للمتغٌّر الموضعًّ محدّد فقط فً البنٌة البرمجٌة التً صُرِّ َح عنه فٌها‬ ‫ف فٌه‪ ,‬ولو أ ّنه‬ ‫مجموعة التعلٌمات المحصورة بٌن القوسٌن }{) أي لو أ ّنه عُرِّ ف ضمن التابع فإنّ مداه هو التابع الذي عُرِّ َ‬ ‫ف ضمن إحدى البنى التكرارٌة فإنّ مداه هو تلك البنٌة التكرارٌّة وحسب‪.‬‬ ‫عُرِّ َ‬

‫(البنٌة البرمجٌة المقصودة هً‬

‫مالحظة ‪ :‬المتغٌرات الشاملة تتم تبدأتها مع بداٌة البرنامج قبل التابع ‪ main‬بشكل تلقابً‬ ‫إلى القٌم الصفرٌة لكل نوع فمثبل المتغٌر ‪ٌ Integer‬ؤخذ القٌمة ‪ 1‬تلقابٌا‬ ‫)جرّ ب أن تطبع قٌم المتغٌرات الشاملة من المثال السابق ستجد أن المتغٌرات الحرفٌة‬ ‫تطبع فراغات )أو ال تطبع شٌبا(( أمّا المتغٌرات الموضعٌة فٌت ّم تبدأتها عندما ٌصل المترجم‬ ‫إلى مكان التصرٌح عنها وهً تأخذ قٌما ا عشوائٌة بشكل تلقائً ما لم تقم بتبدئتها بنفسك‪.‬‬

‫‪74‬‬


‫المتغٌرات الثابتة ‪static‬‬ ‫هذا النوع من المتغٌرات تت ّم تبدأته مرة واحدة فقط وٌمكن أن تتغٌر قٌمته )ٌوجد منه نسخة واحدة فقط(‬ ‫مثال‪:‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬

‫==‬ ‫==‬ ‫==‬ ‫==‬

‫‪x‬‬ ‫‪x‬‬ ‫‪x‬‬ ‫‪x‬‬

‫‪,‬‬ ‫‪,‬‬ ‫‪,‬‬ ‫‪,‬‬

‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬

‫==‬ ‫==‬ ‫==‬ ‫==‬

‫‪// Example static variables‬‬ ‫>‪#include <iostream.h‬‬ ‫)‪void f(int a‬‬ ‫{‬ ‫)‪while(a-- != 0‬‬ ‫{‬ ‫‪static int n = 0 ;// initialized once‬‬ ‫; ‪int x = 0‬‬ ‫‪// initialized n times‬‬ ‫;"‪cout<<"n == "<<n++<<", x == "<<x++<<"\n‬‬ ‫}‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;)‪f(4‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪n‬‬ ‫‪n‬‬ ‫‪n‬‬ ‫‪n‬‬

‫تعٌ​ٌن القٌمة االفتراضٌة للوسطاء‬

‫عندما نصرّ ح عن متغٌّر فإ ّننا نستطٌع أن نعطٌه قٌمة ابتدابٌة ث ّم قد نرغب بتغٌ​ٌر قٌمته فٌما بعد أثناء البرنامج‬ ‫لكن هل نستطٌع أن نعطً قٌمة ابتدائٌة لوسٌط معرف داخل تابع ما؟‬ ‫ال تتعجّ ب إن ُ‬ ‫قلت لك‪" :‬نعم"‪ .‬فً الحقٌقة ٌع ّد هذا ممكنا من أجل ك ّل وسٌط ترٌد أن تعطٌه قٌمة ابتدابٌة لتكون‬ ‫قٌم َته االفتراضٌة فً حال لم تقم بوضع أيّ قٌمة فً مكان هذا الوسٌط عند استدعاء التابع‪ ,‬ولكن لو قمت بوضع‬ ‫قٌمة أخرى أثناء استدعاء التابع فسٌعتبر المترجم أنّ قٌمة الوسٌط هً القٌمة التً أدخلتها عند استدعاء التابع‬ ‫وسٌتجاهل القٌمة االفتراضٌة تلك‪.‬‬ ‫مثال‪:‬‬ ‫‪6‬‬ ‫‪5‬‬

‫‪// default values in functions‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int divide (int a, int b=2‬‬ ‫{‬ ‫;‪int r‬‬ ‫;‪r=a/b‬‬ ‫;)‪return (r‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;)‪cout << divide (12‬‬ ‫;‪cout << endl‬‬ ‫;‪cout << divide (20,4)<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫كما ترى فإنّ ناتج التعلٌمة )‪ divide(12‬هو العدد ‪ 4‬أل ّننا لم نضع قٌمة للوسٌط الثانً ‪ b‬الذي ٌؤخذ القٌمة‬ ‫‪ 3‬كقٌمة افتراضٌة له لذلك فإنّ ‪divide(12) = 12 / 2 = 6‬‬ ‫أمّا فً الحالة الثانٌة فقد استدعٌنا التابع بالشكل )‪ divide(20,4‬أي أ ّننا طلبنا منه أن ٌغٌّر القٌمة‬ ‫االفتراضٌة للوسٌط ‪ b‬لتصبح العدد ‪ 6‬وعندها ٌكون الناتج ‪.divide(20,4) = 20 / 4 = 5‬‬

‫‪75‬‬


‫إعادة تحمٌل التوابع ‪functions overloading‬‬

‫لو كان لدٌنا تابعان ٌقومان بنفس التعلٌمات تماما وٌمتلكان نفس االسم أٌضا لك ّنهما ٌختلفان عن بعضٌهما‬ ‫ُعرفُ بإعادة التحمٌل‬ ‫بالوسطاء وهذا االختبلف قد ٌكون فً األنواع أو فً عدد الوسطاء المطلوبة‪ ,‬فهذا ما ٌ َ‬ ‫التوابع‪.‬‬ ‫وإلٌك المثال التالً‪:‬‬ ‫‪2‬‬ ‫‪2.5‬‬

‫‪//overloaded function‬‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int divide (int a, int b‬‬ ‫} ;)‪{ return (a/b‬‬ ‫)‪float divide (float a, float b‬‬ ‫} ;)‪{ return (a/b‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int x=5,y=2‬‬ ‫;‪float n=5.0,m=2.0‬‬ ‫;)‪cout << divide (x,y‬‬ ‫;"‪cout << "\n‬‬ ‫;)‪cout << divide (n,m‬‬ ‫;"‪cout << "\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫ٌستطٌع المترجم أن ٌحدّد أيّ التابعٌن سٌستخدم من خبلل نوع االوسطاء التً س ُتمرِّ رُها فإذا كانت أعدادا‬ ‫صحٌحة سٌستدعً التابع المعرّ ف أوّ ال والذي ٌقبل وسطاء من النوع ‪ int‬وإذا كانت الوسطاء من النوع‬ ‫‪ float‬عندها سٌستخدم التابع الثانً‪.‬‬ ‫ٌفٌدنا هذا األسلوب فً التقلٌل من أسماء التوابع التً سنستخدمها فً برنامجنا‪ ,‬فطالما أنّ هذه التوابع تقوم بنفس‬ ‫العمل‪ ,‬فلِم ال تؤخذ نفس االسم‪.‬‬

‫التعرٌف المبدئً للتوابع ‪functions prototype‬‬

‫ح ّتى اآلن ك ّل التوابع التً قمنا بكتابها صرّ حنا عنها فوق التابع ‪ main‬لكً نستطٌع استدعاءها فً التابع‬ ‫)(‪ , main‬لكن ماذا لو أردنا أن نكتب تابعا ا ما تحت التابع )(‪main‬؟‬ ‫ٌمكننا فعل ذلك ولكن باستخدام الطرٌقة التالٌة‪:‬‬ ‫نصرّ ح عن التابع فً أعلى البرنامج قبل التابع )(‪ main‬بالشكل التالً‪:‬‬ ‫;)‪data_type function_name (argument_type1, argument_type2...‬‬ ‫مع مراعاة األمور التالٌة‪:‬‬ ‫‪ٌ ‬جب ّأال تكتب أٌّة تعلٌمة من جسم التابع فً هذا التصرٌح‪.‬‬ ‫‪ٌ ‬جب أن تضع فاصلة منقوطة فً نهاٌة هذا التصرٌح‪.‬‬ ‫‪ٌُ ‬كتفى بوضع أنواع البٌانات للوسطاء دون أسمابها‪ ,‬وٌع ّد كتابة األسماء أمرا اختٌارٌا وهو األفضل‪.‬‬ ‫ث ّم تحت التابع )(‪ main‬نقوم بكتابة جسم التابع‪.‬‬

‫‪76‬‬


:‫مثال‬ // prototyping #include <iostream> using namespace std; void odd (int a); void even (int a); int main () { int i; do { cout << "Type a number(0 to exit): "; cin >> i; odd (i); } while (i!=0); return 0; } void odd (int a) { if ((a%2)!=0) cout<<"Number is odd.\n"; else even (a); } void even (int a) { if((a%2)==0) cout <<"Number is even.\n"; else odd (a); }

77

Type a Number Type a Number Type a Number Type a Number

number (0 is odd. number (0 is even. number (0 is even. number (0 is even.

to exit): 9 to exit): 6 to exit): 1030 to exit): 0


‫الفصل الثامن‪:‬‬

‫التعاود ٌّة‪ :‬هً خاصٌّة ٌستطٌع التابع من خبللها أن ٌستدعً نفسه‪.‬‬ ‫وتستخدم هذه الطرٌقة لحل المشاكل التً ٌمكن ردّها إلى مشكلة واحدة مكرّ رة عدّة مرّ ات‪ ,‬و ٌعتبر هذا األسلوب‬ ‫مفٌدا من أجل بعض طرق الترتٌب أو لحساب عاملً عدد ما !‪ n‬والذي ٌعطى بالعبلقة التالٌة‪:‬‬ ‫وٌُصطلح على أنّ ‪:‬‬ ‫لو تؤملنا العبلقة ج ٌّدا سنجد أ ّنها تكتب أٌضا بالشكل التالً‪:‬‬ ‫وكمثال لنؤخذ الرقم ‪ 6‬ونحسب العاملً له‪:‬‬ ‫‪= 24‬‬

‫)‪1‬‬

‫‪2.‬‬

‫‪(3.‬‬

‫‪4! = 4.‬‬

‫أو‬ ‫‪2! = 4. 3. 2. 1! = 24‬‬ ‫واآلن سنكتب برنامجا ٌستخدم تابعا تعاود ٌّا لح ّل هذه المشكلة‪:‬‬ ‫‪Type a number: 4‬‬ ‫‪4! = 732‬‬

‫‪3.‬‬

‫‪3! = 4.‬‬

‫‪4.‬‬

‫= !‪4‬‬

‫‪// factorial calculator‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪long fact(long n‬‬ ‫{‬ ‫)‪if (n > 1‬‬ ‫!)‪return (n * fact(n-1)); // n.(n-1‬‬ ‫‪else‬‬ ‫;)‪return (1‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪long m‬‬ ‫;" ‪cout << "Type a number:‬‬ ‫;‪cin >> m‬‬ ‫;‪cout<<"\n"<<m<<"! = "<<fact(m)<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫لعلّك الحظت أنّ التابع ‪ fact‬قام باستدعاء نفسه من خبلل التعلٌمة ))‪return (n * fact(n-1‬‬ ‫وهذا ما ٌُعرف بالتعاودٌّة‪ .‬والمقصود بهذا أنّ التابع لن ٌكمل تنفٌذ التعلٌمات الموجودة بعد هذه التعلٌمة وإ ّنما‬ ‫لٌستدعً نفسه من جدٌد‪ ,‬وذلك ألنّ قٌمة االستدعاء األوّ ل مرتبطة باستدعاء جدٌد للتابع نفسه وقٌمة هذا‬ ‫سٌعود‬ ‫َ‬ ‫االستدعاء الجدٌد مرتبطة باستدعاء آخر سٌتحقق بمجرّ د وصول المترجم إلى نفس السطر من االستدعاء الذي‬ ‫ٌنفذه حالٌا وتستمر هذه ْ‬ ‫الحلقة من االستدعاءات المترابطة مع بعضها وٌستمر المترجم بحجز أماكن جدٌدة من‬ ‫الذاكرة لكل المتغٌّرات الموجودة فً التابع المُس َت ْدعى ولكن إلى متى؟‬

‫‪78‬‬


‫ٌعتبر شرط التوقف الذي ٌجب أن تضعه فً التابع أه ّم ما ٌجب علٌك فعله أل ّنك لو لم تفعل فإنّ البرنامج سٌدخل‬ ‫فً حلقة تعاودٌّة النهابٌّة نتٌجتها تو ّقف البرنامج بخطؤ من النوع ‪.stack overflow‬‬ ‫شرط التوقف هو شرط ٌإدّي تح ّققه إلى تنفٌذ تعلٌمة ال تحتوي على استدعاء جدٌد للتابع ومن المه ّم أن ٌكون‬ ‫هذا الشرط قاببل للتح ّقق لكً ٌتوقف التابع عن استدعاء نفسه ّ‬ ‫وإال فلٌس لهذا الشرط أٌّة قٌمة‪ .‬فً مثالنا السابق‬ ‫الجزء الثانً من تعلٌمة الشرط هو شرط التوقف‪ .‬اآلن لنعد إلى برنامجنا السابق ولندخل عالم التعاودٌّة الملًء‬ ‫بالمغامرات‪.‬‬ ‫التابع ‪ fact‬من أجل القٌمة ‪5‬‬

‫التابع ‪ fact‬من أجل القٌمة ‪3‬‬ ‫‪fact(3) :‬‬ ‫‪3 > 1 ? yes‬‬ ‫)‪fact(3) = 3 * fact(2‬‬ ‫‪fact(2) :‬‬ ‫‪2 > 1 ? yes‬‬ ‫)‪fact(2) = 2 * fact(1‬‬ ‫‪fact(1) :‬‬ ‫‪1 > 1 ? no‬‬ ‫‪return 1‬‬ ‫‪fact(2) = 2 * 1 = 2‬‬ ‫‪return 2‬‬ ‫‪fact(3) = 3 * 2 = 6‬‬ ‫‪return 6‬‬

‫كما تبلحظ ُتحسب قٌم ُة االستدعاء األخٌر أوّ ال ث ّم الذي قبله ث ّم الذي قبله ح ّتى ٌصل إلى االستدعاء األوّ ل مجسدا‬ ‫بذلك فكرة المكدّس ‪ stack‬وهً تقول‪" :‬آخ ُر الداخلٌن هو أوّ ل الخارجٌن )‪."(Last in first out‬‬ ‫هل ٌجب علٌنا أن نستخدم هذا األسلوب دائماا؟ فً الحقٌقة إنّ استخدام هذا األسلوب مرب ٌ‬ ‫ك كثٌرا وٌكمن البدٌل‬ ‫فً استخدام البنى التكرارٌّة‪ ,‬فالقاعدة تقول‪" :‬البرنامج الذي ٌمكن كتابته بشكل تعاوديّ ٌمكن كتابته بشكل‬ ‫تكراري وهذا أفضل وأسرع"‪ .‬لنكتب المثال السابق بشكل تكراري‪:‬‬ ‫‪Type a number: 9‬‬ ‫‪9! = 362880‬‬

‫‪// factorial calculator‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪long fact(int a‬‬ ‫{‬ ‫;‪long f = 1‬‬ ‫)‪for(int i = a ; i>0 ; i--‬‬ ‫;‪f *= i ; //or f = f * i‬‬ ‫; ‪return f‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪long l‬‬ ‫;" ‪cout << "Type a number:‬‬ ‫;‪cin >> l‬‬ ‫;)‪cout << "\n" << l << "! = " << fact(l‬‬ ‫;‪cout<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪79‬‬


‫‪ :‬اكتب التابع ‪ fact‬باستخدام الحلقتٌن التكرارٌتٌن الباقٌتٌن‪.‬‬ ‫مثال‪ :‬اٌجشٔبِظ اٌزبٌ‪٠ ٟ‬م‪ َٛ‬ثؾغبة ِغّ‪ٛ‬ع اٌغٍغٍخ اٌّى‪ٔٛ‬خ ِٓ األػذاد اٌطج‪١‬ؼ‪١‬خ ثبٌشىً‪:‬‬

‫‪Enter n: 4‬‬ ‫‪sum(4) = 10‬‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int sum(int n‬‬ ‫{‬ ‫)‪if ( n > 1‬‬ ‫;)‪return n+sum(n-1‬‬ ‫‪else‬‬ ‫;‪return 1‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫; ‪int n‬‬ ‫;" ‪cout<< "Enter n:‬‬ ‫;‪cin>> n‬‬ ‫;‪cout << "\nsum(" << n << ")= " << sum(n) << endl‬‬ ‫}‬ ‫‪sum(3) :‬‬ ‫‪3 > 1 ? yes‬‬ ‫)‪sum(3) = 3 + sum(2‬‬ ‫‪sum(2) :‬‬ ‫‪2 > 1 ? yes‬‬ ‫)‪sum(2) = 2 + sum(1‬‬ ‫‪sum(1) :‬‬ ‫‪1 > 1 ? no‬‬ ‫‪return 1‬‬ ‫‪sum(2) = 2 + 1 = 3‬‬ ‫‪return 3‬‬ ‫‪sum(3) = 3 + 3 = 6‬‬ ‫‪return 6‬‬

‫سلسلة فٌبوناكسً ‪:Fibonacci numbers‬‬ ‫عٕىزت ربثؼب ً رؼب‪ٚ‬د‪ّ٠‬ب ً إل‪٠‬غبد األسلبَ اٌزبٌ‪١‬خ‪:‬‬

‫‪0, 1, 1, 2, 3, 5, 8, 13, 21, 34,.. .‬‬

‫ؽ‪١‬ش ّ‬ ‫أْ اٌشلُ األوجش ِٓ ‪ٕ٠ 1‬زظ ِٓ ِغّ‪ٛ‬ع اٌشلّ‪ ٓ١‬اٌز‪٠ ٓ٠‬غجمبٔٗ ‪ٚ‬فك اٌؼاللبد اٌزبٌ‪١‬خ‪:‬‬ ‫‪fib(0) = 0, fib(1) = 1‬‬ ‫‪fib(n) = fib(n-1) + fib(n-2) :n>1.‬‬ ‫‪٘ٚ‬زٖ اٌغٍغٍخ رؼط‪ ٟ‬إٌغجخ اٌز٘ج‪١‬خ اٌز‪ ٟ‬ر‪ٛ‬عذ ثىضشح ف‪ ٟ‬اٌطج‪١‬ؼخ ‪ ٟ٘ٚ‬رٕزظ ِٓ اٌمغّخ‬ ‫‪ ٟ٘ٚ‬اٌّغزخذِخ ف‪ ٟ‬ئٔشبء إٌ‪ٛ‬افز ‪ ٚ‬اٌغشف ‪ ٚ‬اٌّجبٔ‪ ٟ‬ؽ‪١‬ش رّضً ٔغجخ اٌط‪ٛ‬ي ئٌ‪ ٝ‬اٌؼشع‪.‬‬

‫‪7:‬‬


#include<iostream> using namespace std; int fib(int n) { if ( n == 0 || n == 1 ) return n; else return (fib(n-1)+fib(n-2)); } int main() { int n ; cout<< "Enter n: "; cin>> n; cout<< "\nfib(" << n << ") = " << fib(n) << endl; }

1- fib(4): 4 ?= 0 no, or 4 ?= 1 no fib(4) = fib(3) + fib(2) 2- fib(3): 3 ?= 0 no, or 3 ?= 1 no fib(3) = fib(2) + fib(1) 3- fib(2): 2 ?= 0 no, or 2 ?= 1 no fib(2) = fib(1) + fib(0) 4- fib(1): 1 ?= 0 no, or 1 ?= 1 yes fib(1) = 1 return fib(1) 5- fib(0): 0 ?= 0 yes, or 0 ?= 1 no fib(0) = 0 return fib(0) fib(2) = 1 + 0 return fib(2) fib(3) = 1 + fib(1) 6- fib(1): 1 ?= 0 no, or 1 ?= 1 yes fib(1) = 1 return fib(1) fib(3) = 1 + 1 = 2 return fib(3) fib(4) = 2 + fib(2)

81

Enter n: 4 fib(4) = 3


7- fib(2): 2 ?= 0 no, or 2 ?= 1 no fib(2) = fib(1) + fib(0) 8- fib(1): 1 ?= 0 no, or 1 ?= 1 yes fib(1) = 1 return fib(1) 9- fib(0): 0 ?= 0 yes, or 0 ?= 1 no fib(0) = 0 return fib(0) fib(2) = 1 + 0 return fib(2) fib(4) = 2 + 1 = 3

82


‫‪ .1‬ماهو ناتج تنفٌذ التوابع التالٌة‪:‬‬ ‫‪C‬‬

‫‪B‬‬

‫‪A‬‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int sum(int a‬‬ ‫{‬ ‫)‪if(a>1‬‬ ‫;)‪return a+sum(a-1‬‬ ‫)‪else if(a==1‬‬ ‫;‪return a‬‬ ‫;‪else return 0‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪cout<<sum(5)<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int sum(int a‬‬ ‫{‬ ‫)‪if(a>1‬‬ ‫;)‪return a+sum(a--‬‬ ‫)‪else if(a==1‬‬ ‫;‪return a‬‬ ‫;‪else return 0‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪cout<<sum(5)<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int sum(int a‬‬ ‫{‬ ‫)‪if(a>1‬‬ ‫;)‪return a+sum(--a‬‬ ‫)‪else if(a==1‬‬ ‫;‪return a‬‬ ‫;‪else return 0‬‬ ‫}‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪cout<<sum(5)<<endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪C‬‬ ‫ٌطبع القٌمة ‪15‬‬

‫‪B‬‬ ‫ٌحدث خطؤ من النوع‬ ‫‪stack overflow‬‬

‫‪A‬‬ ‫ٌطبع القٌمة ‪11‬‬

‫=‪sum‬‬ ‫‪15‬‬ ‫‪+‬‬ ‫‪12‬‬ ‫‪+‬‬ ‫‪4‬‬ ‫‪+‬‬ ‫‪2‬‬ ‫‪+‬‬ ‫‪1‬‬

‫‪C‬‬ ‫=‪a‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪1‬‬

‫االستدعاء‬ ‫‪1‬‬ ‫‪3‬‬ ‫‪2‬‬ ‫‪6‬‬ ‫‪5‬‬

‫=‪sum‬‬ ‫‪not‬‬ ‫‪calculated‬‬ ‫‪not‬‬ ‫‪calculated‬‬ ‫‪not‬‬ ‫‪calculated‬‬ ‫‪not‬‬ ‫‪calculated‬‬ ‫‪not‬‬ ‫‪calculated‬‬

‫‪B‬‬ ‫=‪ a‬االستدعاء‬ ‫‪1‬‬ ‫‪5‬‬ ‫‪3‬‬ ‫‪5‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪5‬‬ ‫‪...‬‬ ‫‪...‬‬

‫=‪sum‬‬ ‫‪11‬‬ ‫‪+ 7‬‬ ‫‪+ 6‬‬ ‫‪+ 3‬‬ ‫‪+ 1‬‬

‫‪A‬‬ ‫=‪ a‬االستدعاء‬ ‫‪1‬‬ ‫‪5‬‬ ‫‪3‬‬ ‫‪6‬‬ ‫‪2‬‬ ‫‪2‬‬ ‫‪6‬‬ ‫‪3‬‬ ‫‪5‬‬ ‫‪1‬‬

‫الحالة ‪ A‬نجد التعلٌمة ;)‪ return a+sum(--a‬فً هذه التعلٌمة المعامل ‪ٌ --a‬ؤخذ أولوٌة التنفٌذ ح ّتى‬ ‫ولو كان فً ٌمٌن التعلٌمة لذلك فإنّ قٌمة ‪ a‬ستتغ ٌّر أوّ ال ث ّم سٌت ّم االستدعاء التالً‪ ,‬وسٌكون ناتج التابع كما هو‬ ‫ضح فً الجدول ‪.A‬‬ ‫مو ّ‬ ‫الحالة ‪ B‬نجد التعلٌمة ;)‪ return a+sum(a--‬فً هذه التعلٌمة المعامل ‪ٌ a--‬ؤخذ أولوٌة التنفٌذ ح ّتى‬ ‫ولو كان فً ٌمٌن التعلٌمة لكنّ قٌمة ‪ a‬لن تتغ ٌّر ح ّتى ٌنتقل المترجم إلى التعلٌمة التالٌة ّإال أنّ االستدعاء التالً‬ ‫سٌت ّم وستكون قٌمة ‪ a‬عندها نفسها فً االستدعاء السابق أي أنّ شرط تو ّقف التعاودٌّة لن ٌتحقّق أبدا ممّا ٌسبب‬ ‫الخطؤ المذكور فً الجدول ‪.B‬‬ ‫الحالة ‪ C‬نجد التعلٌمة ;)‪ return a+sum(a-1‬فً هذه التعلٌمة ‪ a-1‬تنقص قٌمة ‪ a‬بمقدار ‪ 1‬فً‬ ‫االستدعاء التالً‪ ,‬وسٌكون ناتج التابع كما هو موضح فً الجدول ‪.C‬‬ ‫)راجع فصل المعامبلت‪ .‬فقرة ‪ (6‬معامبلت الزٌادة و النقصان(‬

‫‪83‬‬


‫‪ٌُ .3‬قا ُل عن عد ٍد ما إ ّنه تا ٌّم إذا كان ٌساوي مجموع قواسِ مه كلِّها باإلضافة إلى العدد ‪ 1‬ما عدا العدد نفسه‪.‬‬ ‫مثال‪:‬‬ ‫‪6 = 1 + 2 + 3‬‬ ‫اكتب برنامجا فٌه إجرا ٌء ٌطبع العبارة ‪ Is perfect‬إذا كان العدد المدخل تامّا‬ ‫وٌطبع ‪ sn't perfect‬إذا لم ٌكن تامّا‪.‬‬

‫‪.0‬‬

‫الخوارزمٌة (للتابع فقط)‬

‫‪ -1‬من أجل ‪ i = 1‬حتى ‪i = a-1‬‬ ‫إذا كان ‪ٌ i‬قسم ‪ a‬أضفه إلى مجموع القواسم‬

‫‪ -3‬إذا كان المجموع ٌساوي ‪ a‬اطبع ‪perfect‬‬ ‫و إال فاطبع ‪not perfect‬‬ ‫‪ .2‬الشٌفرة‬ ‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫;)‪void isperfect(int a‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪int n‬‬ ‫;" ‪cout<<"Enter number:‬‬ ‫;‪cin>>n‬‬ ‫;)‪isperfect(n‬‬ ‫;‪return 0‬‬ ‫}‬ ‫)‪void isperfect(int a‬‬ ‫{‬ ‫;‪int sum = 0‬‬ ‫)‪for(int i = 1; i< a;i++‬‬ ‫)‪if(a%i == 0‬‬ ‫;‪sum+= i‬‬ ‫;"‪(sum == a)? cout<<a <<" perfect\n":cout<< a<<" not perfect\n‬‬ ‫}‬

‫‪ .2‬أبراج هانوي (‪)Towers of Hanoi‬‬ ‫رؼزشع ٘زٖ اٌّشىٍخ ِؼظُ ِزؼٍّ‪ ٟ‬اٌجشِغخ ‪ ٟ٘ٚ‬رؼ‪ٛ‬د ئٌ‪ِٕ ٝ‬بؽك ف‪ ٟ‬ششق آع‪١‬ب ؽ‪١‬ش وبْ ف‪ ٟ‬اٌّؼجذ صالصخ‬ ‫أػّذح األ‪ٚ‬ي ف‪ 46 ٗ١‬لشطب ً ِشرجخ رظبػذ‪٠‬ب ً ِٓ األػٍ‪ ٝ‬ئٌ‪ ٝ‬األعفً ثؾ‪١‬ش ‪٠‬ى‪ ْٛ‬أوجش٘ب ف‪ ٟ‬أعفً اٌؼّ‪ٛ‬د ‪ٚ‬رم‪ٛ‬ي‬ ‫األعط‪ٛ‬سح‪" :‬ئّٔٗ ػٕذِب ‪ٕ٠‬ز‪ ٟٙ‬اٌش٘جبْ ِٓ ٔمً وً ٘زٖ األلشاص ئٌ‪ ٝ‬اٌؼّ‪ٛ‬د اٌضبٌش ع‪ٕ١‬ز‪ ٟٙ‬اٌؼبٌُ"‪ٌٚ ,‬ى‪ٕ٠ ٟ‬مً‬ ‫اٌش٘جبْ ٘زٖ األلشاص ‪٠‬غت أْ ‪٠‬شاػ‪ٛ‬ا اٌمبػذح اٌزبٌ‪١‬خ‪:‬‬ ‫‪ٌ -2‬جب نقل قرص واحد فقط فً ك ّل مرّ ة‪.‬‬ ‫‪ٌ -3‬جب استخدام أحد األعمدة كوسٌط مإقت‪.‬‬ ‫‪ -4‬ال ٌجوز أن تضع قرصا كبٌرا فوق قرص أصغر منه أبدا‪.‬‬ ‫مهم ّتنا اآلن أن نساعد هإالء الرهبان على إٌجاد الطرٌقة األفضل لح ّل هذه المشكلة‪.‬‬ ‫حٌث سنكتب تابعا تعاود ٌّا ٌقبل الوسطاء التالٌة‪:‬‬ ‫‪ n 1 ‬عدد األقراص‬ ‫‪ from ‬العمود الموجودة علٌه األقراص‬ ‫‪ to ‬العمود الذي سننقل األقراص إلٌه‬ ‫‪ temp ‬العمود الوسٌط المإقت‬ ‫ث ّم ٌطبع الخطوات البلزمة لنقل األقراص اعتمادا على القاعدة السابقة‪.‬‬ ‫‪84‬‬



‫ لدٌنا ثبلثة أقراص نرٌد نقلها من العمود األول إلى العمود الثالث باالعتماد على العمود الثانً كوسٌط‬:‫مثال‬ .‫مإقت‬ Move Disk (1) from Move Disk (2) from Move Disk (1) from Move Disk (3) from Move Disk (1) from Move Disk (2) from Move Disk (1) from

1to3 1to2 3to2 1to3 2to1 2to3 1to3

‫ الخوارزمٌة‬.0 n = 1 ‫ إذا كان‬-1 .‫انقل القرص من العمود األول إلى العمود الثالث من دون اللجوء إلى العمود الوسٌط المإقت‬ :‫ و إال افعل الخطوات التالٌة‬-3 .‫ من العمود األول إلى العمود الثانً باستخدام العمود الثالث كوسٌط مإقت‬n-1 ‫ انقل القرص رقم‬-a .‫ انقل القرص األخٌر من العمود األول إلى العمود الثالث‬-b .‫ من العمود الثانً إلى العمود الثالث باستخدام العمود األول كوسٌط مإقت‬n-1 ‫ انقل القرص رقم‬-c ‫ الشٌفرة‬.2 #include<iostream> using namespace std; int han(int n,int a,int b,int t); int main() { int n,from=1,to=3,temp=2; cout<<"Enter n, from, to, temp\ne.g: 3\n1\n3\n2\n\n\n"; cin>>n>>from>>to>>temp; han(n,from,to,temp); return 0; } int han(int n,int from,int to,int temp) { if(n ==1) cout<<"Move Disk ("<<n<<") from "<< from<<" to "<< to <<"\n"; else { han(n-1,from,temp,to); cout<<"Move Disk ("<<n<<") from "<< from<<" to "<< to <<"\n"; han(n-1,temp,to,from); } return 0; }

85


โ ซโ ช .1โ ฌุฃู ุฌุฏ ุงุฃู ุฎุทุงุก ู ู ุงู ุชู ุงุจุน ุงู ุชุงู ู ุฉโ ช:โ ฌโ ฌ โ ซ)โ ช1. int Sum(int a , int bโ ฌโ ฌ โ ซ{โ ฌ โ ซ;โ ชint sum = a + bโ ฌโ ฌ โ ซ}โ ฌ โ ซ)โ ช2. int divide(int a , int bโ ฌโ ฌ โ ซ{โ ฌ โ ซ;โ ชreturn (float)a/bโ ฌโ ฌ โ ซ}โ ฌ โ ซ)โ ช3. void subtract(int a , int bโ ฌโ ฌ โ ซ{โ ฌ โ ซ;โ ชreturn a-bโ ฌโ ฌ โ ซ}โ ฌ

โ ซโ ช .2โ ฌู ุง ู ู ู ุงุชุฌ ุงู ุจุฑู ุงู ุฌ ุงู ุชุงู ู โ ช:โ ฌโ ฌ โ ซ>โ ช#include<iostreamโ ฌโ ฌ โ ซ;โ ชusing namespace stdโ ฌโ ฌ โ ซ;โ ชint x = 0โ ฌโ ฌ โ ซ;โ ชfloat bโ ฌโ ฌ โ ซ)โ ชfloat d(float a , float& bโ ฌโ ฌ โ ซ{โ ฌ โ ซ;โ ชa--โ ฌโ ฌ โ ซ;โ ชb++โ ฌโ ฌ โ ซ;โ ชx = a/bโ ฌโ ฌ โ ซ;โ ชreturn (x+1)/2.0โ ฌโ ฌ โ ซ}โ ฌ โ ซ)(โ ชint mainโ ฌโ ฌ โ ซ{โ ฌ โ ซ;โ ชfloat aโ ฌโ ฌ โ ซ;"โ ชcout<<"x\tb\ta\nโ ฌโ ฌ โ ซ;โ ชcout<<x<<"\t"<<b<<"\t"<<a<<endlโ ฌโ ฌ โ ซ;โ ชa = b = ++xโ ฌโ ฌ โ ซ;โ ชcout<<d(a , b)<<endlโ ฌโ ฌ โ ซ;โ ชcout<<x<<"\t"<<b<<"\t"<<a<<endlโ ฌโ ฌ โ ซ;โ ชreturn 0โ ฌโ ฌ โ ซ}โ ฌ โ ซู ุงุฐุง ุณู ู ู ู ู ุงุชุฌ ุงู ุจุฑู ุงู ุฌ ุงู ุณุงุจู ู ู ุงุณุชุจุฏู ู ุง ุงู ุชุนู ู ู ุฉ ;โ ช return (x+1)/2.0โ ฌุจุงู ุชุนู ู ู ุฉโ ฌ

โ ซ;โ ช return ++x/2.0โ ฌุ โ ช.โ ฌโ ฌ โ ซโ ช .3โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ู ุจุงู ุนู ู ู ู ุงุช ุงู ุฑู ุงุถู ู ุฉ ุงุฃู ุฑุจุน ู ุฐู ู ุจุงุณุชุฎุฏุงู ุงู ุชู ุงุจุนโ ช.โ ฌโ ฌ โ ซุซ ู ู ุงู ุชุจู ุจุงุณุชุฎุฏุงู ุชุงุจุน ุชู ุฑุงุฑู โ ช.โ ฌโ ฌ โ ซโ ช .4โ ฌุจุงุณุชุฎุฏุงู ุชุงุจุน ุชุนุงู ุฏู ู ุงู ุชุจ ุจุฑู ุงู ุฌุง ู ุญุณุจ ุงู ุนุฏุฏโ ฌ โ ซ)ู ุน ู ุงู ุญุธุฉ ุฃู ู โ ช:โ ฌโ ฌ

โ ซู ู โ ฌ

โ ซู โ ฌ

โ ซ(โ ฌ

โ ซู โ ฌ

โ ซโ ช .5โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ุชุงุจุน ู ู ู ู ุจุฅู ุฌุงุฏ ู ุฌู ู ุน ุงู ุณู ุณู ุฉ ุงู ุชุงู ู ุฉโ ช:โ ฌโ ฌ โ ซโ โ ฌ

โ ซ๐ โ ฌ

โ ซุงุนุชู ุฏ ุนู ู ุงู ุชู ุฑู ู ุงู ุณุงุจู ู ุญุณุงุจโ ช.โ ฌโ ฌ

โ ซโ ช .6โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ุฅู ู ุฌุงุฏ ุงู ู ุงุณู ุงู ู ุดุชุฑู ุงุฃู ู ุจุฑ ู ุนุฏุฏู ู ุจุงุณุชุฎุฏุงู ุชุงุจุน ุชู ุฑุงุฑู ู ุขุฎุฑ ุชุนุงู ุฏู โ ฌ โ ซุนู ู ุง ุฃู ู โ ช.GCD(x , y) = GCD(x , x % y) :โ ฌโ ฌ โ ซโ ช86โ ฌโ ฌ


โ ซ) (โ ฌ

โ ซโ ช .7โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ุชุงุจุน ู ุญุณุงุจ !โ ช nโ ฌู ุขุฎุฑ ู ุญุณุงุจโ ฌ โ ซู ุขุฎุฑ ู ุญุณุงุจโ ฌ

โ ซ) (โ ฌ

โ ซโ ช .8โ ฌุงู ุชุจ ุชุงุจุนุง )ุฅุฌุฑุงุก( ุงุณู ู โ ช multipleโ ฌุจุญู ุซ ู ุคุฎุฐ ุนุฏุฏู ู ุตุญู ุญู ู ู ู ุณู ุทู ู ุซ ู ู ู ุนู ุฏ )ู ุทุจุน( โ ช trueโ ฌุฅุฐุงโ ฌ โ ซู ุงู ุงู ุนุฏุฏ ุงู ุซุงู ู ู ู ู ุถุงุนู ุงุช ุงู ุนุฏุฏ ุงุฃู ู ู ู ุฅุงู ู ู ุนู ุฏ )ู ุทุจุน( โ ช.falseโ ฌโ ฌ โ ซโ ช .9โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ู ุชุงุจุน ู ู ู ู ุจู ุญุต ุฑู ู ุตุญู ุญ ู ู ุฑู ุฑ ุฅู ู ู ู ู ุนู ุฏ ู ู ู ุฉ ู ู ุทู ู ู ุฉ โ ช trueโ ฌุฅุฐุง ู ุงู ุฃู ู ู ู ุง ู โ ฌ โ ซโ ช falseโ ฌุฅุฐุง ู ู ู ู ู โ ช ,โ ฌุซ ู ู ุงุณุชุฎุฏู ุฅุฌุฑุงุก ู ู ู ู ุจุทุจุงุนุฉ ู ู ุงุฃู ุฑู ุงู ุงุฃู ู ู ู ู ุฉ ุจู ู โ ช 1โ ฌู ุงู ุฑู ู ุงู ู ุฏุฎู โ ชู ).โ ฌู ู ู ู ุงุณุชุฎุฏุงู โ ฌ โ ซุงู ุชุงุจุน ุงู ุณุงุจู ุฏุงุฎู ู ุฐุง ุงุฅู ุฌุฑุงุก(โ ช.โ ฌโ ฌ โ ซู ุจู ุญุธุฉ โ ช :โ ฌุงู ุฑู ู ุงุฃู ู ู ู ู ู ู ุงู ุฑู ู ุงู ุฐู ู ู ุจู ุงู ู ุณู ุฉ ุนู ู ู ู ุณู ู ุนู ู โ ช 1โ ฌู ู ุทโ ช .โ ฌู ุงู ุฑู ู โ ช 1โ ฌู ู ุณ ุฃู ู ู ู ุงโ ช.โ ฌโ ฌ

โ ซโ ช .10โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ุชุงุจุน ู ุญุณุงุจ ุงู ู ู ู ุฉ ุงู ู ุทู ู ุฉ ู ุนุฏุฏ ู ุงโ ช .โ ฌุนู ู ุง ุฃ ู ู ู ุง ุชุญ ู ู ู ุงู ุดู ู ุงู ุชุงู ู โ ช:โ ฌโ ฌ โ ซ| |โ ฌ

โ ซ{โ ฌ โ ซโ ช .11โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ุซุจู ุซุฉ ุชู ุงุจุน ู ู ุง ู ู ู โ ช:โ ฌโ ฌ โ ซโ ชู ๏ ทโ ฌุญุณุจ ู ุณุงุญุฉ ุฏุงุจุฑุฉ ุจุนุฏ ุฅุฏุฎุงู ู ุตู ู ุทุฑู ุง โ ชrโ ฌโ ฌ โ ซโ ชู ๏ ทโ ฌุญุณุจ ู ุณุงุญุฉ ู ุณุชุทู ู ุจุนุฏ ุฅุฏุฎุงู ุทู ู ู ุถู ุนู ู โ ชa, bโ ฌโ ฌ โ ซโ ช๏ ทโ ฌโ ฌ

โ ซ๐ โ ฌ

โ ซู ุญุณุจ ู ุณุงุญุฉ ู ุซู ุซ ุจุนุฏ ุฅุฏุฎุงู ุทู ู ู ุงุนุฏุชู โ ช bโ ฌู ุงุฑุชู ุงุนู โ ชhโ ฌโ ฌ

โ ซุญู ุซ ู ุนุฑุถ ุงู ุจุฑู ุงู ุฌ ู ุงุจู ุฉ ู ู ู ุง ุงู ุฎู ุงุฑุงุช ุงู ู ู ู ู ุฉ ู ู ุฎุชุงุฑ ุงู ู ุณุชุฎุฏู ุฃุญุฏู ุง ู ู ุง ู ู ุงู ุดู ู ุงู ุชุงู ู โ ช:โ ฌโ ฌ โ ซโ ชcircle spaceโ ฌโ ฌ โ ซโ ชrectangle spaceโ ฌโ ฌ โ ซโ ชtriangle spaceโ ฌโ ฌ โ ซโ ชfrom list above to select: 2โ ฌโ ฌ

โ ซโ ช1- Calculateโ ฌโ ฌ โ ซโ ช2- Calculateโ ฌโ ฌ โ ซโ ช3- Calculateโ ฌโ ฌ โ ซโ ชEnter numberโ ฌโ ฌ

โ ซโ ฆ โ ชCalculating rectangle spaceโ ฌโ ฌ โ ซโ ชEnter Rectangle width: 5โ ฌโ ฌ โ ซโ ชEnter Rectangle height: 3โ ฌโ ฌ โ ซโ ชS = 15โ ฌโ ฌ

โ ซโ ช .12โ ฌุงู ุชุจ ุจุฑู ุงู ุฌุง ู ู ู ุชุงุจุน ู ุคุฎุฐ ู ุณู ุทุง ู โ ฌ โ ซู ู ุซู ุงุฑุชู ุงุน ู ุซู ุซ ุซ ู ู ู ุทุจุนู ุจุงู ุดู ู ุงู ุชุงู ู โ ช:โ ฌโ ฌ โ ซ*โ ฌ โ ซ*โ ฌ โ ซ*โ ฌ โ ซ*โ ฌ โ ซ*โ ฌ

โ ซ*โ ฌ โ ซ* *โ ฌ โ ซ* * *โ ฌ โ ซ* * * *โ ฌ

โ ซ*โ ฌ โ ซ* *โ ฌ โ ซ* * *โ ฌ โ ซ* * * *โ ฌ โ ซู ู ู ุฐุง ุงู ู ุซุงู ุงุงู ุฑุชู ุงุน โ ช h = 5โ ฌู ู ุณุทุฑ ู ุญู ู โ ช) -1โ ฌุฑู ู ุงู ุณุทุฑ(*โ ช 3โ ฌู ุฌู ุฉโ ช.โ ฌโ ฌ โ ซุงุทุจุน ู ุฑุงุบุงุช ุญ ู ุชู ุฃู ู ู ู ุฌู ุฉ ู ู ุงู ุณุทุฑ ุซ ู ู ุงุณุชุฎุฏู ุงู ุนุจู ู ุฉ ุงู ุณุงุจู ุฉ ู ุทุจุงุนุฉ ุนุฏุฏ ุงู ู ุฌู ุงู ู ุทู ู ุจุฉ ู ู ู ู โ ฌ โ ซุณุทุฑโ ช.โ ฌโ ฌ

โ ซโ ช87โ ฌโ ฌ


‫القسم الثاني‬ ‫ِ‬ ‫مِ ّإل بست ٍة‬ ‫أخي لن تنال الع َ‬ ‫اجتُاد وبمغةٌ‬ ‫وحرص و ٌ‬ ‫ٌ‬ ‫ذكاءٌ‬

‫يك‬ ‫سأَُّبِ َ‬ ‫وصحبةُ‬

‫ِ‬ ‫ببيان‬ ‫عن تفصيمُا‬ ‫ٍ‬ ‫ِ‬ ‫زمان‬ ‫وطول‬ ‫أستاذ‬ ‫ُ‬ ‫اإلمام الشافعي‬

‫‪88‬‬


‫الفصل التاسع‪:‬‬

‫المصفوفة هً سلسلة من العناصر ذات النوع نفسه محفوظة فً الذاكرة بشكل متتالً بحٌث ٌمكن الوصول إلى‬ ‫أي عنصر بذكر اسم المصفوفة متبوعا بالدلٌل‪ .‬الشكل العام للتصرٌح عن المصفوفات هو‬

‫;]‪type name [elements‬‬ ‫‪:type‬‬

‫نوع البٌانات الخاص بالمصفوفة‪.‬‬

‫‪ :name‬اسم الصفوفة‪.‬‬

‫‪ :elements‬عدد العناصر‪.‬‬

‫فمثبل ٌمكن أن نخزن ‪ 5‬قٌم من النوع ‪ int‬دون الحاجة إلى التصرٌح عن خمسة متغٌّرات بؤسماء مختلفة وذلك‬ ‫باستخدام المصفوفات كما ٌلً‪:‬‬

‫; ]‪int array[5‬‬

‫أي المصفوفة ‪ array‬تحوي خمس قٌم صحٌحة ) ‪ ( integer‬كما فً الشكل السابق‪.‬‬

‫مالحظة ‪ :‬عند التصرٌح عن المصفوفة فً لغة ‪ٌ C++‬جب أن ٌكون عدد العناصر قٌمة ثابتة‬ ‫حٌث إن المصفوفات هً حجرات ذاكرة ستاتٌكٌة ٌجب أن ٌُعطى حجم هذه الحجرات‬ ‫للمترجم ‪ compiler‬لٌحدد كم من الذاكرة ٌجب أن ٌحجز للمصفوفة قبل تنفٌذ البرنامج‪.‬‬

‫ٌمكن تعببة المصفوفة )إسناد القٌم لعناصرها ( كما ٌلً‬ ‫;}‪int array[5]={1,3,4,2,7‬‬ ‫وٌمكن فً هذه الحالة تجاوز المبلحظة السابقة أي ٌمكن كتابة‬ ‫;}‪int array[]={1,3,4,2,7‬‬ ‫عندما نصرح عن المصفوفات داخل التوابع وال نضع قٌم لعناصرها فإن قٌم العناصر ستبقى عشوابٌة حتى‬ ‫نضع قٌم لهذه العناصر ‪,‬وعندما نصرح عن المصفوفات خارج أي تابع فإن قٌم العناصر تكون صفرٌة‪.‬‬

‫‪89‬‬


‫التعامل مع المصفوفات‬ ‫فً أي جزء من البرنامج تكون فٌه المصفوفة مربٌّة )راجع فقرة المدى( ٌمكن أن نصل إلى عناصرها للقراءة أو‬ ‫للتعدٌل على أيّ عنصر منها كما ٌلً‪:‬‬ ‫اسم المصفوفة ] الدلٌل [‬

‫]‪name[index‬‬

‫من المثال السابق تكون العناصر كما فً الشكل‪:‬‬

‫فإذا أردنا إسناد قٌمة العنصر الثالث للمتحول ‪ a‬نكتب‬

‫; ]‪a=array[2‬‬

‫ولِوضع القٌمة ‪ 10‬فً العنصر األول نكتب‬

‫; ‪array[0]=10‬‬

‫لؤلقواس المربعة استخدامان مختلفان األول لتحدٌد حجم المصفوفة عند التصرٌح عنها‪ ,‬والثانً لتحدٌد دلٌل‬ ‫العنصر المراد الوصول إلٌه من المصفوفة‬ ‫التصرٌح عن مصفوفة جدٌدة ٌبدأ بتحدٌد نوعها ‪//‬‬ ‫الوصول إلى العنصر األول من المصفوفة ‪//‬‬

‫;]‪int array[5‬‬ ‫;‪array[0] = 10‬‬

‫هناك عبارات أخرى صحٌحة مثل‬ ‫;‪array [0] = a‬‬ ‫;‪array [a] = 75‬‬ ‫;]‪b = array [a+2‬‬ ‫;‪array [array [a]] = array [2] + 5‬‬

‫مثال‬ ‫‪12206‬‬

‫‪// arrays example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫;}‪int m[] = {16, 2, 77, 40, 12071‬‬ ‫;‪int i,sum=0‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫) ‪for ( i=0 ; i<5 ; i++‬‬ ‫{‬ ‫;]‪sum+= m[i‬‬ ‫}‬ ‫;‪cout <<sum‬‬ ‫;‪return 0‬‬ ‫}‬

‫الخرج هو مجموع عناصر المصفوفة ‪m‬‬ ‫‪8:‬‬


‫المصفوفات المتعددة األبعاد‬ ‫ٌمكن أن توصف المصفوفات المتعددة األبعاد بؤ ّنها مصفوفات لمصفوفات فالمصفوفة ثنابٌة البعد ٌمكن تصورها‬ ‫على أ ّنها جدول ثنابً البعد لبٌانات من نوع واحد‪.‬‬

‫تمثل ‪ a‬مصفوفة ثنابٌة البعد مإلفة من ‪ 3‬أسطر و ‪ 5‬أعمدة من النوع ‪ int‬تع ّرف كما ٌلً ‪:‬‬ ‫;]‪int a[3][5‬‬ ‫وللوصول إلى العنصر الواقع فً السطر الثانً والعمود الرابع نكتب‬ ‫]‪a[1][3‬‬

‫) تذ ّكر أنّ أدلّة المصفوفة تبدأ دابما بـ ‪( 0‬‬ ‫المصفوفات المتعددة األبعاد ال تقتصر على دلٌلٌن) بعدٌن( فقط بل ٌمكن أن تحوي أدلة بحسب الحاجة‪ ,‬لك ّننا‬ ‫نادرا ما نحتاج أكثر من ‪ 3‬أبعاد حٌث تكون كمٌة الذاكرة المطلوبة لتخزٌن هذه المصفوفات كبٌرة جدّا فمثبل‬ ‫;]‪char century [100][365][24][60][60‬‬ ‫هذه المصفوفة تحجز فً الذاكرة متغٌّر من نوع ‪ char‬لكل ثانٌة فً القرن أي تحجز حوالً ‪ 3‬ملٌارات باٌت‬ ‫إذا صرحنا عن هذه المصفوفة فإ ّنها ستستهلك حوالً ‪ 3‬جٌغا من الذاكرة ‪.RAM‬‬ ‫المصفوفات المتعددة األبعاد هً مجرد تبسٌط لمصفوفة من بعد واحد حٌث المصفوفتان التالٌتان متكافبتان‬ ‫)‪int a [15]; (3 * 5 = 15‬‬

‫;]‪int a [3][5‬‬

‫والشٌفرتان التالٌتان متكافبتان أٌضا‬

‫‪91‬‬


‫‪// pseudo-multidimensional array‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬

‫‪// multidimensional array‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬

‫‪#define WIDTH 5‬‬ ‫‪#define HEIGHT 3‬‬

‫‪#define WIDTH 5‬‬ ‫‪#define HEIGHT 3‬‬

‫;]‪int a [HEIGHT * WIDTH‬‬ ‫;‪int n,m‬‬

‫;]‪int a [HEIGHT][WIDTH‬‬ ‫;‪int n,m‬‬

‫)( ‪int main‬‬ ‫{‬ ‫)‪for (n=0;n<HEIGHT;n++‬‬ ‫)‪for (m=0;m<WIDTH;m++‬‬ ‫{‬ ‫;)‪a[n*WIDTH+m]=(n+1)*(m+1‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫)( ‪int main‬‬ ‫{‬ ‫)‪for (n=0;n<HEIGHT;n++‬‬ ‫)‪for (m=0;m<WIDTH;m++‬‬ ‫{‬ ‫;)‪a[n][m]=(n+1)*(m+1‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫كبل البرنامجٌن ٌحجزان ذاكرة للمصفوفة ‪ a‬كما فً الجدول التالً ‪:‬‬

‫استخدمنا ‪ #define‬لٌصبح التعدٌل البلحق على البرنامج أسهل فلو أردنا أن تكون قٌمة البعد ‪HEIGHT‬‬ ‫‪ 4‬بدال من ‪ 2‬نكتب ‪ #define HEIGHT 4‬بدال من ‪#define HEIGHT 3‬‬ ‫وذلك أبسط من تعرٌف المصفوفة بثوابت عددٌة ) ;]‪ ( int a[3][5‬ث ّم تعدٌل ‪ 3‬إلى ‪ 4‬فً كل مرّ ة تذكر فٌها المصفوفة‬

‫فً البرنامج‪.‬‬ ‫كما ٌمكن أن نسند قٌم لعناصر المصفوفة أثناء التصرٌح كما ٌلً ‪:‬‬ ‫;}}‪int a[3][5]={{1,2,3,4,5},{2,4,6,8,10},{3,6,9,12,15‬‬ ‫حٌث إنّ العناصر المحصورة بٌن األقواس الداخلٌة هً عناصر السطر األول والثانً والثالث بالترتٌب‬ ‫أمّا إذا كتبنا‬ ‫;}}‪int a[3][5]={{1,3,4,5},{10},{12,15‬‬ ‫فإنّ باقً عناصر المصفوفة تكون أصفارا كما فً الجدول المبٌن ‪:‬‬

‫‪92‬‬


‫المصفوفات كمعامالت(وسطاء) للتوابع‬ ‫نحتاج أحٌانا أن نم ّرر مصفوفة كمعامل لتابع ما‪ .‬فً لغة ‪ C++‬ال ٌمكن تمرٌر مجموعة حجرات ذاكرة بالقٌمة‬ ‫كمعامل لتابع ما‪ ,‬وبالتالً ال ٌمكن تمرٌر كامل المصفوفة‪ ,‬ولكن ٌمكن تمرٌر عنوانها الذاكري‪.‬‬ ‫ولكً تصبح المصفوفات معامبلت ٌجب علٌنا عند التصرٌح عن التابع المراد التعامل معه أن نضع نوع‬ ‫البٌانات للمصفوفة المراد استقبالها واسم للمصفوفة داخل التابع ث ّم أقواس مربعة فارغة فمثبل التابع‬ ‫)][‪void procedure (int arg‬‬ ‫ٌقبل مصفوفة من النوع ‪ int‬وسٌسمٌها ‪ arg‬ولنمرر مصفوفة لهذا التابع نصرح عنها‬ ‫;]‪int myarray [40‬‬ ‫ث ّم نستدعً التابع كما ٌلً‬

‫;)‪procedure (myarray‬‬

‫مثال‬ ‫‪5 10 15‬‬ ‫‪2 4 6 8 10‬‬

‫‪// arrays as parameters‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ )‪void printarray(int arg[], int length‬‬ ‫)‪for (int n=0; n<length; n++‬‬ ‫;" " << ]‪cout << arg[n‬‬ ‫;"‪cout << "\n‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;}‪int firstarray[] = {5, 10, 15‬‬ ‫;}‪int secondarray[] = {2, 4, 6, 8, 10‬‬ ‫;)‪printarray (firstarray,3‬‬ ‫;)‪printarray (secondarray,5‬‬ ‫;‪return 0‬‬ ‫}‬

‫كما ترى فإنّ المعامل األول للتابع ‪ printarray‬هو )][‪ٌ (int arg‬قبل أي مصفوفة من النوع ‪ int‬أٌا كان‬ ‫طولها‪ ,‬أمّا المعامل الثانً فهو طول المصفوفة المراد تمرٌرها وهذا ٌعطً الحلقة ‪ for‬شرط التوقف‪.‬‬ ‫عند التصرٌح عن التابع ٌمكن أٌضا أن نم ّكنه من أن ٌستقبل المصفوفات المتعددة األبعاد وٌكون التصرٌح عن‬ ‫التابع الذي ٌقبل المصفوفة‬ ‫;)]‪void procedure (int myarray[ ][3‬‬ ‫ثنابٌة األبعاد‬ ‫;)]‪void procedure (int myarray[ ][3][4‬‬ ‫وثبلثٌة األبعاد‬ ‫‪93‬‬


‫الحظ أنّ القوس األول فارغ أمّا باقً األقواس فٌجب أن نحدّد عمقها ألنّ المترجم ٌجب أن ٌحدد خبلل التابع ما‬ ‫هً قٌمة كل بعد إضافً‪.‬‬ ‫عندما تمرّ ر المصفوفات األحادٌة أو المتعددة األبعاد كمعامبلت للتوابع تشكل مصدرا شابعا لؤلخطاء عند‬ ‫المبرمجٌن قلٌلً الخبرة‪ ,‬ننصح هنا بقراءة فصل المإ ّ‬ ‫شرات لفهم أفضل آللٌة عمل المصفوفات‪.‬‬

‫األعداد العشوائٌة‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫هناك العدٌد من التطبٌقات البرمجٌة الشابعة التً تحتاج إلى المحاكاة كاأللعاب والدراسات االحتمالٌة‬ ‫واالحصابٌة‪.‬‬ ‫ٌمكن أن نولد األعداد العشوابٌة فً لغة ‪ C++‬باستخدام التابع )(‪ rand‬الموجود فً المكتبة القٌاسٌة‬ ‫>‪ <cstdlib‬لذلك ٌجب أن نضمّنها فً البرنامج‪.‬‬ ‫ٌولد التابع )(‪ rand‬أرقاما صحٌحة موجبة (‪ )unsigned integer‬بٌن ‪ 0‬و ‪ RAND_MAX‬الذي‬ ‫هو ثابت رمزي معرف فً المكتبة القٌاسٌة تكون قٌمته ‪ 32767‬على األقل‪.‬‬ ‫لكً نحدد مجال لؤلعداد التً سٌتم تولٌدها نستخدم العبلقة‬

‫;‪number = shiftingValue + rand() % scalingFactor‬‬ ‫‪ :number‬العدد المولّد‪ :shiftingValue .‬اإلزاحة‪ :scalingFactor .‬طول مجال التولٌد‪.‬‬ ‫مثال‪:‬‬ ‫إنّ القٌم المحتملة للمتغٌّر ‪ number‬هً ضمن المجال ]‪.[1,6‬‬

‫;‪number = 1 + rand() % 6‬‬

‫‪‬‬

‫كل مرّ ة ٌت ّم فٌها تنفٌذ البرنامج ٌت ّم تولٌد نفس األعداد لذلك ٌوجد تابع فً المكتبة القٌاسٌة اسمه‬ ‫)(‪ٌ srand‬قوم بتغٌ​ٌر سلسلة األرقام عند كل تنفٌذ للبرنامج وٌستقبل هذا التابع قٌمة من النوع‬ ‫‪ unsigned integer‬ولكً نضمن تغٌّر القٌمة المرسلة إلى ‪ srand‬نستخدم التابع )(‪ time‬كالتالً‪:‬‬ ‫;) ) ‪srand( time( 0‬‬ ‫) ‪ٌ time( 0‬قرأ الوقت عند التنفٌذ بالثوانً وٌحوّ له إلى ‪.unsigned integer‬‬ ‫التابع )(‪ time‬موجود فً المكتبة >‪ <ctime‬التً ٌجب أن نضمّها إلى البرنامج‪.‬‬

‫مثال‪:‬‬ ‫>‪#include <iostream‬‬ ‫>‪#include <cstdlib‬‬ ‫>‪#include <ctime‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int num,guess,guessNum‬‬ ‫;"‪cout<<"\tguessing game\n\n‬‬ ‫;))‪srand(time(0‬‬ ‫;‪num=1+rand()%100‬‬ ‫;" ‪cout<<"enter your guess between 1 and 100:‬‬ ‫)‪for(guessNum=0;guess!=num;guessNum++‬‬ ‫{‬ ‫;‪cin>>guess‬‬ ‫)‪if(guess<num‬‬ ‫;" ‪cout<<"your guess is too low!. try again:‬‬ ‫)‪if(guess>num‬‬ ‫;" ‪cout<<"your guess is too high!. try again:‬‬ ‫}‬

‫‪94‬‬


cout<<"congratulations. you guessed it!!!. " <<"\nyou tried "<<guessNum<<" times to guess it\n"; return 0; } guessing game enter your guess between 1 and 100: your guess is too high!. try again: your guess is too low!. try again: your guess is too high!. try again: your guess is too high!. try again: congratulations. you guessed it!!!. you tried 5 times to guess it

95

50 25 37 31 28


: ‫ ذات النوع الصحٌح قم بطباعتها ث ّم اطبع مجموع عناصرها‬A ‫ لتكن لدٌنا المصفوفة‬-1 A= [ 5, 6, 1, 9, 12, 4, 7 ]

#include <iostream> using namespace std; int main() { int A[]={5,6,1,9,12,4,7}; int sum=0; for(int i=0;i<7;i++) { cout<<A[i]<<" "; sum+=A[i]; //sum =sum+A[i]; } cout<<"\nsum= "<<sum<<endl; return 0; }

.‫ اكتب برنامجا لحساب سلسلة فٌبوناكسً بطرٌقة تكرارٌّة‬-2

#include<iostream> using namespace std; int f[1000]; int fib(int n) { f[0] = 0; f[1] = 1; for(int i=2; i<=n;i++) f[i] = f[i-1]+f[i-2]; return f[n]; } int main() { int n ; cout<< "Enter n: "; cin>> n; cout<< "\nfib(" << n << ") = " << fib(n) << endl; }

‫ ث ّم ٌقوم بالبحث عن‬V ‫ أرقام صحٌحة إلى مصفوفة وعدد‬10 ‫ اكتب برنامجا ٌطلب من المستخدم أن ٌدخل‬-3 ّ ‫ موجودا فٌها‬V ‫" إذا كان‬V is in the array" ‫ ضمن عناصر المصفوفة المدخلة وٌطبع‬V ‫وإال فإ ّنه ٌطبع‬ ."V is not in the array" 96


#include <iostream> using namespace std; int main() { int arr[10],V,i; bool found=false; cout<<"enter 10 numbers please!\n"; for(i=0;i<10;i++) { cout<<"number"<<i+1<<"= "; cin>>arr[i]; } cout<<"enter V: "; cin>>V; for(i=0;i<10;i++) if(arr[i]==V) { found=true; break; } if(found) //same as if(found==true) cout<<"V is in the array\n"; else cout<<"V is not in the array\n"; return 0; }

: ً‫ث ّم عمل ماٌل‬ ‫ اكتب برنامجا لقراءة مصفوفة ثنابٌة األبعاد‬-4 .print() ‫ طباعة المصفوفة بشكل مناسب باستخدام تابع‬ .( ‫ الصفرٌة‬, ‫السالبة‬, ‫ طباعة عدد العناصر) الموجبة‬ .‫ طباعة عدد العناصر الزوجٌة والفردٌة‬ .‫ طباعة عناصر القطر الربٌسً ث ّم عناصر القطر الثانوي‬

#include <iostream> using namespace std; void print(int a[][4]) { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) cout<<a[i][j]<<"\t"; cout<<"\n\n"; } } int main() {

97


int X[4][4],i,j; int positives=0,negatives=0,zeros=0; int even=0,odd=0; for(i=0;i<4;i++) for(j=0;j<4;j++) { cout<<"X["<<i+1<<"]["<<j+1<<"]= "; cin>>X[i][j]; if(X[i][j]>0) positives++; if(X[i][j]<0) negatives++; if(X[i][j]==0) zeros++; if(X[i][j]%2==0) even++; if(X[i][j]%2!=0) odd++; } cout<<"\n"; print(X);//printing X cout<<"\nnumber of positive elements="<<positives; cout<<"\nnumber of negative elements="<<negatives; cout<<"\nnumber of zeroth elements="<<zeros; cout<<"\nnumber of even elements="<<even; cout<<"\nnumber of odd elements="<<odd; cout<<"\nleading diagonal: "; for(i=0;i<4;i++) cout<<X[i][i]<<"\t"; cout<<"\ncross diagonal: "; for(i=0;i<4;i++) { for(j=0;j<4;j++) if(i+j==4-1) cout<<X[i][j]<<"\t"; } cout<<endl; return 0; }

‫ اكتب برنامجا ٌقوم بجمع مصفوفتٌن ثنابٌتً األبعادعلما أن شرط الجمع هو أن ٌكون للمصفوفتٌن نفس‬-5 .‫األبعاد‬

// program to add matrix to another one #include <iostream> using namespace std; int main() { int a[10][10],b[10][10],c[10][10]; int i,j,m,n; cout<<"number of rows=";cin>>m; cout<<"number of columns=";cin>>n; for(i=0;i<m;i++) for(j=0;j<n;j++)

98


{ cout<<"a["<<i+1<<"]["<<j+1<<"]=";cin>>a[i][j]; cout<<"b["<<i+1<<"]["<<j+1<<"]=";cin>>b[i][j]; c[i][j]=a[i][j]+b[i][j]; } for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<a[i][j]<<" "; cout<<"\n"; } cout<<"\n +\n\n"; for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<b[i][j]<<" "; cout<<"\n"; } cout<<"\n =\n\n"; for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<c[i][j]<<" "; cout<<"\n"; } return 0; }

‫ اكتب برنامجا ٌقوم بضرب مصفوفتٌن ثنابٌتً األبعادعلما أن شرط الضرب هو أن ٌكون عدد أعمدة‬-6 .‫المصفوفة األولى ٌساوي عدد أسطر المصفوفة الثانٌة‬

//matrix multiplication #include<iostream> using namespace std; #define M 20 int a[M][M],b[M][M],c[M][M];//all arrays' elements equal zero void main() { int ma,na,mb,nb,i,j,k; /*ma=number of A rows,na=number of A columns, mb=number of B rows,nb=number of B columns, i,j,k:counters */ cout<<"enter dimensions of A(ma,na): ";cin>>ma>>na; cout<<"enter dimensions of B(mb,nb): ";cin>>mb>>nb; if(na!=mb) cout<<"verify multiplication condition na=mb\n"; else { cout<<"enter A elements\n";//reading A elements for(i=0;i<ma;i++) for(j=0;j<na;j++) { cout<<"a["<<i+1<<"]["<<j+1<<"]= ";cin>>a[i][j];}

99


cout<<"enter B elements\n";//reading B elements for(i=0;i<mb;i++) for(j=0;j<nb;j++) { cout<<"b["<<i+1<<"]["<<j+1<<"]= ";cin>>b[i][j];} for(i=0;i<ma;i++)//multiplication for(j=0;j<nb;j++) for(k=0;k<na;k++) c[i][j]+=(a[i][k]*b[k][j]); cout<<"the result C=\n\n"; for(i=0;i<ma;i++) {for(j=0;j<nb;j++) cout<<c[i][j]<<"\t"; cout<<"\n\n";} } }

‫( لٌقوم‬print) ‫( تحوي أسماء األشهر ث ّم مرر هذه المصفوفة إلى تابع‬string) ‫ عرّ ف مصفوفة من النوع‬-8 .‫بطباعتها‬

#include<iostream> #include<string> using namespace std; void print(string m[],int n) { for(int i=0;i<n;i++) cout<<m[i]<<"\n"; } int main() { string months[12]={"January","February","March" ,"April","May", "June" ,"July","August","September" ,"October","November","December"}; print(months,12); return 0; }

9:


‫‪ -1‬أوجد األخطاء فً كل من العبارات التالٌة‪:‬‬ ‫بفرض ; } ‪int b[ 10 ] = { 0‬‬ ‫) ‪for ( int i = 0; i<= 10; i++‬‬ ‫;‪b[ i ] = 1‬‬

‫)‪a‬‬

‫;] ‪int a[ 3‬‬ ‫بفرض‬ ‫;‪cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl‬‬

‫)‪b‬‬

‫;} ‪double f[ 3 ] = { 1.1, 10.01, 100.001, 1000.0001‬‬

‫)‪c‬‬

‫;] ‪double d[ 2 ][ 10‬‬ ‫;‪d[ 1, 9 ] = 2.345‬‬

‫)‪d‬‬

‫بفرض‬

‫‪ -2‬امؤل الفراغات التالٌة ‪:‬‬ ‫‪ (a‬أسماء العناصر األربع للمصفوفة ‪ ( int p[4]; ) p‬هً ______ و ______ و‬ ‫______ و ______‪.‬‬ ‫‪ (b‬تسمٌة المصفوفة بتحدٌد نوعها وعدد عناصرها ٌدعى _______ المصفوفة‪.‬‬ ‫‪ (c‬اسم العنصر الواقع فً السطر ‪ 3‬والعمود ‪ 5‬فً المصفوفة ‪ d‬هو ______‪.‬‬ ‫‪ (d‬المصفوفة المإلفة من ‪ 4‬أسطر و ‪ 5‬أعمدة تحوي ______ عنصرا‪.‬‬

‫‪ -3‬اكتب التعلٌمة أو التعلٌمات البلزمة للقٌام بالمهام التالٌة ‪:‬‬ ‫‪ (a‬صرّ ح عن متغٌّر ثابت باسم ‪ arraySize‬وأعطه القٌمة ‪.10‬‬ ‫‪ (b‬صرّ ح عن المصفوفة ‪ fractions‬بعدد عناصر ‪ arraySize‬ونوع ‪ double‬وأعط عناصرها‬ ‫القٌمة ‪.1‬‬ ‫‪ (c‬ضع القٌمة ‪ 1.667‬فً العنصر التاسع والقٌمة ‪ 3.333‬فً العنصر السابع‪.‬‬ ‫‪ (d‬اطبع المصفوفة باستخدام حلقة ‪.for‬‬ ‫‪ -4‬رتب المصفوفة التالٌة تصاعدٌا ث ّم تنازلٌا واطبعها فً الحالتٌن‬ ‫]‪A = [1,5,4,3,7,2,9,0‬‬ ‫‪ -5‬اكتب برنامجا ٌطلب من المستخدم إدخال مصفوفتٌن ‪ A‬و ‪) B‬من النوع ‪ (integer‬كل منهما مكونة‬ ‫من ‪ 10‬عناصر ‪ٌ ,‬جب على البرنامج أن ٌضم المصفوفة ‪ B‬إلى نهاٌة المصفوفة ‪ A‬وٌضع الناتج فً‬ ‫المصفوفة ‪ C‬المإلفة من ‪ 20‬عنصر ث ّم ٌطبع المصفوفة ‪.C‬‬ ‫‪ -6‬اكتب برنامجا ٌطلب من المستخدم إدخال مصفوفة )‪ (integer‬من ‪10‬عناصر ث ّم ٌطبع البرنامج‬ ‫المصفوفة تصاعدٌة " ‪ " the array is growing‬أو تنازلٌة "‪"the array is decreasing‬‬ ‫أو ثابتة "‪ "the array is constant‬أو تصاعدٌة وتنازلٌة ‪"the array is growing and‬‬ ‫"‪decreasing.‬‬ ‫‪:1‬‬


‫‪ -7‬اكتب برنامجا ٌم ّكن المستخدم من إدخال عدد الطبلب ‪ n‬وأسمابهم ‪ names‬ودرجاتهم ‪ marks‬فً‬ ‫مقرر ما ث ّم ٌطبع أسماء الطبلب حسب درجاتهم فً المقرر وبترتٌب تنازلً‪.‬‬ ‫‪ -8‬اكتب برنامجا ٌقوم بجمع مصفوفتٌن ثنابٌتً األبعاد علما أن شرط الجمع هو أن ٌكون للمصفوفتٌن‬ ‫نفس األبعاد باستخدام التوابع‪) .‬التمرٌن محلول فً التمارٌن المحلولة بدون استخدام التوابع(‪.‬‬ ‫‪ -9‬اكتب برنامجا ٌقوم بتنفٌذ اللعبة التالٌة‬ ‫لعبة ) ورقة – مقص – حجر (‬ ‫تحتاج هذه اللعبة إلى العبٌن فقط حٌث ٌخفً كل منهما ٌده وٌختار أحد الخٌارات الثبلث وٌكون‬ ‫الرابح وفق الجدول التالً‪:‬‬ ‫الخٌار األول‬ ‫ورقة‬ ‫حجر‬ ‫مقص‬

‫الخٌار الثانً‬ ‫حجر‬ ‫مقص‬ ‫ورقة‬

‫النتٌجة‬ ‫الورقة تغطً الحجر لذلك تربح نقطة‬ ‫الحجر ٌكسر المقص لذلك ٌربح نقطة‬ ‫المقص ٌقص الورقة لذلك ٌربح نقطة‬

‫‪:2‬‬


‫الفصل العاشر‪:‬‬

‫تم ّكننا السبلسل من التعامل مع النصوص سواء منها الكلمات أو الجمل أو األسماء‪. ..‬‬ ‫السلسلة مإلفة من تتابع من العناصر ذات النوع ‪ char‬حٌث إنّ كل عنصر ٌمثل حرف فً السلسلة‪ .‬فمثبل‬ ‫المصفوفة )سلسلة الرموز( التالٌة ‪:‬‬ ‫;]‪char str [20‬‬ ‫ٌمكن أن تخزن سلسلة مإلفة من ‪ 15‬حرف كما فً الشكل‬

‫لٌس ضرورٌا أن نمؤل كل عناصر السلسلة فٌمكن أن تحوي السلسلة فً نقطة ما من البرنامج الكلمة "‪"Hello‬‬ ‫التً تمؤل ‪ 5‬خانات أو العبارة "‪ "Hello World‬التً تمؤل ‪ 12‬خانة‪.‬‬ ‫عند نهاٌة السلسلة المخزنة فً كبل الحالتٌن نصل إلى الرمز ‪ null‬الذي ٌمكن أن ٌكتب ‪ 0‬أو ' ‪' \0‬‬

‫أما العناصر الواقعة فً المنطقة الرمادٌة فقٌمها غٌر محددة‪.‬‬

‫التعامل مع السالسل‬

‫بما أنّ السبلسل هً مصفوفات طبٌعٌة فإ ّنها تخضع لنفس قواعد المصفوفات فإذا أردنا مثبل أن نضع القٌم فً‬ ‫السلسلة أثناء التصرٌح نكتب ‪:‬‬ ‫;} '‪char mystring[6] = { 'H', 'e', 'l', 'l', 'o', '\0‬‬ ‫أو‬ ‫;} '‪char mystring[ ] = { 'H', 'e', 'l', 'l', 'o', '\0‬‬ ‫ولكن هناك طرٌقة أخرى لعمل ذلك وهً‪:‬‬ ‫;"‪char mystring [ ] = "Hello‬‬ ‫حٌث إنّ السبلسل المحصورة بعبلمات اقتباس مزدوجة ٌضاف إلى نهاٌتها الثابت ‪ null‬بشكل آلً‪.‬‬ ‫إنّ إسناد الثوابت النصٌة مثل "‪ "Hello‬للسبلسل صحٌح فقط أثناء التصرٌح عن السلسلة )المصفوفة(‬ ‫لذلك فالعبارات التالٌة غٌر صحٌحة‪:‬‬ ‫;"‪mystring = "Hello‬‬ ‫;"‪mystring[] = "Hello‬‬ ‫;} '‪mystring = { 'H', 'e', 'l', 'l', 'o', '\0‬‬

‫‪:3‬‬


‫السبب فً ذلك ٌعود إلى أنّ المصفوفة هً عبارة عن مإ ّ‬ ‫شر ثابت ٌشٌر إلى كتلة ذاكرة محجوزة وبسبب هذا‬ ‫الثبات )فً قٌمة المإ ّ‬ ‫شر( فبل ٌمكن أن نسند أٌّة قٌمة للمصفوفة بح ِّد ذاتها ولكن ٌمكن إسناد قٌمة أليّ عنصر من‬ ‫عناصر هذه المصفوفة‪.‬‬ ‫لذلك فإنّ الطرف األٌسر لئلسناد ٌمكن أن ٌكون فقط عنصر من مصفوفة ولٌس مصفوفة كاملة‪.‬‬ ‫إذا ٌمكن أن نكتب ‪:‬‬ ‫;'‪mystring[0] = 'H‬‬ ‫;'‪mystring[1] = 'e‬‬ ‫;'‪mystring[2] = 'l‬‬ ‫;'‪mystring[3] = 'l‬‬ ‫;'‪mystring[4] = 'o‬‬ ‫;'‪mystring[5] = '\0‬‬ ‫ال تبدو هذه طرٌقة عملٌة لذلك سنستخدم توابع جاهزة مثل التابع ‪ strcpy‬المعرّ ف فً المكتبة ‪cstring‬‬ ‫)‪ (string‬وٌُستد َعى بالطرٌقة التالٌة‪:‬‬ ‫;)‪strcpy (string1, string2‬‬ ‫هذا التابع ٌقوم بنسخ محتوى ‪ string2‬وٌضعه فً ‪string1‬‬ ‫‪ٌ string2‬مكن أن ٌكون مصفوفة أو مإ ّ‬ ‫شرا أوسلسلة ثابتة‪.‬‬ ‫إذا إلسناد "‪ "Hello‬إلى السلسلة ‪ mystring‬نكتب‪:‬‬ ‫;)"‪strcpy (mystring, "Hello‬‬ ‫مثال‬ ‫‪Basil‬‬

‫‪// setting value to string‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫>‪#include <string‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;]‪char MyName[20‬‬ ‫;)"‪strcpy (MyName,"Basil‬‬ ‫;‪cout << MyName‬‬ ‫;‪return 0‬‬ ‫}‬

‫استخدمنا المكتبة >‪ <string‬لنتمكن من التعامل مع التابع ‪strcpy‬‬ ‫ٌمكن أن نكتب التابع ‪ setstring‬المإدي نفس الوظٌفة دون االستعانة بـ ‪strcpy‬‬ ‫‪Basil‬‬

‫‪// setting value to string‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)][‪void setstring(char Out[],char In‬‬ ‫{‬ ‫;‪int n=0‬‬ ‫{ ‪do‬‬ ‫;]‪Out[n] = In[n‬‬ ‫;)'‪} while (In[n++] != '\0‬‬ ‫}‬ ‫)( ‪int main‬‬ ‫{‬ ‫;]‪char MyName [20‬‬ ‫;)"‪setstring (MyName,"Basil‬‬ ‫;‪cout <<MyName‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪:4‬‬


‫هناك طرٌقة أخرى تعتمد على تعلٌمة اإلدخال ‪ cin‬فً هذه الحالة ٌت ّم إدخال السلسلة من قبل المستخدم أثناء‬ ‫تنفٌذ البرنامج حٌث نستخدم هنا التابع ‪ getline‬حسب الشكل العام‬ ‫;)'‪cin.getline ( char buffer[], int length, char delimiter = ' \n‬‬ ‫‪ :buffer‬هو المصفوفة التً سٌ َّ‬ ‫ُخزنُ فٌها الدخل‪.‬‬ ‫‪ :length‬هو الطول األعظمً للمصفوفة ‪buffer‬‬ ‫ّ‬ ‫‪ :delimiter‬هو الرمز الذي ٌحدّد نهاٌة إدخال المستخدم )إذا لم نضع هذا المعامل فإنه ٌكون بشكل افتراضً‬ ‫رمز السطر الجدٌد '‪ '\n‬أي عندما نضغط ‪( enter‬‬ ‫فمثبل ٌقوم هذا البرنامج بتكرار ماتكتبه على لوحة المفاتٌح‬ ‫?‪What's your name‬‬ ‫‪Sameer‬‬ ‫‪Hello Sameer.‬‬ ‫‪Which is your favourite‬‬ ‫‪book? The Holy Qura’an‬‬ ‫‪I like The Holy Qura’an too.‬‬

‫‪// cin with strings‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;]‪char mybuffer [100‬‬ ‫;"‪cout << "What's your name?\n‬‬ ‫;)‪cin.getline (mybuffer,100‬‬ ‫;"‪cout << "Hello " << mybuffer << ".\n‬‬ ‫;"‪cout << "Which is your favourite book?\n‬‬ ‫;)‪cin.getline (mybuffer,100‬‬ ‫;"‪cout << "I like " << mybuffer << " too.\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫عندما استخدمنا ‪ cin.getline‬ألول مرّ ة كانت قٌمته ّ‬ ‫تخزن االسم ‪ Sameer‬فً المصفوفة ‪ mybuffer‬أما فً‬ ‫المرّ ة الثانٌة فإنّ التابع ٌقوم بالكتابة فوق المحتوى األول للمصفوفة أي ٌخزن ‪ The Holy Qura’an‬فً‬ ‫المصفوفة‪.‬‬ ‫مالحظة ‪ٌ :‬مكن إدخال السبلسل باستخدام التعلٌمة ; ‪cin >> mybuffer‬‬ ‫هذه الطرٌقة مقبولة لكنها تسمح لنا بإدخال الكلمات فقط و ال تستقبل من الجملة الحاوٌة على‬ ‫فراغات إال أول كلمة ‪ ,‬كما ال ٌمكن تحدٌد طول المصفوفة ‪ mybuffer‬التً سٌدخلها المستخدم‬ ‫أي إذا أدخل عددا من األحرف أكبر من طول المصفوفة المحجوزة سٌتوقف تنفٌذ البرنامج‬ ‫لذلك من األفضل استخدام ‪ cin.getline‬عند التعامل مع السبلسل‪.‬‬

‫‪:5‬‬


‫الفصل احلاد‬

‫شصر‪:‬‬

‫إنّ ذاكرة الحاسوب ماهً ّإال تتابع من خبلٌا حجم كل منها واحد باٌت‪ ,‬ولكل واحدة من هذه الخبلٌا عنوان ممٌز‬ ‫حٌث ٌتولى نظام التشغٌل عنونة الذاكرة بؤرقام متتابعة‪.‬‬ ‫المإ ّ‬ ‫شر هو متغٌّر كسابر المتغٌّرات ولكنه ٌختلف عنها فٌما ٌختزنه فهو ال ٌختزن البٌانات العادٌة كاألرقام‬ ‫والرموز وإ ّنما ٌختزن عنوان المتغٌّر الذي ٌشٌر إلٌه‪.‬‬

‫معامل العنوان ( & )‬ ‫ّ‬ ‫سٌخزن فً إحدى الخبلٌا المتاحة فً الذاكرة بشكل آلً من قبل المترجم ونظام‬ ‫عندما نصرّ ح عن متغٌّر فإ ّنه‬ ‫التشغٌل‪ ,‬فإذا أردنا معرفة مكان تخزٌن هذا المتغٌّر نسبق اسم المتغٌّر بالرمز &‪.‬‬ ‫مثبل التعلٌمة ;‪ a = &b‬ستضع عنوان المتغٌّر ‪ b‬فً المتغٌّر ‪.a‬‬ ‫ّ‬ ‫مؤشراً​ً )مثل المتغٌّر ‪ a‬فً السطر السابق(‪.‬‬ ‫إنّ المتغٌّر الذي ٌحوي عنوان متغٌّر آخر ٌدعى‬

‫معامل المرجع ( * )‬ ‫إذا سبقنا المإ ّشر ‪ a‬بمعامل المرجع * أي إذا كتبنا ‪ *a‬فإنّ العبارة ;‪ c = *a‬تعنً ضع القٌمة التً ٌُشٌ ُر‬ ‫إلٌها المإ ّ‬ ‫شر ‪ a‬فً المتغٌّر ‪.c‬‬

‫;‪a = &b‬‬ ‫;‪c = *a‬‬

‫ٌجب االنتباه إلى الفرق بٌن العبارتٌن‬ ‫‪c = a; // c == 1176‬‬ ‫‪c = *a; // c = =25‬‬ ‫مما سبق تكون العبارات التالٌة صحٌحة‬ ‫‪b == 25‬‬ ‫‪&b == 1776‬‬ ‫‪a == 1776‬‬ ‫‪*a == 25‬‬ ‫‪*a == b‬‬ ‫‪:6‬‬


‫التصرٌح عن المؤ ّ‬ ‫شرات‬ ‫الشكل العام للتصرٌح هو‬ ‫;‪type * pointer_name‬‬ ‫شر ولٌس نوع المإ ّ‬ ‫‪ :type‬هو نوع البٌانات التً سٌشٌر إلٌها المإ ّ‬ ‫شرذاته‬ ‫‪ :pointer_name‬اسم المإ ّ‬ ‫شر ‪.‬‬ ‫أمثلة‬

‫;‪int * number‬‬ ‫;‪char * character‬‬ ‫;‪float * greatnumber‬‬ ‫شرات كل منها ٌشٌر إلى نوع مختلف من البٌانات مع ذلك فإنّ ك ّل واحد من هذه المإ ّ‬ ‫لدٌنا ثبلثة مإ ّ‬ ‫شرات ٌحجز‬ ‫نفس الحجم فً الذاكرة بحسب نظام التشغٌل أ ّما البٌانات التً ُتشٌر إلٌها هذه المإ ّ‬ ‫شرات لها حجوم مختلفة فً‬ ‫الذاكرة كما أنها من أنواع مختلفة‪.‬‬ ‫مثال ‪0‬‬ ‫‪a=10 , b=20‬‬

‫‪// my first pointer‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int a = 5, b = 15‬‬ ‫;‪int *ptr‬‬ ‫;‪ptr= &a‬‬ ‫;‪*ptr = 10‬‬ ‫;‪ptr = &b‬‬ ‫;‪*ptr = 20‬‬ ‫;‪cout<<"a="<<a<<" , b="<<b‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪ ‬الحظ أنه تم تعدٌل قٌم ‪ a‬و ‪ b‬بشكل غٌر مباشر حٌث جعلنا المإ ّ‬ ‫شر ‪ٌ ptr‬شٌر إلى ‪ a‬عن‬ ‫طرٌق الرمز & ث ّم أسندنا القٌمة ‪ 10‬إلى ماٌشٌر إلٌه المإ ّ‬ ‫شر ‪ ptr‬وكذلك األمر بالنسبة لـ ‪.b‬‬ ‫ّ‬ ‫‪ ‬كما ٌمكن أن ٌؤخذ المإ ّ‬ ‫شر خبلل البرنامج عناوٌن مختلفة حٌث استخدمنا المإشر ‪ ptr‬لٌشٌر إلى ‪a‬‬ ‫ث ّم إلى ‪.b‬‬ ‫مثال ‪2‬‬ ‫‪a=10 , b=20‬‬

‫‪// more pointers‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;‪int a = 5, b = 15‬‬ ‫;‪int *p1, *p2‬‬ ‫‪ = p1‬عنوان ‪// a‬‬ ‫;‪p1 = &a‬‬ ‫;‪p2 = &b‬‬ ‫‪ = p2‬عنوان ‪// b‬‬ ‫;‪*p1 = 10‬‬ ‫اٌم‪ّ١‬خ اٌز‪٠ ٟ‬ش‪١‬ش ئٌ‪ٙ١‬ب ‪// 12=p1‬‬ ‫;‪*p2 = *p1‬‬ ‫القٌمة التً ٌشٌر إلٌها ‪ = p2‬القٌمة التً ٌشٌر إلٌها ‪// p1‬‬ ‫‪// p1 = p2‬‬ ‫;‪p1 = p2‬‬ ‫القٌمة التً ٌشٌر إلٌها ‪// 32 = p1‬‬ ‫;‪*p1 = 20‬‬ ‫;‪cout << "a=" << a << " , b=" << b‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪:7‬‬


‫المؤ ّ‬ ‫شرات والمصفوفات‬ ‫إنّ المصفوفة تشبه المإ ّ‬ ‫شر إلى ح ّد كبٌر فعندما نصرح عن مصفوفة فإ ّننا نضع فً الذاكرة عنوان أول عنصر‬ ‫ّ‬ ‫ّ‬ ‫من عناصرها كما أ ّننا عندما نصرح عن مإشر فإنه ٌشٌر إلى أول عنصر لذلك فهما متشابهان‪.‬‬ ‫لنفرض التصرٌحٌن التالٌ​ٌن‪:‬‬ ‫;]‪int numbers [20‬‬ ‫;‪int * p‬‬ ‫إنّ اإلسناد ;‪ p = numbers‬صحٌح ألنّ ‪ p‬و ‪ numbers‬متكافبان ولهما نفس الخصابص‪ ,‬االختبلف الوحٌد‬ ‫هو أ ّننا نستطٌع أن نعطً قٌمة مختلفة للمإ ّ‬ ‫شر ‪ p‬فً حٌن أنّ ‪ numbers‬سٌشٌر دوما إلى أول عنصر من‬ ‫شر عادي إلى المتغٌّرات أ ّما ‪ numbers‬فهو مإ ّ‬ ‫العشرٌن عنصر‪ .‬لذلك فإنّ ‪ p‬هو مإ ّ‬ ‫شر ثابت ) اسم المصفوفة‬ ‫هو مإ ّ‬ ‫شر ثابت (‪.‬‬ ‫أمّا اإلسناد ;‪ numbers = p‬فلٌس صحٌحا ألنّ ‪ numbers‬مصفوفة )مإ ّ‬ ‫شر ثابت( وال ٌمكن إسناد قٌمة‬ ‫للمإ ّ‬ ‫شر الثابت‪.‬‬ ‫مثال ‪3‬‬ ‫‪10, 20, 30, 40, 50,‬‬

‫‪// more pointers‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)( ‪int main‬‬ ‫{‬ ‫;]‪int numbers[5‬‬ ‫;‪int * p‬‬ ‫;‪p = numbers; *p = 10‬‬ ‫;‪p++; *p = 20‬‬ ‫;‪p = &numbers[2]; *p = 30‬‬ ‫;‪p = numbers + 3; *p = 40‬‬ ‫;‪p = numbers; *(p+4) = 50‬‬ ‫)‪for (int n=0; n<5; n++‬‬ ‫;" ‪cout << numbers[n] << ",‬‬ ‫;‪return 0‬‬ ‫}‬

‫فً فصل المصفوفات استخدمنا األقواس المربعة للتعامل مع عناصر المصفوفة‪ ,‬هناك طرٌقة مكافبة باستخدام‬ ‫شرات كما ٌلً )إذا كان المإ ّ‬ ‫المإ ّ‬ ‫شر ‪ٌ p‬شٌر إلى المصفوفة ‪:(a‬‬ ‫]‪a[0‬‬ ‫]‪a[1‬‬ ‫]‪a[2‬‬ ‫‪...‬‬ ‫]‪a[i‬‬ ‫‪.‬‬ ‫‪.‬‬

‫‪*p‬‬ ‫)‪*(p+1‬‬ ‫)‪*(p+2‬‬ ‫‪...‬‬ ‫)‪*(p+i‬‬ ‫‪.‬‬ ‫‪.‬‬

‫فإذا أردنا وضع القٌمة ‪ 1‬فً العنصر الخامس للمصفوفة ‪ a‬فهناك طرٌقتان متكافبتان‬ ‫;‪a[5] = 0‬‬ ‫;‪*(p+5) = 0‬‬

‫‪:8‬‬


‫تبدئة المؤ ّ‬ ‫شرات‬ ‫ٌمكن عند التصرٌح عن المإ ّ‬ ‫شرات جعلها تشٌر إلى المتغٌّر المراد أي‬ ‫;‪int number‬‬ ‫;‪int * p = &number‬‬ ‫وهذا ٌكافا‬ ‫;‪int number‬‬ ‫;‪int * p‬‬ ‫;‪p = &number‬‬ ‫شرات ولٌس إسناد قٌم المتغٌّرات للمإ ّ‬ ‫شرات نسند فقط عناوٌن المتغٌّرات للمإ ّ‬ ‫فً المإ ّ‬ ‫شرات‪.‬‬ ‫فبل ٌجوز فً أي مكان عدا مكان التصرٌح أن نكتب ;‪ *p = &number‬ألنّ ‪ *p‬هو قٌمة ماٌشٌر إلٌه المإ ّ‬ ‫شر‬ ‫وال ٌجوز أن نسند إلٌها عنوان المتغٌّر‪.‬‬ ‫أمّا فً حالة المصفوفات فإنّ المترجم ٌسمح لنا بؤن نسند الثابت الذي سٌشٌر إلٌه المإ ّ‬ ‫شر أثناء التصرٌح عن‬ ‫المإ ّ‬ ‫شر )هنا الثابت هو سلسلة رموز(‪:‬‬ ‫;"‪char * p = "hello‬‬ ‫فً هذه الحالة ت ّم حجز حجم ثابت من الذاكرة لتخزٌن السلسة "‪ "hello‬وت ّم جعل المإ ّ‬ ‫شر ‪ٌ p‬شٌر إلى أول‬ ‫رمز )‪ (char‬لمجموعة الحجرات الذاكرٌّة التً ت ّم حجزها أي أنّ ‪ٌ p‬شٌر إلى الحجرة التً تحوي الحرف '‪'h‬‬ ‫فإذا فرضنا أنّ "‪ُ "hello‬خ ّزنت فً العنوان ‪ 2813‬وما بعده فإنّ الذي ت ّم ٌُلخصه الشكل التالً‪:‬‬

‫مصفوفة المؤ ّ‬ ‫شرات‬ ‫ٌمكن أن نع ّرف مصفوفة مإ ّ‬ ‫شرات كما ٌلً ‪:‬‬ ‫;]‪type* name[ELEMENTS‬‬ ‫مثال ‪:‬‬

‫مصفوفة ‪ 4‬مإ ّ‬ ‫شرات على سبلسل ‪//‬‬

‫;]‪char* cars[3‬‬

‫;"‪char[0]="Mercedes‬‬ ‫;"‪char[1]="Nissan‬‬ ‫;"‪char[2]="Ferrari‬‬

‫‪:9‬‬


‫العمل ٌّات الحسابٌة على المؤ ّ‬ ‫شرات‬ ‫العملٌّات الحسابٌة على المإ ّ‬ ‫شرات تختلف قلٌبلعن تلك التً ننفذها على األعداد الصحٌحة إذ ٌمكن أن ننفذ فقط‬ ‫عملٌتً الجمع والطرح أمّا الضرب والقسمة فلٌس لهما أي معنى فى عالم المإ ّ‬ ‫شرات‪ .‬لكن الجمع والطرح لهما‬ ‫شرات وذلك بحسب حجم نوع المعطٌات التً تشٌر إلٌها المإ ّ‬ ‫سلوك مختلف مع المإ ّ‬ ‫شرات‪.‬‬ ‫كما نعلم فإنّ مقدار ما ٌت ّم حجزه من الذاكرة ٌعتمد على نوع المعطٌات فمثبل النوع )‪ٌ (char‬حجز ‪ 2‬باٌت‬ ‫والنوع )‪ٌ (short‬حجز ‪ 3‬باٌت أما النوع )‪ (long‬فٌحجز ‪ 5‬باٌت ولنفرض أ ّنه لدٌنا ثبلثة مإ ّ‬ ‫شرات‬ ‫;‪char *mychar‬‬ ‫;‪short *myshort‬‬ ‫;‪long *mylong‬‬ ‫وبفرض أ ّنها تشٌر إلى حجرات الذاكرة ‪ 4111 , 3111 , 2111‬بالترتٌب فإذا كتبنا‬ ‫;‪mychar++‬‬ ‫;‪myshort++‬‬ ‫;‪mylong++‬‬ ‫عندب ٍذ المإ ّ‬ ‫شر ‪ mychar‬سٌحوي القٌمة ‪ 2112‬و ‪ myshort‬سٌحوي القٌمة ‪ 2113‬و ‪ mylong‬سٌحوي‬ ‫ّ‬ ‫القٌمة ‪ 2115‬وسبب ذلك أننا عندما نضٌف ‪ 2‬إلى المإشر معنى ذلك أننا نجعله ٌشٌر إلى العنصر التالً لنفس‬ ‫النوع الذي عرفناه أي ٌضاف الحجم بالباٌت إلى المإ ّ‬ ‫شر حسب النوع‪.‬‬ ‫حجم النوع )‪ 2 (char‬باٌت لذلك تم إضافة ‪ 2‬إلى المإ ّ‬ ‫شر ‪mychar‬‬ ‫حجم النوع )‪ 2 (short‬باٌت لذلك تم إضافة ‪ 2‬إلى المإ ّ‬ ‫شر ‪myshort‬‬ ‫حجم النوع )‪ 4 (long‬باٌت لذلك تم إضافة ‪ 4‬إلى المإ ّ‬ ‫شر ‪mylong‬‬

‫سٌحدث نفس األمر تماما إذا كتبنا‬ ‫;‪mychar = mychar + 1‬‬ ‫;‪myshort = myshort + 1‬‬ ‫;‪mylong = mylong + 1‬‬

‫‪::‬‬


‫من المهم التنبٌه إلى أنّ معامبل الزٌادة )‪ (++‬والنقصان )‪ (--‬لهما أولوٌّة على معامل المرجع )*( لذلك فإنّ‬ ‫التعابٌر التالٌة ربما تسبب التباس فً فهمها‬ ‫;‪*p++‬‬ ‫;‪*p++ = *q++‬‬ ‫التعبٌر األول مكافا لـ )‪ *(p++‬وهو ٌقوم بزٌادة ‪ 2‬إلى العنوان الذي ٌحوٌه المإ ّ‬ ‫شر ‪ p‬ولٌس القٌمة التً ٌشٌر‬ ‫إلٌها وبالتالً فإنّ القٌمة الجدٌدة التً ٌشٌر إلٌها ‪ p‬هً قٌمة عشوابٌة‪.‬‬ ‫فً التعبٌر الثانً بما أنّ المعاملٌن )‪ (++‬و )‪ (--‬بعد المساواة التً ٌجب أن تتح ّقق فإنّ القٌمة ‪ُ *q‬تسند إلى ‪*p‬‬ ‫ث ّم ٌُزاد ك ّل من ‪ p‬و ‪ q‬بمقدار ‪ 2‬أي التعبٌر الثانً مكافا لـ‬ ‫;‪*p = *q‬‬ ‫;‪p++‬‬ ‫;‪q++‬‬ ‫لذلك ٌنبغً استخدام األقواس لتجنب األخطاء‪.‬‬

‫شرات على المؤ ّ‬ ‫المؤ ّ‬ ‫شرات‬

‫شرات تشٌر إلى مإ ّ‬ ‫ٌمكن فً لغة ‪ C++‬استخدام مإ ّ‬ ‫شرات أخرى والتً تشٌر بدورها إلى بٌانات‪ .‬لفعل ذلك‬ ‫نحتاج فقط إلى أن نضٌف * إلى ك ّل مستوى من التؤشٌر فمثبل‪:‬‬ ‫;‪char a‬‬ ‫;‪char * b‬‬ ‫;‪char ** c‬‬ ‫;'‪a = 'z‬‬ ‫;‪b = &a‬‬ ‫;‪c = &b‬‬

‫بفرض حجرات الذاكرة التً حُجزت عشوابٌا مبٌّنة بالشكل‪:‬‬

‫الجدٌد فً هذا المثال هو المتغٌّر ‪ c‬الذي ٌمكن أن ٌد ّل على ثبلث قٌم مختلفة‬ ‫هو متغٌّر من النوع )** ‪ (char‬وقٌمته ‪8092‬‬ ‫‪c‬‬ ‫‪ *c‬هو متغٌّر من النوع )* ‪ (char‬وقٌمته ‪7230‬‬ ‫‪ **c‬هو متغٌّر من النوع )‪ (char‬وقٌمته '‪'z‬‬ ‫مالحظة‬

‫المؤ ّ‬ ‫شرات الخالٌة (‪)void pointers‬‬

‫‪*c == b == 7230‬‬ ‫'‪**c == *b == a == 'z‬‬

‫المإ ّ‬ ‫شر ذو النوع ‪ٌ void‬مكنه أن ٌشٌر إلى أي نوع من المعطٌات سواء كان صحٌحا )‪ (integer‬أو حقٌقٌا‬ ‫)‪ (float‬أو سلسلة رموز)‪ .(string of characters‬فً هذا النوع من المإ ّ‬ ‫شرات ال نستطٌع أن نستخدم معامل‬ ‫المرجع * بشكل مباشر ألنّ طول المإ ّ‬ ‫شر غٌر معلوم‪ ,‬ولهذا السبب ٌجب علٌنا أن نلجؤ دابما إلى تحوٌل النوع‬ ‫‪ void‬إلى نوع آخر مح َّدد من المعطٌات‪.‬‬

‫‪211‬‬


ّ ‫من فوابد هذا المإ‬ : ً‫شر هو إمكانٌة تمرٌر قٌم عامّة إلى تابع ما كما فً المثال التال‬ // integer increaser #include <iostream> using namespace std;

6, 10, 13

void increase (void* data, int type) { switch (type) { case sizeof(char) : (*((char*)data))++; break; case sizeof(short): (*((short*)data))++; break; case sizeof(long) : (*((long*)data))++; break; } } int main () { char a = 5; short b = 9; long c = 12; increase (&a,sizeof(a)); increase (&b,sizeof(b)); increase (&c,sizeof(c)); cout << (int) a << ", " << b << ", " << c; return 0; }

‫ هو‬sizeof(char) ‫ فمثبل‬,‫ هو تابع مدمج فً اللغة ٌرجع قٌمة ثابتة تمثل الحجم بالباٌت لما بٌن القوسٌن‬sizeof .‫ باٌت‬2 ‫ هو‬char ‫ ألنّ طول النوع‬2

ّ ‫المؤ‬ ‫شرات على التوابع‬

ّ ‫ نصرّ ح عن المإ‬.‫شرات على التوابع ٌمكن أن نم ّرر التابع كمعامل لتابع آخر‬ ّ ‫من خبلل المإ‬ ‫شر على تابع بنفس‬ .* ‫األسلوب الذي نصرّ ح به عن تابع باستثناء أ ّننا نضع االسم بٌن قوسٌن ونسبقه بـ‬ :‫مثال‬ // pointer to functions #include <iostream> using namespace std; int addition(int a, int b) { return (a+b); } int subtraction(int a, int b) { return (a-b); } int (*minus)(int,int) = subtraction;//pointer to function int operation(int x, int y, int (*p)(int,int)) { int g; g = (*p)(x,y); return (g); }

212

8


int main () { int m,n; m = operation(7, 5, addition); n = operation(20, m, minus); cout <<n; return 0; }

ّ ‫ هو مإ‬minus subtraction ‫ أسندنا التابع‬.int ‫ ٌقبل معاملٌن من النوع‬int ‫شر عام على تابع من النوع‬ ّ ‫إلى المإ‬ ‫ فً سطر التعرٌف نفسه‬minus ‫شر‬ int (* minus)(int,int) = subtraction;

213


‫الفصل الثاني شصر‪:‬‬

‫ح ّتى اآلن كان حجز الذاكرة فً برامجنا ٌت ّم أثناء كتابة الكود أي أثناء التصرٌح عن المتغٌّرات المختلفة قبل‬ ‫تنفٌذ البرنامج‪ .‬ولكن ماذا لو احتجنا مقداراا متغ ٌّراا من الذاكرة ٌت ّم تحدٌده أثناء تنفٌذ البرنامج؟‬ ‫مثبل فً حال احتجنا إلى دخل من المستخدم لنحدّد الحجم البلزم حجزه‪.‬‬ ‫اإلجابة على ذلك هً الذاكرة الدٌنامٌكٌة التً من أجلها تحوي ‪ C++‬معاملً ‪ new‬و ‪delete‬‬

‫المعامل ‪new‬‬ ‫‪ ‬لكً نطلب ذاكرة دٌنامٌكٌة نستخدم المعامل ‪ new‬متبوعا بنوع المعطٌات أو متبوعا بنوع المعطٌات و‬ ‫قوسٌن مربعٌن ] [ ٌحوٌان عدد العناصر المطلوبة‪.‬‬ ‫‪ٌ ‬عٌد المعامل ‪ new‬مإ ّ‬ ‫شرا ٌشٌر إلى أول حجرة من حجرات الذاكرة التً ت ّم حجزها‪.‬‬ ‫نستخدمه كما ٌلً‬ ‫;‪pointer = new type‬‬ ‫لحجز ذاكرة تحوي عنصر واحد من نوع المعطٌات‪.‬‬ ‫أو‬ ‫لحجز ذاكرة تحوي مجموعة عناصر)مصفوفة( من نوع المعطٌات ;]‪pointer = new type[elements‬‬ ‫مثال‪:‬‬ ‫;‪int * p‬‬ ‫;]‪p = new int [5‬‬ ‫فً هذه الحالة ٌقوم النظام بحجز مقدار من الذاكرة مإلّف من ‪ 6‬حجرات من النوع ‪ int‬وٌعٌد مإ ّ‬ ‫شرا ٌشٌر‬ ‫إلى أول حجرة من الحجرات الخمس وت ّم إسناد قٌمة هذا المإ ّشر إلى المإ ّ‬ ‫شر ‪. p‬‬ ‫إذا ‪ٌ p‬شٌر إلى أول خانة من ‪ 6‬خانات من النوع ‪ int‬كما فً الشكل‬

‫سابقا عند التصرٌح عن المصفوفة كان ٌجب أن ٌكون عدد العناصر قٌمة ثابتة أمّا فً الذاكرة الدٌنامٌكٌة فٌمكن‬ ‫أن ٌكون عدد العناصر متغٌّرا ٌقوم المستخدم بإدخاله‬ ‫العدٌد من البرامج تستخدم الذاكرة الدٌنامٌكٌة و ٌت ّم أحٌانا استهبلك الذاكرة بشكل كامل لذلك ٌجب التؤكد من أنّ‬ ‫الحجز قد ت ّم بشكل صحٌح عند استخدام ‪ new‬كما ٌلً‬ ‫;‪int * p‬‬ ‫;]‪p = new int [5‬‬ ‫)‪if (p == NULL‬‬ ‫‪exit(1); // error assigning memory.‬‬

‫‪214‬‬


‫المعامل ‪delete‬‬ ‫بعد أن تنتهً حاجتنا إلى الذاكرة التً حجزناها باستخدام ‪ٌ new‬نبغً علٌنا أن نحرّ رها باستخدام المعامل‬ ‫‪ delete‬لكً تصبح متاحة للحجز الحقا‪ ,‬ونستخدمه كما ٌلً‪:‬‬ ‫لتحرٌر الذاكرة المحجوزة لعنصر واحد‬ ‫أو‬ ‫لتحرٌر الذاكرة المحجوزة لعدة عناصر )مصفوفة(‪.‬‬

‫;‪delete pointer‬‬ ‫;‪delete [] pointer‬‬

‫مثال‪:‬‬ ‫‪enter the number of courses: 7‬‬ ‫‪mark 1= 91‬‬ ‫‪mark 2= 78‬‬ ‫‪mark 3= 77‬‬ ‫‪mark 4= 68‬‬ ‫‪mark 5= 83‬‬ ‫‪mark 6= 73‬‬ ‫‪mark 7= 81‬‬ ‫‪average= 78.7143‬‬

‫‪//calculate average using dynamic memory‬‬ ‫>‪#include <iostream‬‬ ‫>‪#include<stdlib.h‬‬ ‫;‪using namespace std‬‬

‫)( ‪int main‬‬ ‫{‬ ‫;‪int n,i,sum=0‬‬ ‫;" ‪cout<<"enter the number of courses:‬‬ ‫;‪cin>>n‬‬ ‫;]‪int *p=new int[n‬‬ ‫;)‪if(p==NULL)exit(1‬‬ ‫)‪for(i=0;i<n;i++‬‬ ‫{‬ ‫;" ="<<‪cout<<"mark "<<i+1‬‬ ‫)‪cin>>p[i];//or cin>>*(p+i‬‬ ‫;]‪sum+=p[i‬‬ ‫}‬ ‫;‪cout<<"average= "<<(float)sum/n<<endl‬‬ ‫;‪delete [] p‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪ NULL‬هً قٌمة ثابتة مع ّرفة فً مكتبات ‪ C++‬لتد ّل على المإ ّ‬ ‫شرات الفارغة )التً ال تشٌر إلى شًء(‪.‬‬ ‫‪#define NULL 0‬‬ ‫فً حال لم تكن معرّ فة فٌمكن أن تع ّرفها بنفسك كما ٌلً‪:‬‬ ‫ال ٌوجد فارق أن تضع ‪ 1‬أو ‪ NULL‬عندما تفحص المإ ّ‬ ‫شرات‪ ,‬ولكن ‪ NULL‬مستخدمة بشكل أكبر وهً أكثر‬ ‫وضوحا أل ّننا نادرا ما نقارن المإ ّ‬ ‫شرات مع قٌم ثابتة أو نسندها إلى أرقام‪.‬‬

‫‪215‬‬


‫الفصل الثالث شصر‪:‬‬

‫تراكٌب المعطٌات‬ ‫تركٌب المعطٌات هو نوع ٌقوم المستخدم بتعرٌفه وٌتؤلف من أنواع مختلفة من البٌانات ذات الحجوم المختلفة‬ ‫مجموعة فً تصرٌح واحد بالشكل ‪:‬‬ ‫{ ‪struct name‬‬ ‫;‪data_type element1‬‬ ‫;‪data_type element2‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫;‪data_type elementN‬‬ ‫; ‪} object1_name, object2_name, … , objectN_name‬‬ ‫‪ :name‬اسم التركٌب‪.‬‬ ‫‪ :object_name‬اسم الكابن الذي نرٌد أن نشتقه من التركٌب )تعرٌفه هنا اختٌاري(‪.‬‬ ‫أنواع البٌانات المختلفة التً ٌحوٌها التركٌب موجودة بٌن القوسٌن { }‪.‬‬ ‫مثال‪:‬‬ ‫{ ‪struct products‬‬ ‫;]‪char name [30‬‬ ‫;‪float price‬‬ ‫;‪} apple, orange, melon‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫عرّ فنا أوال التركٌب ‪ products‬الذي ٌتؤلف من حقلٌن هما ‪ name‬و ‪ price‬ك ّل منهما له نوع‬ ‫مختلف عن نوع اآلخر‪.‬‬ ‫بعد أن عرّ فنا التركٌب قمنا بتعرٌف ثبلثة كابنات من نفس النوع ‪ products‬وهً‪ apple :‬و‬ ‫‪ orange‬و ‪.melon‬‬ ‫ٌمكن أن نشتق الكابنات من التركٌب بطرٌقة أخرى وذلك بؤن نعرف الكابن المشتق باستخدام اسم‬ ‫التركٌب‪ .‬مثبل‪:‬‬ ‫{ ‪struct products‬‬ ‫;]‪char name [30‬‬ ‫;‪float price‬‬ ‫;}‬ ‫;‪products apple‬‬ ‫;‪products orange, melon‬‬ ‫‪216‬‬


‫ كل منهما له نوع مختلف عن نوع‬price ‫ و‬name ‫ الذي ٌتؤلف من حقلٌن هما‬products ‫عرّ فنا أوال التركٌب‬ .‫اآلخر‬ :ً‫( للتصرٌح عن ثبلثة كابنات من النوع نفسه ه‬products) ‫بعد أن عرّ فنا التركٌب استخدمنا اسم التركٌب‬ .melon‫ و‬orange ‫ و‬apple ‫ ٌصبح اسم نوع جدٌد مثل األنواع األساسٌة‬products ّ‫( فإن‬products) ‫ بعد أن صرّ حنا عن التركٌب‬ (‫ وٌصبح بإمكاننا أن نصرح عن كابنات )متغٌّرات‬short ‫ أو‬char ‫ أو‬int ‫المعرفة مسبقا كالنوع‬ .‫من هذا النوع‬ ‫ و‬name ‫ ٌصبح لكل منها حقبلن هما‬melon ‫ و‬orange ‫ و‬apple ‫ بعد أن صرحنا عن الكابنات‬ .‫( ث ّم اسم الحقل‬.) ‫ ٌمكن أن نتعامل مع الحقول بذكر اسم الكابن تلٌه نقطة‬price ‫أمثلة‬ apple.name orange.name char [30] melon.name apple.price orange.price float melon.pric

‫مثال‬ // example about structures #include <iostream> using namespace std; #include <string> struct students{ char name[50]; char city[50]; int tel; }st1,st2; int main() { //filling information cout<<"enter student1 name, city and tel_no: "; cin>>st1.name; cin>>st1.city; cin>>st1.tel; cout<<"enter student2 name, city and tel_no: "; cin>>st2.name; cin>>st2.city; cin>>st2.tel; //printing information cout<<"\nname"<<"\tcity\t"<<"tel_no"; cout<<"\n------------------------\n"; cout<<st1.name<<"\t"<<st1.city<<"\t"<<st1.tel<<endl; cout<<st2.name<<"\t"<<st2.city<<"\t"<<st2.tel<<endl; return 0; }

217


enter student1 name, city and tel_no: Ali Hama 3245675 enter student2 name, city and tel_no: Ahmad Homs 2452658 name city tel_no ---------------------------Ali Hama 3245675 Ahmad Homs 2452658

‫مصفوفة التراكٌب‬ ‫التراكٌب مٌزة كثٌرا ما تستخدم لبناء قواعد المعطٌات خاصة إذا استخدمناها مع المصفوفات حٌث ٌمكن بناء‬ : ً‫مصفوفة تراكٌب باإلعبلن عن التركٌب أوال ث ّم نعلن عن مصفوفة من نوع التركٌب كما ٌل‬ struct name { type element1; type element2; . . type elementN; } object_name [ELEMENTS]; :‫مثال‬ // array of structures #include <iostream> using namespace std; #include <stdlib.h> #define N_BOOKS 5 struct book { char title [50]; int year; } books [N_BOOKS]; void printBook (book mybook); int main () { char buffer [50]; int n; cout<<"please enter the titles and years for 5 books!.\n"; for (n=0; n< N_BOOKS; n++) { cout << "title: "; cin.getline (books[n].title,50); cout << "year: "; cin.getline (buffer,50); books[n].year = atoi(buffer); }

218

Enter Enter Enter Enter Enter Enter Enter Enter Enter Enter

title: java how to program year: 1997 title: eat, pray, love year: 2006 title: advanced memory year: 2005 title: being logical year: 2004 title: c++ how to program year: 2005

You have entered these movies: java how to program (1997) eat, pray, love (2006) advanced memory (2005) being logical (2004) c++ how to program (2005)


cout << "\nYou have entered these books:\n"; for (n=0; n< N_BOOKS; n++) printBook (books[n]); return 0; } void printBook (book mybook) { cout << mybook.title; cout << " (" << mybook.year<< ")\n"; }

ّ ‫التراكٌب و المؤ‬ ‫شرات‬

ّ ‫ٌمكن استخدام للمإ‬ : ً‫شرات لتشٌر إلى التراكٌب كما ٌل‬ struct book { char title [50]; int year; }; book abook; book * pbook; book ‫ هو كابن من النوع‬:abook ّ ‫ هو مإ‬:pbook book ‫شر ٌشٌر إلى كابن من النوع‬ ّ ‫ولجعل المإ‬ ‫ نكتب‬abook ‫ ٌشٌر إلى الكابن‬pbook ‫شر‬ pbook = &abook; ‫مثال‬ // pointers to structures #include <iostream> using namespace std; #include <stdlib.h> struct book { char title [50]; int year; } ; int main () { char buffer[50]; book abook; book * pbook; pbook = &abook; cout<<"please enter a book title and its publish year!.\n"; cout << "title: "; cin.getline (pbook->title,50); cout << "Enter year: "; cin.getline (buffer,50); pbook->year = atoi (buffer); cout << "\nYou have entered:\n"; cout << pbook->title; cout << " (" << pbook->year << ")\n"; return 0; }

219

Enter title: c++ how to program Enter year: 2005 You have entered: c++ how to program (2005)


‫‪‬‬

‫شرات على التراكٌب أو المإ ّ‬ ‫المعامل )>‪ (-‬هو معامل مرجعً ٌستخدم خصٌصا مع المإ ّ‬ ‫شرات على‬ ‫األصناف للوصول إلى الحقول الموجودة فٌها وهو ٌلغً الحاجة الستخدام األقواس فً كل مرة نرٌد‬ ‫أن نصل إلى حقل ما فً تركٌب ما‪.‬‬ ‫‪pbook->title‬‬

‫‪(*pbook).title‬‬

‫كبل العبارتٌن صحٌحتان وتعنٌان أ ّننا نتعامل مع الحقل ‪ title‬المشار إلٌه بالمإ ّ‬ ‫شر ‪pbook‬‬ ‫وٌجب أن نمٌزهما عن العبارتٌن ‪:‬‬ ‫‪*pbook.title‬‬

‫)‪*(pbook.title‬‬

‫اللتٌن تعنٌان أ ّننا نتعامل مع القٌمة المشار إلٌها بالعنصر ‪) title‬الذي ال ٌعتبر مإ ّ‬ ‫شرا باألساس(‬ ‫أي أنّ العبارتٌن األخٌرتان خاطبتان وال تعنٌان شٌبا‪.‬‬ ‫ٌلخص الحاالت الممكنة للمإ ّ‬ ‫الجدول التالً ّ‬ ‫شرات والتراكٌب‬ ‫العببرة‬

‫الوصف‬

‫‪pbook.title‬‬

‫العنصر ‪ title‬من التركٌب ‪pbook‬‬

‫‪pbook->title‬‬

‫العنصر ‪ title‬من التركٌب المشار إلٌه بالمإ ّ‬ ‫شر‬ ‫‪pbook‬‬ ‫القٌمة المشار إلٌها بالعنصر ‪ title‬من التركٌب‬ ‫‪pbook‬‬

‫‪*pbook.title‬‬

‫العببرة المكبفئت‬

‫‪(*pbook).title‬‬ ‫)‪*(pbook.title‬‬

‫التراكٌب المتداخلة‬ ‫تراكٌب أخرى كما فً المثال التالً‪:‬‬ ‫ٌمكن أن تكون التراكٌب حقوال موجودة داخل‬ ‫َ‬ ‫{‪struct books‬‬ ‫;]‪char title [50‬‬ ‫;‪int year‬‬ ‫}‬ ‫{‪struct friends‬‬ ‫;]‪char name [50‬‬ ‫;]‪char email [50‬‬ ‫;‪books favourite_book‬‬ ‫;‪} ahmad,ali‬‬ ‫;‪friends *p = &ahmad‬‬ ‫بعد هذه التصرٌحات ٌمكن أن نستخدم العبارات التالٌة ‪:‬‬ ‫‪ahmad.name‬‬ ‫‪ali.favourite_book.title‬‬ ‫‪ahmad.favourite_book.year‬‬ ‫‪p->favourite_book.year‬‬

‫‪21:‬‬


: ‫اكتب برنامج ٌقوم باستعراض البحة تتضمن‬ . ‫ إدخال اسم جدٌد لطالب‬.2 . ‫ استعراض كل أسماء الطبلب المدخلة‬.3 . ‫ البحث عن طرٌق إدخال اسم الطالب‬.4 . ‫ البحث عن طرٌق إدخال السنة الدراسٌة للطالب‬.5 . ‫ ترتٌب أسماء الطبلب أبجدٌا‬.6 . ‫ الخروج من البرنامج‬.7

#include<iostream> #include<string> using namespace std; #define M 100 int count=0; struct studentsType { string name; int age,year; }student[M]; void add(); void browse(); void searchByName(); void searchByYear(); void order(); int main() { int choice; do { cout<<"please enter your choice!.\n"; cout<<"1-add new student\n2-browse\n3-search by name\n4-search by year" <<"\n5-alphabetical order\n6-exit\n"; cin>>choice; switch(choice) { case 1: add();break; case 2: browse();break; case 3: searchByName();break; case 4: searchByYear();break; case 5:order();break; case 6: return 0; } }while(count<M); return 0; } 221


void add() { cout<<"student name: ";cin>>student[count].name; cout<<"student age: ";cin>>student[count].age; cout<<"student Year: ";cin>>student[count].year; count++; cout<<"\n"; } void browse() { cout<<"name\tage\tyaer\n"; for(int i=0;i<count;i++) cout<<student[i].name<<"\t"<<student[i].age<<"\t"<<student[i].year<<"\n"; cout<<"\n"; } void searchByName() { string name; bool found=false; int i; cout<<"enter name:";cin>>name; for(i=0;i<count;i++) { if(name==student[i].name) { cout<<student[i].name<<"\t"<<student[i].age<<"\t"<<student[i].year<<"\n"; found=true; } } if(!found) cout<<name<<" was not found\n"; cout<<"\n";

} void searchByYear() { int y; bool found=false; int i; cout<<"enter year:";cin>>y; for(i=0;i<count;i++) { if(student[i].year==y) {

222


cout<<student[i].name<<"\t"<<student[i].age<<"\t"<<student[i].year<<"\n"; found=true; } } cout<<"\n"; if(!found) cout<<"no result\n"; } void order() { int i,j; studentsType temp; if(count<2)goto out; for(i=0;i<count;i++) { for(j=0;j<count-1;j++) { if(student[j].name>student[j+1].name) { temp=student[j]; student[j]=student[j+1]; student[j+1]=temp; } } } cout<<"\n"; out:browse(); }

223


‫الفصل الرابع شصر‪:‬‬

‫نوع بٌانا ٍ‬ ‫ت ٌع ّرفه المستخدم )المبرمج (‪ ,‬باإلضافة إلى التراكٌب توجد‬ ‫تعرّ فنا سابقا على التراكٌب التً تعتبر َ‬ ‫أنوع أخرى مثل‪:‬‬

‫صة (‪)typedef‬‬ ‫تعرٌف أنواع خا ّ‬ ‫ٌمكن أن نعرف أنواع خاصّة بنا باالعتماد على أنواع معرّ فة وموجودة مسبقا باستخدام الكلمة المفتاحٌة‬ ‫‪ typedef‬التً ُتستخدم كما ٌلً ‪:‬‬ ‫;‪new_type_name‬‬

‫‪existing_type‬‬

‫‪Typedef‬‬

‫‪ :existing_type‬هو النوع األصلً المعرف فً ‪ C++‬أو أي نوع مع ّرف مسبقا‪.‬‬ ‫‪ :new_type_name‬هو اسم النوع الجدٌد الذي سنعرفه‪ .‬مثبل ‪:‬‬ ‫;‪char C‬‬ ‫;‪unsigned int WORD‬‬ ‫;‪char * string_t‬‬ ‫;]‪char field [50‬‬

‫‪typedef‬‬ ‫‪typedef‬‬ ‫‪typedef‬‬ ‫‪typedef‬‬

‫هنا عرّ فنا أربعة أنواع جدٌدة هً ‪ C‬و ‪ WORD‬و ‪ string_t‬و ‪ field‬على أنها ‪ char‬و ‪unsigned‬‬ ‫‪ int‬و *‪ char‬و ]‪ char[50‬بالترتٌب‪ ,‬وبالتالً ٌمكن استخدام هذه األنواع لتعرٌف متغٌّرات كما ٌلً ‪:‬‬ ‫;‪C achar, anotherchar, *ptchar1‬‬ ‫;‪WORD myword‬‬ ‫;‪string_t ptchar2‬‬ ‫;‪field name‬‬ ‫‪ typedef‬مفٌدة لتعرٌف نوع س ٌُستخدم بكثرة فً البرنامج ومن الممكن أن تحتاج لتغٌ​ٌرهذا النوع فٌما بعد‪,‬‬ ‫كما تستخدم أحٌانا عندما ٌكون اسم النوع طوٌبل وترٌده أن ٌكون مختصرا‪.‬‬

‫الوحدات )‪(Unions‬‬ ‫الـ ‪ union‬هو تركٌب جمٌع عناصره ٌت ّم حجزها فً نفس العنوان الذاكري‪.‬‬ ‫طرٌقة اإلعبلن عنها واستخدامها مشابهة للطرٌقة المتبعة فً التراكٌب لكنّ عملها مختلف تماما‪:‬‬ ‫{ ‪union model_name‬‬ ‫;‪type1 element1‬‬ ‫;‪type2 element2‬‬ ‫;‪type3 element3‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫;‪} object_name‬‬ ‫الحجم الـذي ٌشغله الـ ‪ union‬هو حجم أكبر عنصر فٌه‪.‬‬ ‫‪224‬‬


‫مثبل‪:‬‬ ‫{ ‪union mytypes_t‬‬ ‫;‪char c‬‬ ‫;‪int i‬‬ ‫;‪float f‬‬ ‫;‪} mytypes‬‬ ‫تنتج العناصر ‪:‬‬ ‫‪mytypes.c‬‬ ‫‪mytypes.i‬‬ ‫‪mytypes.f‬‬ ‫كل واحد من هذه العناصر له نوع مختلف ولكنها فً نفس الموقع من الذاكرة وأي تعدٌل على قٌمة أحد‬ ‫العناصر سٌإثر على قٌم كل العناصر‪.‬‬

‫المر ّقمات )‪Enumerations(enum‬‬ ‫ٌسمح هذا النوع بتعرٌف أنواع بٌانات ٌمكن أن تؤخذ قٌم مختلفة محدّدة من قبل المستخدم والشكل العام لها هو ‪:‬‬ ‫{ ‪enum model_name‬‬ ‫‪value1,‬‬ ‫‪value2,‬‬ ‫‪value3,‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫;‪} object_name‬‬ ‫مثال‪:‬‬

‫;}‪enum colors {black, blue, green, cyan, red, purple, yellow, white‬‬ ‫الحظ أ ّننا لم نضمّن أي نوع بٌانات أساسً أي أ ّننا أنشؤنا نوع بٌانات جدٌد دون اإلعتماد على نوع موجود‬ ‫مسبقا وهو النوع ‪ colors‬الذي ٌؤخذ أحد القٌم الموجودة بٌن القوسٌن }{ وعندما نعرّ ف الكابن ‪mycolor‬‬ ‫من هذا النوع فإنّ العبارات التالٌة صحٌحة‪:‬‬ ‫;‪colors mycolor‬‬ ‫;‪mycolor = blue‬‬ ‫;‪if (mycolor == green) mycolor = red‬‬ ‫فً الواقع إنّ البٌانات الموجودة داخل القوسٌن }{ تستبدل بقٌم عددٌة صحٌحة أثناء الترجمة والقٌم االفتراضٌة‬ ‫هً ‪ 2‬ألول عنصر و‪ 1‬للثانً و ‪ 3‬للثالث وهكذا‪...‬‬ ‫أمّا إذا خصّصنا قٌمة ألول عنصر فإنّ قٌمة العنصر الثانً تزٌد عن قٌمة األول بواحد وهكذا‪..‬‬ ‫مثبل إذا كتبنا ‪ black=1‬بدال من ‪ black‬وتركنا العناصر الباقٌة كما هً فإنّ ‪ white‬سٌؤخذ القٌمة ‪.8‬‬

‫‪225‬‬


‫الفصل اخلامس شصر‪:‬‬

‫الملفات تش ّكل أساس التعامل مع الحاسب فعندما تعمل على أي حاسب الب ّد لك من أن تفتح مل ّفا ما أو تكتب على‬ ‫ملف سواء كان هذا الملف نصّا أو صورة أو صوتا‪. ..‬إلخ‪.‬‬ ‫ّ‬ ‫تخزن فً الذاكرة العشوابٌة وٌت ّم فقدانها عند إنهاء‬ ‫فً معظم البرامج التً كتبناها سابقا كانت المعلومات‬ ‫البرنامج فإذا ك ّنا بحاجة لهذه المعلومات فٌمكننا تخزٌنها فً ملفات على القرص الصلب الستعادتها الحقا‪.‬‬ ‫تدعم لغة ‪ C++‬اإلدخال واإلخراج فً الملفات من خبلل الصفوف التالٌة ‪:‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫‪ :ofstream‬صف الملفات الخاص بعملٌات الكتابة )مشتق من الصف ‪( ostream‬‬ ‫‪ :ifstream‬صف الملفات الخاص بعملٌات القراءة )مشتق من الصف ‪( istream‬‬ ‫‪ :fstream‬صف الملفات الخاص بعملٌات القراءة والكتابة )مشتق من الصف ‪(iostream‬‬

‫فتح ملف‬

‫عموما العملٌة األولى التً تن ّفذ على كابن من الصفوف المذكورة هً ربط هذا الكابن بملف حقٌقً أي عملٌة‬ ‫فتح ملف‪ ,‬هذه العملٌة ُت ّ‬ ‫مثل فً البرنامج من خبلل الكابن )‪ (stream‬وأي دخل أو خرج ٌنفذ على هذا الكابن‬ ‫سٌطبق على الملف الحقٌقً‪.‬‬

‫لكً نفتح ملفا عن طرٌق الكابن ‪ stream‬نستخدم تابعه العضوي )(‪ open‬المعرّ ف بالشكل ‪:‬‬ ‫;)‪mode‬‬

‫‪void open (const char * filename, openmode‬‬

‫‪ :filename‬سلسلة رموز تمثل اسم الملف المراد فتحه‪.‬‬ ‫‪ :mode‬وضعٌة الفتح وهً مزٌج من األوضاع المبٌنة بالجدول ‪:‬‬ ‫‪ios::in‬‬ ‫‪ios::out‬‬ ‫‪ios::ate‬‬ ‫‪ios::app‬‬ ‫‪ios::trunc‬‬ ‫‪ios::binary‬‬

‫فتح الملف للقراءة‬ ‫فتح الملف للكتابة‬ ‫الوضع االبتدابً ‪ :‬نهاٌة الملف‬ ‫كل خرج ٌضاف إلى نهاٌة الملف‬ ‫إذا كان الملف موجود سابقا فٌت ّم حذفه‬ ‫الوضع الثنابً‬

‫ٌمكن الجمع بٌن هذه األوضاع بالمعامل "أو" الثنابً |‪ .‬مثبل إذا أردنا فتح الملف "‪ "example.bin‬فً‬ ‫الوضع الثنابً إلضافة بٌانات ٌمكن أن نفعل ذلك باستدعاء التابع العضوي ‪ open‬كالتالً‪:‬‬ ‫;‪ofstream file‬‬ ‫;)‪file.open ("example.bin", ios::out | ios::app | ios::binary‬‬ ‫لكل تابع ‪ open‬من التوابع الخاصة بالصفوف ‪ ofstream‬و ‪ ifstream‬و ‪ fstream‬وضع افتراضً‬ ‫خاص ٌختلف من صف إلى آخر كما فً الجدول ‪:‬‬ ‫الصف‬ ‫‪ofstream‬‬ ‫‪ifstream‬‬ ‫‪fstream‬‬

‫الوضع االفتراضً للفتح‬ ‫‪ios::out | ios::trunc‬‬ ‫‪ios::in‬‬ ‫‪ios::in | ios::out‬‬

‫‪226‬‬


‫تطبق القٌمة االفتراضٌة فقط فً حال ت ّم استدعاء التابع بدون تخصٌص البارامتر ‪.mode‬‬ ‫‪‬‬

‫بما أنّ العملٌة األولى التً تنفذ على الكابن من الصفوف السابقة هً عملٌة فتح ملف فإنّ كبل من هذه‬ ‫الصفوف الثبلثة ٌحتوي على مشٌد )بانً( ٌقوم باستدعاء التابع ‪ open‬بنفس البارامترات‪ ,‬لذلك ٌمكننا‬ ‫أن نعرّ ف الكابن ونستدعً التابع بسطر واحد كما ٌلً‪:‬‬ ‫;)‪ofstream file ("example.bin", ios::out | ios::app | ios::binary‬‬

‫ٌمكنك التحقق من أنّ الملف قد فُتح بشكل صحٌح باستدعاء التابع العضوي )(‪is_open‬‬ ‫هذا التابع ٌُعٌد ‪ true‬إذا ت ّم ربط الكابن بالملف بشكل صحٌح ّ‬ ‫وإال فإ ّنه ٌُعٌد ‪.false‬‬

‫;)(‪bool is_open‬‬

‫إغالق ملف‬ ‫عندما تنتهً عملٌات القراءة أو الكتابة أو فً حال اكتمال الملف فٌجب إغبلقه لٌصبح متاحا لبلستخدام ثانٌة‪.‬‬ ‫لفعل ذلك نستدعً التابع العضوي )(‪ close‬المعرّ ف كما ٌلً‪:‬‬ ‫;)( ‪void close‬‬ ‫بعد استدعاء هذا التابع ٌصبح الكابن ‪ stream‬جاهزا لفتح ملف آخر‬ ‫‪ ‬فً حالة هدم الكابن وهو ماٌزال مرتبط بالملف فإنّ الهادم ٌستدعً التابع ‪ close‬تلقابٌا‪.‬‬

‫صٌة‬ ‫الملفات الن ّ‬ ‫الصفوف ‪ ofstream‬و ‪ ifstream‬و ‪ fstream‬مشتقة من الصفوف ‪ ostream‬و ‪ istream‬و‬ ‫‪ iostream‬لذلك فإنّ كابنات الـ ‪ٌ fstream‬مكنها أن تستخدم عناصر الصفوف األصلٌة لتصل إلى‬ ‫المعطٌات‪ ,‬أي ٌمكننا أن نستخدم ‪ cin‬و ‪ cout‬مع الكابنات التً نعرّ فها كما فً المثال التالً حٌث نستخدم‬ ‫معامل اإلدخال << الذي ت ّم إعادة تحمٌله‬ ‫‪file example.txt‬‬ ‫‪This is a line.‬‬ ‫‪This is another line.‬‬

‫‪// writing on a text file‬‬ ‫>‪#include <iostream‬‬ ‫>‪#include <fstream‬‬ ‫;‪using namespace std‬‬ ‫{ )( ‪int main‬‬ ‫;)"‪ofstream examplefile ("example.txt‬‬ ‫))(‪if (examplefile.is_open‬‬ ‫{‬ ‫;"‪examplefile << "This is a line.\n‬‬ ‫;"‪cout<< "This is a line.\n‬‬ ‫;"‪examplefile << "This is another line.\n‬‬ ‫;"‪cout<< "This is another line.\n‬‬ ‫;)(‪examplefile.close‬‬ ‫}‬ ‫;"‪else cout<<"Unable to open the file‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪227‬‬


‫كما أنّ إدخال البٌانات من ملف ٌنفذ بنفس الطرٌقة التً نستخدم بها ‪:cin‬‬ ‫‪// reading a text file‬‬ ‫>‪#include <iostream‬‬ ‫>‪#include <fstream‬‬ ‫>‪#include <stdlib.h‬‬ ‫;‪using namespace std‬‬

‫‪This is a line.‬‬ ‫‪This is another line.‬‬

‫{ )( ‪int main‬‬ ‫;]‪char buffer[256‬‬ ‫;)"‪ifstream examplefile ("example.txt‬‬ ‫))(‪if (! examplefile.is_open‬‬ ‫} ;)‪{ cout << "Error opening file"; exit (1‬‬ ‫) )(‪while (! examplefile.eof‬‬ ‫{‬ ‫;)‪examplefile.getline (buffer,100‬‬ ‫;‪cout << buffer << endl‬‬ ‫}‬ ‫;‪return 0‬‬ ‫}‬

‫‪‬‬ ‫‪‬‬

‫هذا البرنامج ٌقوم بقراءة ملف نصًّ وٌطبع محتواه على الشاشة‪.‬‬ ‫التابع العضوي )(‪ٌ eof‬عٌد ‪ true‬عند الوصول إلى نهاٌة الملف‪.‬‬

‫التحقق من الحالة‬ ‫باإلضافة إلى التابع )(‪ eof‬توجد توابع عضوٌة أخرى للتحقق من حالة الكابن )الملف( تعٌد كلها قٌم منطقٌة‬ ‫)‪(bool‬‬ ‫)(‪:bad‬‬ ‫ٌعٌد ‪ true‬إذا حدث خطؤ فً عملٌة القراءة أو الكتابة‪ .‬مثبل إذا حاولنا الكتابة على ملف غٌر مفتوح ألجل‬ ‫الكتابة‪.‬‬ ‫)(‪:fail‬‬ ‫ٌعٌد ‪ true‬كما فً حالة التابع )(‪ bad‬كما ٌعٌد ‪ true‬فً حال حدوث خطؤ فً صٌغة الملف كما فً حالة‬ ‫قراءة عدد صحٌح وت ّم إدخال حرف‪.‬‬ ‫)(‪:good‬‬ ‫ٌعٌد ‪ false‬فً نفس الحاالت التً تعٌد فٌها التوابع السابقة ‪.true‬‬ ‫لتصفٌر عبلمات الحالة التً ت ّم فحصها بالتوابع السابقة نستخدم التابع )(‪ clear‬بدون وسطاء‪.‬‬

‫مؤ ّ‬ ‫شرا التدفق (‪ get‬و ‪)put‬‬ ‫جمٌع كابنات التدفق الخاصة بالدخل والخرج تحوي مإ ّ‬ ‫شرا واحدا على األقل‪:‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫‪ ifstream‬مثل ‪ٌ istream‬حوي المإ ّ‬ ‫شر ‪ get‬الذي ٌشٌر إلى العنصر التالً المراد قراءته‪.‬‬ ‫ّ‬ ‫‪ ofstream‬مثل ‪ٌ ostream‬حوي المإشر ‪ put‬الذي ٌشٌر إلى المكان الذي سٌكتب فٌه العنصر التالً‪.‬‬ ‫وأخٌرا ‪ fstream‬مثل ‪ٌ iostream‬رث ّ‬ ‫كبل من ‪ get‬و ‪.put‬‬

‫‪228‬‬


‫ٌمكن التعامل مع هذه المإ ّ‬ ‫شرات من خبلل التوابع التالٌة‪:‬‬ ‫)(‪ tellg‬و )(‪tellp‬‬ ‫هذان التابعان ال ٌقببلن وسطاء وٌعٌدان قٌمة من النوع ‪ pos_type‬وهً قٌمة من النوع الصحٌح )‪(integer‬‬ ‫شر ‪) get‬فً حالة التابع )(‪ ( tellg‬أو مكان المإ ّ‬ ‫تمثل المكان الحالً للمإ ّ‬ ‫شر ‪) put‬فً حالة التابع )(‪.(tellp‬‬ ‫)(‪ seekg‬و )(‪seekp‬‬ ‫ّ‬ ‫ٌقوم هذان التابعان بتغٌ​ٌر مكانً المإشرٌن ‪ get‬و ‪ put‬وت ّم إعادة تحمٌلهما كما ٌلً ‪:‬‬ ‫;) ‪seekg ( pos_type position‬‬ ‫;) ‪seekp ( pos_type position‬‬ ‫باستخدام هذا الشكل ٌت ّم تحوٌل المإ ّ‬ ‫شر إلى مكان ٌبعد بعدا ثابتا عن بداٌة الملف والوسٌط المطلوب من نفس‬ ‫النوع الذي ٌعٌدانه التابعان )(‪ tellg‬و )(‪.tellp‬‬ ‫;) ‪seekg ( off_type offset, seekdir direction‬‬ ‫;) ‪seekp ( off_type offset, seekdir direction‬‬ ‫باستخدام هذا الشكل ٌت ّم تحوٌل المإ ّ‬ ‫شر إلى مكان ٌبعد بعدا ثابتا عن نقطة معٌنة بحٌث‪:‬‬ ‫‪ :off_type‬نوع مكافا للنوع ‪.long‬‬ ‫‪ :direction‬الوجهة التً سٌتم نقل المإ ّ‬ ‫شر إلٌها وٌجب أن تؤخذ إحدى الحاالت التالٌة‪:‬‬ ‫‪ ios::beg‬إلى بداٌة الملف‬ ‫‪ ios::cur‬من المكان الحالً للمإ ّ‬ ‫شر‬ ‫‪ ios::end‬إلى نهاٌة الملف‬ ‫المثال التالً ٌستخدم التوابع المذكورة لحساب حجم ملف ثنابً‪:‬‬ ‫‪size of example.txt is 40 bytes.‬‬

‫‪// obtaining file size‬‬ ‫>‪#include <iostream‬‬ ‫>‪#include <fstream‬‬ ‫;‪using namespace std‬‬ ‫;"‪const char * filename = "example.txt‬‬ ‫{ )( ‪int main‬‬ ‫;‪long l,m‬‬ ‫‪ifstream file (filename,‬‬ ‫;)‪ios::in|ios::binary‬‬ ‫;)(‪l = file.tellg‬‬ ‫;)‪file.seekg (0, ios::end‬‬ ‫;)(‪m = file.tellg‬‬ ‫;)(‪file.close‬‬ ‫;‪cout << "size of " << filename‬‬ ‫;"‪cout << " is " << (m-l) << " bytes.\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪229‬‬


‫الفصل السادس شصر‪:‬‬

‫مالحظة‪ :‬معالجة االستثناءات من المٌزات الحدٌثة التً ت ّم إنتاجها مع لغة ‪ ANSI-C++‬القٌاسٌة‪.‬‬ ‫لذلك إذا كنت تستعمل مترجما ا ال ٌدعم هذه اللغة القٌاس ٌّة فمن الممكن ّأال تكون قادراا على‬ ‫استخدامها‪.‬‬

‫أثناء تطوٌر البرنامج قد نتعرض لمواقف ال نستطٌع فٌها أن نح ّدد فٌما إذا كانت هذه الشٌفرة ستعمل بالشكل‬ ‫الصحٌح أو ال وذلك أل ّنه قد تكون هناك بعض الحاالت التً ال نتو ّقع حدوثها والتً قد تتسبب بخطؤ فً‬ ‫البرنامج‪ .‬مثل هذه المواقف هو ما ندعوه باالستثناءات‪.‬‬ ‫وأخٌرا قدمت ‪ C++‬ثبلث معامبلت جدٌدة )‪ (try, throw, catch‬لتساعدنا فً معالجة هذه الحاالت وهً‬ ‫تؤخذ الشكل التالً‪:‬‬ ‫{ ‪try‬‬ ‫اٌش‪١‬فشح اٌز‪ ٟ‬عزؼًّ أ ّ‪ٚ‬لً ‪//‬‬ ‫‪٠‬شعً ِزغ‪ّ١‬شاً ‪٠‬غزخذَ ٌّؼشفخ العزضٕبء اٌؾبطً‪throw exception; //‬‬ ‫}‬ ‫)‪catch (type exception‬‬ ‫{‬ ‫اٌش‪١‬فشح اٌز‪ ٟ‬ع‪١‬زُ رٕف‪١‬ز٘ب ؽ‪٠ ٓ١‬ؾذس العزضٕبء ‪//‬‬ ‫}‬ ‫وهً تعمل بالطرٌقة التالٌة‪:‬‬ ‫الشٌفرة داخل التعلٌمة ‪ُ try‬تن َّفذ بشكل طبٌعً‪ ,‬وبمجرّ د حصول استثناء ما ٌت ّم استدعاء التعلٌمة ‪throw‬‬ ‫التً تعٌد وسٌطا قٌمته وصفٌ لبلستثناء الحاصل و ٌؤخذ )الوسٌط( أي نوع مناسب لبلستثناء‪.‬‬ ‫إذا حصل االستثناء فإنّ التعلٌمة ‪ catch‬ستعمل على استقبال الوسٌط الممرّ ر من التعلٌمة ‪ throw‬و ّإال‬ ‫فإنّ التعلٌمة ‪ catch‬لن تن ّفذ‪.‬‬

‫‬‫‬‫مثال ‪:‬‬

‫‪Exception: Out of range‬‬

‫‪// exceptions‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ )( ‪int main‬‬ ‫;]‪char myarray[10‬‬ ‫‪try‬‬ ‫{‬ ‫)‪for (int n=0; n<=10; n++‬‬ ‫;"‪{ if (n>9) throw "Out of range‬‬ ‫;'‪myarray[9]='z‬‬ ‫}‬ ‫}‬ ‫)‪catch (char * str‬‬ ‫} ;‪{ cout << "Exception: " << str << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪22:‬‬


‫ عندها فإنّ التعلٌمة التً ستن ّفذ هً تلك‬.‫ لٌقبل أكثر من نوع من الوسطاء‬catch ‫ٌمكننا أن نعٌد تحمٌل المعامل‬ .throw ‫التً تقابل الحالة الحاصلة وٌتعرّ ف المترجم علٌها من خبلل الوسٌط المرسل من التعٌمة‬ : ‫مثال‬ // exceptions: multiple catch blocks #include <iostream> using namespace std; int main () { try { char * mystring; mystring = new char [10]; if (mystring == NULL) throw "Allocation failure"; for (int n=0; n<=100; n++) { if (n>9) throw n; mystring[n]='z'; } } catch (int i) { cout << "Exception: "; cout << "index " << i << " is out of range" << endl; } catch (char * str) { cout << "Exception: " << str; } return 0; }

Exception: index 10 is out of range

: ‫فً هذا المثال ٌوجد احتماالن لحدوث استثنابٌن مختلفٌن‬ ‫ عندها سٌت ّم‬mystring ‫األول هو أ ّال ٌت ّم إسناد أيّ حرف من الحروف العشر المشكلة للمصفوفة‬ ّ .catch( char * str ){…} ‫استدعاء التعلٌمة‬ .catch ( int i ) {…} ‫ عندها ُتستدعى التعلٌمة‬9 ‫ القٌمة أكبر من‬i ‫الثانً عندما ٌؤخذ العدّاد‬

231

-


‫القسم الثالث‬ ‫إذا غامرت يف َشر ٍ‬ ‫ف َم ُر ِوم‬ ‫َْ َ‬ ‫َ‬ ‫فطَ ْع ُِ امل ْو ِت يف ْأم ٍر َح ِق ٍي‬ ‫َ‬ ‫جز َع ْق ٌل‬ ‫الع‬ ‫ن‬ ‫أ‬ ‫ناء‬ ‫َيرى اجلُبَ ُ ّ َ َ‬ ‫جاع ٍة يف امل ْرِء تُغين‬ ‫كل َش َ‬ ‫و ّ‬ ‫َ‬ ‫وكِ من عائِ ٍ‬ ‫صحيحاً‬ ‫ب ْقولً َ‬ ‫ْ‬ ‫ِ‬ ‫وِ‬ ‫لك ْن‬ ‫ُ‬ ‫تأخ ُذ اآلذا ُن مْنهُ‬

‫فَال تَقنَ ْع مبا دو َن‬ ‫كطَ ْع ِ امل ْو ِت يف ْأم ٍر‬ ‫َ‬ ‫ديعةُ الطّب ِع‬ ‫خ‬ ‫وتهِ ه ه ه ه ه ه َ‬ ‫مك َ َ‬ ‫ِ‬ ‫جاع ِة يف‬ ‫ثل ّ‬ ‫الش َ‬ ‫ول م َ‬ ‫وآفَهتُهُ ِم َن ال َف ُْ ِ​ِ‬ ‫عمى قَ َد ِر ال َقَرائِ ِح‬

‫الن ِ‬ ‫جوم‬ ‫ّ‬ ‫َعظي ِ‬ ‫المّئي ِ‬ ‫احلَكي ِ‬ ‫السقي ِ‬ ‫ّ‬ ‫والعُ​ُز ِوم‬ ‫المتنبّي‬

‫‪232‬‬


‫الفصل السابع شصر‪:‬‬

‫مق ّدمة‪:‬‬ ‫ح ّتى هذه اللحظة ك ّل البرامج التً كتبناها كانت من نمط البرمجة الهٌكل ٌّة أي أنّ البرنامج له مسار مح ّدد ال‬ ‫ٌمكن أن ٌتغ ٌّر‪ ,‬وٌواجه المبرمجون مشاكل عدٌدة فً هذا النمط من البرمجة حٌث تصبح عمل ٌّة تت ُّبع األخطاء و‬ ‫التعدٌل على البرنامج صعبة ج ّدا ح ّتى مع استخدام التوابع ففً البرامج الكبٌرة والتً ٌعمل على إنجازها‬ ‫عشرات المبرمجٌن سٌكون من الصعب تقسٌم العمل بحٌث نضمن فصبل تامّا لما سٌقوم به ك ّل مبرمج لذلك ت ّم‬ ‫تصمٌم هذا المبدأ الجدٌد لٌح ّل مح ّل سابقه وقد اع َت َم َد هذا المبدأ على التفكٌر بالبرامج على أ ّنها مجموعة من‬ ‫الكابنات تربط بٌنها عبلقات منطقٌّة معٌّنة تماما كما ٌحدث فً حٌاتنا الٌومٌّة‪.‬‬ ‫ما هً الكائنات؟ الكابنات هً األشٌاء!‪ .‬أجل انظر من حولك فك ّل األشٌاء التً تراها هً كابنات‪ ,‬وك ّل الكابنات‬ ‫التً تصادفها تمتلك صفات خاصة بها تمٌزها عن غٌرها وقد تمتلك بعض الصفات المشتركة مع كابنات‬ ‫أخرى‪ .‬لنؤخذ المثال التالً‪:‬‬

‫إنّ ك ّل مربع من هذه المربعات هو عبارة عن صفّ مستق ٍّل بح ّد ذاته عن اآلخرٌن فً الصفات الخاصّة به‬ ‫)كاالسم والطول ولون البشرة‪ (...‬وهو ٌشبه البقٌّة فً صفاته العامّة األخرى )كل األحٌاء تتنفّس وتؤكل وتنتقل‬ ‫وتتكاثر‪ .(...‬وقٌاسا على ذلك ٌمكننا أن نحوّ ل كل األشٌاء التً من حولنا إلى صفوف ونقو َم ببرمجتها لتإدّي‬ ‫الوظابف المطلوبة منها ولتسهٌل هذه العملٌّة سنقوم بكتابة الشٌفرة )التً تحتوي على بٌانات وصفات هذا‬ ‫الصفّ ( ث ّم نستطٌع أن ننشؤ كابنات عدٌدة من هذا الصفّ الذي ّ‬ ‫ٌمثل مرجعا لك ّل الكابنات من نوعه ومثال ذلك‬ ‫ك ٌّل من الج ّد واألب واالبن فً مثالنا السابق هً صفوف مستقلّة لكنّ عصام وخالد هما كابنٌن من صفّ االبن‬ ‫وكل كابن منهما ٌختلف عن الكابن اآلخر فً بعض الصفات‪.‬‬ ‫الخبلصة إنّ الصفّ ّ‬ ‫صة‬ ‫ٌمثل المرجع العام للنوع‪ .‬أ ّما الكابن فهو نسخة من هذا الصفّ ٌمتلك بٌاناته الخا ّ‬ ‫والمختلفة عن باقً الكابنات المنشؤة من هذا النوع‪.‬‬ ‫مالحظة‪ :‬البنٌة األساسٌّة فً البرامج الهٌكلٌّة هً التوابع‪.‬‬ ‫أمّا فً البرمجة كابنٌّة التوجّ ه فالبنٌة األساسٌّة هً الصفوف‪.‬‬

‫‪233‬‬


‫صف‪ :‬هو طرٌقة منطق ٌّة لترتٌب البٌانات والتوابع فً بنٌة واحدة‪.‬‬ ‫ال ّ‬ ‫ٌصرّ ح عن الصفّ باستخدام الكلمة المحجوزة ‪ class‬والتً تقابل من الناحٌة الوظٌف ٌّة الكلمة المحجوزة ‪struct‬‬ ‫فً لغة ‪ C‬مع قدرتها على احتواء التوابع كؤعضاء‪ ,‬بدال من احتوابها على بٌانات فقط كما فً ‪ struct‬وٌكمننا‬ ‫القول‪" :‬إنّ ‪ struct‬هو نوع خاص من الصفوف"‪.‬‬ ‫الصفوف هً أنواع جدٌدة من تعرٌف المستخدم‪.‬‬ ‫ٌمكننا أن نعرّ ف الصفّ بالشكل ‪:‬‬ ‫{ ‪class class_name‬‬ ‫;‪member0‬‬ ‫‪permission_label_1:‬‬ ‫;‪member1‬‬ ‫‪permission_label_2:‬‬ ‫;‪member2‬‬ ‫‪...‬‬ ‫;‪} object_name‬‬ ‫‪ :class‬هً كلمة محجوزة ُتستخدم للتصرٌح عن صفّ جدٌد‪.‬‬ ‫‪ :class_name‬هو اسم الصفّ )النوع من تعرٌف المستخدم(‪.‬‬ ‫ٍّ‬ ‫مشتق‬ ‫‪ :object_name‬اسم الكابن ال ُمشتق من الصفّ وهو اختٌاري‪ ,‬و ٌمكن أن ٌكون هناك أكثر من كابن‬ ‫عندها نفصل بٌن أسمابها بفاصلة عاد ٌّة تماما كما فعلنا فً ‪.struct‬‬ ‫جسم الصفّ ٌمكن أن ٌحتوي على أعضاء واألعضاء إمّا أن تكون تصرٌحات عن بٌانات )متغٌّرات( أو عن‬ ‫توابع‪ ,‬وهناك مستوى الوصول )السماح( وهو اختٌاريّ وٌكون إحدى الكلمات المحجوزة الثبلث التالٌة‪:‬‬ ‫وصول مع ٌّ ٍن وهً تختلف عن‬ ‫‪ private, public, protectd‬والتً توضع قبل األعضاء إلكسابها مستوى‬ ‫ٍ‬ ‫بعضها كما سنب ٌّن فً الفقرة التالٌة‪.‬‬

‫معرفات الوصول ‪Access modifieres‬‬ ‫ّ‬ ‫ُ‬ ‫ثبلث معرّ فا ٍ‬ ‫ت تحدّد المدى الذي سٌظهر‬ ‫تقدّم ‪ C++‬ما ٌُدعى بمعرّ فات الوصول أو ‪ Access modifieres‬وهً‬ ‫فٌه العضو وهً ‪:‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬

‫‪ : private‬األعضاء من هذا النوع فً صفّ ما ٌمكن الوصول إلٌها فقط من أعضاء الصفّ نفسه أو‬ ‫من أي صفّ من النوع ‪ friend‬الذي ٌمكن ألعضابه أن ٌصِ لوا إلٌها )األعضاء ‪.(private‬‬ ‫‪ : protected‬األعضاء من هذا النوع فً صفّ ما ٌمكن الوصول إلٌها من الصفّ نفسه أو من أيّ‬ ‫صفّ من النوع ‪ friend‬وكذلك من أعضاء الصفوف التً ٌت ّم اشتقاقها من هذا الصفّ ‪.‬‬ ‫‪ : public‬األعضاء فً هذا المستوى ٌمكن الوصول إلٌها من أيّ مكان ٌظهر فٌه الصفّ الذي‬ ‫ٌحوٌها‪.‬‬

‫مالحظة‪ :‬لو صرّ حنا عن أعضاء فً صفّ ما قبل أن نضع أيّ معرّ ف وصول فإنّ هذه األعضاء‬ ‫س ُتعتبر من المستوى ‪ private‬أل ّنه ٌعتبر مستوى الوصول االفتراضً لؤلعضاء التً ٌُصرّ ح‬ ‫آخر‪.‬‬ ‫عنها فً أيّ صفّ ما لم نحدّد لها مستوى َ‬ ‫‪234‬‬


‫مثال‪:‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int x, y‬‬ ‫‪public:‬‬ ‫;)‪void set_values (int,int‬‬ ‫;)‪int area (void‬‬ ‫;‪} rect‬‬ ‫فً هذا المثال قمنا بالتصرٌح عن صفّ )نوع( أسمٌناه ‪ CRectangle‬ث ّم أنشؤنا منه كابنا دعوناه ‪ .rect‬هذا‬ ‫الصفّ ٌحتوي أربعة أعضاء‪ ,‬متغٌّرٌن )‪ (x, y‬من النوع ‪ int‬وهما من المستوى ‪ private‬أل ّنه المستوى‬ ‫وصول كما قلنا‪ ,‬و ٌحتوي أٌضا على تابعٌن )(‪set_values‬‬ ‫االفتراضً لؤلعضاء إن لم نح ِّدد لها أيّ مستوى‬ ‫ٍ‬ ‫و )(‪ area‬فً المستوى ‪ , public‬و قد صرّ حنا عنهما بالشكل ‪ prototype‬كما تبلحظ‪.‬‬ ‫ّ‬ ‫المشتق منه‪ ,‬فً المثال السابق اسم الصفّ هو ‪ Crectangle‬الذي‬ ‫الحظ الفرق بٌن اسم الصفّ و اسم الكابن‬ ‫ٌمثل اسم النوع الجدٌد الذي عر ّفناه‪ ,‬بٌنما اسم الكابن هو ‪ rect‬وهو من نوع الصفّ )أل ّنه اش ُت َّق منه(‪ٌ .‬مكن‬ ‫توضٌح هذه المسؤلة من خبلل المثال التالً‪:‬‬ ‫;‪rect‬‬

‫‪CRectangle‬‬

‫; ‪CRectangle rect‬‬

‫; ‪a‬‬

‫‪int‬‬

‫; ‪int a‬‬

‫‪ int‬هو اسم الصفّ )النوع(‪ ,‬بٌنما ‪ a‬هو اسم الكابن ال ُم ّ‬ ‫شتق من الصفّ )النوع( ‪.int‬‬ ‫أثناء كتابة التعلٌمات داخل البرنامج ٌمكننا أن نشٌر إلى أيّ عضو عام )من المستوى ‪ (public‬للكابن ‪ rect‬كما‬ ‫العضو )كما فعلنا مع ‪struct‬‬ ‫اسم‬ ‫ِ‬ ‫لو كان تابعا أو متغٌّرا عادٌّا‪ ,‬وذلك فقط بوضع اسم الكابن متبوعا بنقطة ث ّم ِ‬ ‫فً ‪ .(C‬مثال‪:‬‬ ‫; )‪rect.set_value(3,4‬‬ ‫;)(‪myarea = rect.area‬‬ ‫لكن ال ٌمكننا أن نفعل ذلك مع العضوٌن ‪ x, y‬أل ّنهما من المستوى الخاص )‪ (private‬أي أ ّنه ال ٌمكن الوصول‬ ‫إلٌهما ّإال من داخل الصفّ ‪ CRectangle‬الذي ُعرِّ فا داخله‪ .‬إلٌك اآلن المثال كامبل‪:‬‬ ‫‪area: 12‬‬

‫‪// classes example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int x, y‬‬ ‫‪public: // permission_label_1:‬‬ ‫;)‪void set_values (int,int‬‬ ‫};)‪int area (void) {return (x*y‬‬ ‫;}‬ ‫{ )‪void CRectangle::set_values (int a, int b‬‬ ‫;‪x = a‬‬ ‫;‪y = b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫; ‪CRectangle rect; // like int a‬‬ ‫;)‪rect.set_values (3,4‬‬ ‫;‪cout << "area: " << rect.area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪235‬‬


‫الشًء الجدٌد فً هذا المثال هو معامل المدى ‪ ::‬الذي ظهر فً تعرٌف التابع )(‪ set_values‬حٌث اس ُتخدِم‬ ‫من أجل التصرٌح عن العضو )(‪ set_values‬خارج الصفّ الذي عُرِّ ف فٌه‪.‬‬ ‫الحظ أ ّننا قمنا بكتابة جسم )سلوك( التابع العضو )(‪ area‬داخل الصفّ ‪ CRectangle‬فً حٌن صرّ حنا عن‬ ‫التابع )(‪ set_values‬بالتعرٌف المبدبً للتوابع ‪ prototype‬كً نستطٌع كتابة جسمه خارج الصفّ ‪ .‬فً هذه‬ ‫عضو ما خارج الصفّ الذي ٌحوٌه ٌجب علٌنا أن نستخدم‬ ‫تابع‬ ‫ٍ‬ ‫الحالة عندما نرغب بكتابة جسم )سلوك( ٍ‬ ‫المعامل ‪.::‬‬

‫معامل المدى ‪::‬‬ ‫ٌحدّد هذا المعامل إلى أيّ صفّ ٌنتمً هذا العضو‪ ,‬وهذا المعامل ٌمنح التصرٌح عن العضو خارج الصفّ نفس‬ ‫صفات المدى للعضو عندما ٌُع ّرف داخل الصفّ ‪.‬‬ ‫ِب‬ ‫فً المثال السابق استطعنا الوصول إلى المتغٌّرٌن ‪ x, y‬فً التابع )(‪ set_values‬علما أنّ جسم التابع ُكت َ‬ ‫خارج الصفّ وأ ّنهما عضوٌن فً الصفّ ‪ CRectangle‬وهما من المستوى الخاص)‪ (private‬أي أ ّنه ال ٌمكن‬ ‫الوصول إلٌهما ّإال من داخل الصفّ كما أسلفنا سابقا‪.‬‬ ‫مثال ٌوضح كٌف ٌمكننا باستخدام هذا المعامل الوصول إلى المتغٌّرات الشاملة فً برنامجنا‪.‬‬ ‫‪0‬‬ ‫‪0‬‬

‫‪150‬‬ ‫‪0‬‬

‫‪// example on Scope Operator ::‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫)‪int x ,y ; //Auto Initializing to 0 (global var's‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;‪int x = 150‬‬ ‫;‪cout<< x << "\t"<< y << endl‬‬ ‫;‪cout<< ::x << "\t" << y << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫الفرق الوحٌد بٌن أن تقو َم بكتابة التابع العضو داخل الصفّ بشكل كامل ّ‬ ‫وأال تفع َل ذلك هو أنّ المترجم فً الحالة‬ ‫األولى سٌعتبر التابع من النوع ‪ inline‬بشكل تلقابً‪ .‬أمّا فً الحالة الثانٌة )التعرٌف المبدبً( فإنّ المترجم‬ ‫سٌعتبر التابع من النوع الطبٌعً ‪.not-inline‬‬

‫التوابع األعضاء ‪inline‬‬ ‫كل التوابع األعضاء المعرفة بشكل كامل داخل الصف هً من النوع ‪ .inline‬لنفترض أن لدٌنا المثال التالً‪:‬‬ ‫‪class Account‬‬ ‫{‬ ‫‪private:‬‬ ‫;‪double balance‬‬ ‫‪public:‬‬ ‫} ;‪Account(double initial_balance) { balance = initial_balance‬‬ ‫;)(‪double getBalance‬‬ ‫;) ‪double deposit( double amount‬‬ ‫;) ‪double withdraw( double amount‬‬ ‫;}‬ ‫‪236‬‬


‫التابع ‪ Account‬والذي ٌدعى مشٌّدا )انظر الفقرة القادمة( فً هذا المثال هو تابع من النوع ‪ inline‬أمّا التوابع‬ ‫األخرى مثل )(‪ GetBalance(), Deposite(), Withdraw‬فهً من النوع الطبٌعً ‪ّ not-inline‬إال أ ّنه‬ ‫ٌمكننا أن نحولها إلى توابع من النوع ‪ inline‬بالشكل التالً ‪:‬‬ ‫)(‪inline double Account::getBalance‬‬ ‫{‬ ‫;‪return balance‬‬ ‫}‬ ‫) ‪inline double Account::deposit( double amount‬‬ ‫{‬ ‫;) ‪return ( balance += amount‬‬ ‫}‬ ‫) ‪inline double Account::withdraw( double Amount‬‬ ‫{‬ ‫;) ‪return ( balance -= amount‬‬ ‫}‬ ‫مالحظة‪ :‬كل التوابع المعرفة بشكل كامل داخل الصف هً من النوع ‪ inline‬سواء أستخدمنا الكلمة ‪ inline‬فً‬ ‫التصرٌح عنها أم لم نستخدمها‪.‬‬ ‫إنّ التصرٌح عن التوابع على أ ّنها من النوع ‪ٌ inline‬جعلها تعمل بؤسلوب مختلف فبدال من استدعابها مثل‬ ‫التوابع العادٌة ٌت ّم نسخ جسم التابع مرّ ة لكل استدعاء وٌن ّفذ كما لو كان جزءا من الشٌفرة التً اس ُتدعً فٌها‪.‬‬ ‫ربّما تسؤل نفسك لماذا جعلنا العضوٌن ‪ x, y‬من المستوى الخاص ‪private‬؟ )تذ ّكر أ ّنه إذا لم نحدد مستوى‬ ‫الوصول لؤلعضاء فهً من المستوى ‪ .(private‬الجواب أل ّننا عرّ فنا تابعا )(‪ set_values‬لٌقوم بقراءة قٌمِهما‬ ‫فً محاولة لحماٌتهما من استقبال قٌم خاطبة )نستطٌع أن نكتب شٌفرة داخل التابع للتحقق من صحة البٌانات المدخلة( ولذا‬ ‫فلٌس من حاجة لجعل البرنامج قادرا على التعامل معهما مباشرة‪ .‬ربّما فً البرامج الصغٌرة والبسٌطة كالمثال‬ ‫السابق لن تجد منفعة كبٌرة من ذلك‪ ,‬ولكن فً المشارٌع الضخمة قد ٌكون من الضروري جدا أن تبقى قٌم‬ ‫المتغٌّرات بعٌدة عن التحوٌر أو التغٌ​ٌر)قد ٌنتج التغٌ​ٌر عن خطؤ غٌر متوقع أثناء كتابة الشٌفرة‪ .‬انظر فقرة التغلٌف‬ ‫‪.(encapsulation‬‬ ‫من أه ّم مٌزات الصفوف أ ّنه ٌمكننا أن نصرّ ح عن العدٌد من الكابنات منها‪ .‬فً المثال السابق كان بإمكاننا أن‬ ‫نصرِّ ح عن الكابن )المتغٌّر( ‪ rectb‬باإلضافة إلى الكابن ‪.rect‬‬ ‫‪rect area: 12‬‬ ‫‪rectb area: 30‬‬

‫‪// class example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int x, y‬‬ ‫‪public:‬‬ ‫;)‪void set_values (int,int‬‬ ‫};)‪int area (void) {return (x*y‬‬ ‫;}‬ ‫{ )‪void CRectangle::set_values (int a, int b‬‬ ‫;‪x = a‬‬ ‫;‪y = b‬‬ ‫}‬

‫‪237‬‬


โ ซ{ )( โ ชint mainโ ฌโ ฌ โ ซ;โ ชCRectangle rect, rectbโ ฌโ ฌ โ ซ;)โ ชrect.set_values (3,4โ ฌโ ฌ โ ซ;)โ ชrectb.set_values (5,6โ ฌโ ฌ โ ซ;โ ชcout << "rect area: " << rect.area() << endlโ ฌโ ฌ โ ซ;โ ชcout << "rectb area: " << rectb.area() << endlโ ฌโ ฌ โ ซ}โ ฌ

โ ซุงู ุญุธ ุฃู ู ุงุงู ุณุชุฏุนุงุก )(โ ช rect.areaโ ฌุงู ู ุนุทู ู ู ุณ ู ุชู ุฌุฉ ุงุงู ุณุชุฏุนุงุก )(โ ช.rectb.areaโ ฌโ ฌ โ ซู ุฐู ู ุฃู ู ู ู ู ู ุงุจู ู ู ู ุด ู ุช ู ู ู ู ู ุงู ุตู ู โ ชู CRectangleโ ฌู ุชู ู ุฃุนุถุงุก ุงู ุตู ู ู ู ู ุง ู ู ุฌุฏู ุฏโ ช .โ ฌุฃู ุฃู ู ู ู ู ุงุจู ู ู ู ู ุงโ ฌ โ ซุตู ู ุจู โ ช ,โ ฌู ุชุงุจุนู ู )(โ ช set_value() , areaโ ฌุฎุงุตู ู ุจู ุฃู ุถุงโ ช.โ ฌโ ฌ โ ซู ุญุชู ู ุนู ู ู ุชุบู ู ุฑู ู โ ช x, yโ ฌุฎุง ู โ ฌ โ ซู ู ู ู ุง ู ุดุคุช ู ู ุฑุฉ ุงู ู ุงุจู ุงุช ู ุงู ุจุฑู ุฌุฉ ู ุงุจู ู ู ุฉ ุงู ุชู ุฌู ู โ ช .โ ฌุญู ุซ ู ุชุนุชุจุฑ ุงู ุจู ุงู ุงุช ู ุงู ุชู ุงุจุน ุฎุตุงุจุต )ุตู ุงุช( ู ู ู ุงุจู โ ช.โ ฌโ ฌ โ ซุณู ู ุงู ุด ู ู ู ู ุฑุงุช ู ุงุฏู ุฉ ู ู ุฒุงุช ู ุฐุง ุงุฃู ุณู ู ุจโ ช.โ ฌโ ฌ โ ซู ู ุญุงู ุชู ุง ุงู ุณุงุจู ุฉ ุงู ุตู ู )ู ู ุน ุงู ุจู ุงู ุงุช ู ู ู ุงุจู ุงุช ุงู ู ุดุช ู ู ุฉ ู ู ู ( ู ู โ ช CRectangleโ ฌุญู ุซ ุฃู ุดุคู ุง ู ู ู ู ุณุฎุชู ู ุฃู โ ฌ โ ซู ุงุจู ู ู ู ู ุง โ ช rect , rectbโ ฌู ู ู ู ู ู ู ู ุง ู ู ุฃุนุถุงุฅู ุงู ุฎุงุตุฉ )ุตู ุงุชู ู ู ู ุชุบู ู ุฑุงุช ู ุชู ุงุจุน(โ ช.โ ฌโ ฌ

โ ซโ ช -2โ ฌุงู ุชุจ ุต ู ู ุง ุฌุฏู ุฏุง ุงุณู ู โ ช Circleโ ฌุจุญู ุซ ู ุญุชู ู ุนู ู ุงุฃู ุนุถุงุก ุงู ุชุงู ู ุฉ โ ช:โ ฌโ ฌ โ ซโ ช ๏ ผโ ฌู ุชุบู ู ุฑ ู ุตู ุงู ู ุทุฑ โ ช.rโ ฌโ ฌ โ ซโ ช ๏ ผโ ฌุชุงุจุน ู ู ุฑุงุกุฉ ู ุตู ุงู ู ุทุฑ )(โ ช. set_radiusโ ฌโ ฌ โ ซ๐ โ ฌ โ ซโ ช ๏ ผโ ฌุชุงุจุน ู ุญุณุงุจ ู ุณุงุญุฉ ุงู ุฏุจุฑุฉ โ ช calc_spaceโ ฌุญู ุซ ุฃู ู ุงู ู ุณุงุญุฉ ู ู โ ฌ โ ซ๐ โ ฌ โ ซโ ช ๏ ผโ ฌุชุงุจุน ุญุณุงุจ ู ุญู ุท ุงู ุฏุงุจุฑุฉ โ ช calc_perimeterโ ฌุญู ุซ ุฃู ุงู ู ุญู ุท ู ู โ ฌ

โ ซโ ช.โ ฌโ ฌ

โ ซโ ช.โ ฌโ ฌ

โ ซุซ ู ู ุงุณุชุฎุฏู ู ู ู ุจุฑู ุงู ุฌู ุญู ุซ ู ุฏุฎู ุงู ู ุณุชุฎุฏู ู ุตู ุงู ู ุทุฑ ู ู ุทุจุน ุงู ุจุฑู ุงู ุฌ ุงู ู ุณุงุญุฉ ู ุงู ู ุญู ุทโ ช.โ ฌโ ฌ โ ซโ ช -3โ ฌุงู ุชุจ ุต ู ู ุง ุงุณู ู โ ช Pointโ ฌุญู ุซ ู ุญุชู ู ุนู ู ุงุฃู ุนุถุงุก ุงู ุชุงู ู ุฉโ ช:โ ฌโ ฌ โ ซโ ช ๏ ผโ ฌู ุชุบู ู ุฑู ู ู ู ุซุจู ู ุงุญุฏุงุซู ุงุช ุงู ู ู ุทุฉ โ ช.x , yโ ฌโ ฌ โ ซโ ช ๏ ผโ ฌุชุงุจุน ุงู ุณุชู ุจุงู ู ู ู ุงู ู ุชุบู ู ุฑู ู ุงู ุณุงุจู ู ู โ ช.set_pointโ ฌโ ฌ โ ซโ ช ๏ ผโ ฌุชุงุจุน ู ุญุณุงุจ ุงู ู ุณุงู ุฉ ุจู ู ู ู ุทุชู ู โ ช distanceโ ฌุญู ุซโ ฌ โ ซโ ช.โ ฌโ ฌ

โ ซโ โ ฌ

โ ซุซ ู ู ุงุณุชุฎุฏู ู ู ู ุจุฑู ุงู ุฌ ู ุญุณุจ ุงู ู ุณุงู ุฉ ุจู ู ู ู ุทุชู ู ู ุญุฏุฏู ู ุง ุงู ู ุณุชุฎุฏู โ ฌ

โ ซโ ช238โ ฌโ ฌ


‫المش ٌّدات ‪Constructors‬‬ ‫تحتوي الصفوف على تابع خاصّ ٌدعى المشٌّد ‪ constructor‬الذي ٌص ّرح عنه على أ ّنه تاب ٌع عضو فً الصفّ‬ ‫مرة واحدة فقط وبشكل تلقائً عندما تقوم بإنشاء (اشتقاق)‬ ‫وهو ٌؤخذ نفس اسم الصفّ ‪ٌ .‬ت ّم استدعاء المش ٌّد ّ‬ ‫الصف وهو أوّ ل تابع ٌت ّم تنفٌذه فً الكابن‪.‬‬ ‫نسخة (كائن) جدٌدة من‬ ‫ّ‬ ‫كامل‬ ‫بشكل‬ ‫تحتاج الكابنات عموما إلى تبدبة متغٌّراتها أو حجز ذاكرة دٌنامٌكٌة أثناء عمل ٌّات بنابها لتصبح فعّالة‬ ‫ٍ‬ ‫ٍ‬ ‫فعل ذلك )التبدبة(‪.‬‬ ‫ولنتج ّنب القٌم غٌر المتو ّقعة أو العشوابٌّة ألعضابها خبلل فترة تنفٌذ الكابن والناتجة عن عدم ِ‬ ‫مثال‪ :‬ماذا سٌحدث فً المثال السابق لو أ ّننا استدعٌنا التابع )(‪ area‬قبل أن نستدعً التابع )(‪set_values‬؟‬ ‫قد تكون النتٌجة غٌر معروفة )عشوابٌة( ألنّ المتغٌّرٌّن ‪ x, y‬لم ٌُسْ ند إلٌهما أٌّة قٌم‪ ,‬وفً محاولة للتخلّص من‬ ‫هذه المشكلة سنكتب الصفّ ‪ CRectangle‬وسنضٌف إلٌه مشٌّدا ‪constructor‬‬ ‫‪// classes example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬

‫‪rect area: 12‬‬ ‫‪rectb area: 30‬‬

‫{ ‪class CRectangle‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫‪CRectangle (int,int); //Constructor‬‬ ‫};)‪int area (void) {return (width*height‬‬ ‫;}‬ ‫{ )‪CRectangle::CRectangle (int a, int b‬‬ ‫;‪width = a‬‬ ‫;‪height = b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫‪CRectangle rect (3,4); //try to remove (3,4) & run‬‬ ‫;)‪CRectangle rectb (5,6‬‬ ‫;‪cout << "rect area: " << rect.area() << endl‬‬ ‫;‪cout << "rectb area: " << rectb.area() << endl‬‬ ‫}‬

‫كما ترى نتٌجة هذا المثال هً نفس نتٌجة المثال السابق‪ .‬حٌث قمنا باستبدال التابع )(‪- set_values‬الذي لم‬ ‫ٌعد موجودا‪ -‬بالتابع المشٌّد ‪.constructor‬‬ ‫الحظ كٌف مرّ رنا وسٌطٌن إلى المشٌّد فً نفس اللحظة التً أنشؤنا فٌها نسخة من الصفّ ‪ .‬كاآلتً‪:‬‬ ‫;)‪CRectangle rect (3,4‬‬ ‫;)‪CRectangle rectb (5,6‬‬ ‫وترى أٌضا أنّ التابع المشٌّد ال ٌمتلك قٌمة معادة كما أ ّنه لٌس من النوع ‪.void‬‬

‫ٌجب أن تضع هذا فً حسبانك دابما المشٌّد الٌعٌد قٌمة ولٌس من النوع ‪.void‬‬

‫أضف مشٌّد ا إلى التمرٌن السابق بحٌث ٌمكنه أن ٌقرأ نصف القطر كوسٌط مباشرة دون الحاجة إلى التابع‬ ‫‪.set_radius‬‬

‫‪239‬‬


‫الهادمات ‪Destructors‬‬ ‫مرة واحد اة عندما‬ ‫الهادم‪ :‬هو تابع له وظٌفة تعاكس بشكل كامل وظٌفة المشٌّد حٌث ٌت ّم استدعاؤه بشكل تلقائً ّ‬ ‫ٌتحرر الكائن من الذاكرة )إمّا أل ّنه أنهى كل تعلٌماته كؤن نعرِّ ف كابنا على أ ّنه متغٌّر موضعً ضمن تابع ما و ٌنهً التابع‬ ‫ّ‬ ‫تعلٌماته‪ ,‬أو أل ّنه كابن ت ّم إسناد القٌم المطلوبة إلٌه ث ّم ت ّم تحرٌره من الذاكرة باستعمال معامل الحذف ‪.( delet‬‬

‫الهادم ٌجب أن ٌؤخذ نفس اسم الصفّ مسبوقا بالرمز ~ كما وٌجب ّأال ٌعٌد الهادم قٌمة‪.‬‬ ‫ٌستخدم الهادم عادة لتحرٌر الذاكرة ‪-‬التً ٌحجزها الكابن أثناء تنفٌذه‪ -‬فً اللحظة التً ٌنهً فٌها الكابن عمله‪.‬‬ ‫‪rect area: 12‬‬ ‫‪rectb area: 30‬‬

‫‪// example on constructors and destructors‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int *width, *height‬‬ ‫‪public:‬‬ ‫;)‪CRectangle (int,int‬‬ ‫;)( ‪~CRectangle‬‬ ‫};)‪int area (void) {return (*width * *height‬‬ ‫;}‬ ‫{ )‪CRectangle::CRectangle (int a, int b‬‬ ‫;‪width = new int‬‬ ‫;‪height = new int‬‬ ‫;‪*width = a‬‬ ‫;‪*height = b‬‬ ‫}‬ ‫{ )( ‪CRectangle::~CRectangle‬‬ ‫;‪delete width‬‬ ‫;‪delete height‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;)‪CRectangle rect (3,4), rectb (5,6‬‬ ‫;‪cout << "rect area: " << rect.area() << endl‬‬ ‫;‪cout << "rectb area: " << rectb.area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫إعادة تحمٌل المش ٌّدات ‪Overloading Constructors‬‬ ‫كؤيّ تابع آخر ٌمكن تطبٌق هذا المبدأ على المشٌّد وذلك بإنشاء عـ ّدة مشٌّدات لها نفس االسم و تختلف فً عدد‬ ‫أو أنواع الوسطاء‪) .‬راجع فقرة إعادة التحمٌل فصل التوابع( وٌستطٌع المترجم أن ٌعرف أيّ هذه التوابع‬ ‫سٌستخدمها الكابن عندما تصرِّ ح عنه‪.‬‬ ‫فً الواقع‪ ,‬عندما ننش ُا ص ّفا وال نع ّرف فٌه أيّ مشٌّد فإنّ المترجم ٌفترض بشكل تلقابً وجود مشٌّدٌن هما‬ ‫المشٌّد العادي )دون وسطاء أو ‪ (nop‬والمشٌّد النسخة‪ ,‬مثال ‪:‬‬ ‫{ ‪class CExample‬‬ ‫‪public:‬‬ ‫;‪int a,b,c‬‬ ‫;} ;‪void multiply (int n, int m) { a=n; b=m; c=a*b‬‬ ‫;}‬ ‫‪23:‬‬


‫بما أنّ الصفّ السابق ال ٌمتلك مشٌّدا فإنّ المترجم سٌفترض أنّ هناك مشٌّدٌن افتراضٌ​ٌن هما‪:‬‬ ‫المش ٌّد العادي ‪ :‬وهو مشٌّد ال ٌمتلك وسطاء وٌُعْ َرفُ بـ )‪ nop (no parameters‬وهو ال ٌفعل أي شًء عادة‪.‬‬ ‫;} { )( ‪CExample::CExample‬‬ ‫المش ٌّد النسخة ‪ٌ :‬حتوي على وسٌط من نوع الصفّ ممرّ ر بالمرجع‪ ,‬وهو ٌقوم بنسخ قٌم المتغٌّرات األعضاء‬ ‫غٌر الثابتة ‪ non-static‬من الكابن الوسٌط وٌسندها إلى المتغٌّرات األعضاء المقابلة لها )‪ (non-static‬فً‬ ‫ّ‬ ‫المشتق من صفّ من النوع ‪ non-static‬أٌضا‪.‬‬ ‫الكابن ‪a‬‬ ‫{ )‪CExample::CExample (const CExample& rv‬‬ ‫;‪a=rv.a; b=rv.b; c=rv.c‬‬ ‫}‬ ‫ٌجب أن تعلم أنّ المشٌّدٌن االفتراضٌن ٌكونان موجودٌن عندما ال تقوم بالتصرٌح عن أيِّ مشٌّد فً الصفّ و‬ ‫لذلك عندما تضٌف مشٌّدا ما إلى الصفّ فإنّ هذٌن المشٌّدٌن لن ٌكونا موجودٌن وفً حال رغبت باإلبقاء على‬ ‫أحدهما فعلٌك أن تصرّ ح عنه بنفسك‪.‬‬ ‫‪rect area: 12‬‬ ‫‪rectb area: 25‬‬

‫‪// overloading class constructors‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫;)( ‪CRectangle‬‬ ‫;)‪CRectangle (int,int‬‬ ‫};)‪int area (void) {return (width*height‬‬ ‫;}‬ ‫{ )( ‪CRectangle::CRectangle‬‬ ‫;‪width = 5‬‬ ‫;‪height = 5‬‬ ‫}‬ ‫{ )‪CRectangle::CRectangle (int a, int b‬‬ ‫;‪width = a‬‬ ‫;‪height = b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;)‪CRectangle rect (3,4‬‬ ‫;‪CRectangle rectb‬‬ ‫;‪cout << "rect area: " << rect.area() << endl‬‬ ‫;‪cout << "rectb area: " << rectb.area() << endl‬‬ ‫}‬

‫فً هذه الحالة الكابن ‪ rectb‬صُرِّ ح عنه بدون وسطاء‪ ,‬لذلك فقد تمّت تبدبة متغٌّراته باستخدام المشٌّد العادي‬ ‫‪ nop‬والذي ٌسند القٌمة ‪ 6‬إلى ك ّل من المتغٌّرٌن ‪ width‬و ‪height‬‬ ‫مالحظة‪ :‬إذا أردنا أن ننشؤ كابنا جدٌدا من صفّ ما واستخدامنا المشٌّد العادي فعلٌنا أن نذكر اسم‬ ‫الصفّ و بعده اسم الكابن الجدٌد دون أن نضع أقواسا من الشكل )(‪ .‬أمّا إذا كان فً صفّ ما‬ ‫مشٌّد ات غٌر المشٌّد العادي )‪ (nop‬الذي ال ٌمتلك وسطاء لتمرّ ر إلٌه وأردنا استخدام أحدها‬ ‫عندها ٌجب علٌنا أن نذكر القوسٌن )( بعد اسم الكابن الجدٌد وبداخلهما الوسطاء المطلوبة‪.‬‬ ‫‪241‬‬


‫مثال‪ :‬فً المثال السابق‪:‬‬ ‫رظش‪٠‬ؼ طؾ‪١‬ؼ ألّٕٔب اعزخذِٕب اٌّش‪ّ١‬ذ اٌؼبد‪CRectangle rectb; // ٞ‬‬ ‫رظش‪٠‬ؼ خبؽئ! ّ‬ ‫ألْ اٌّش‪ّ١‬ذ اٌؼبد‪ ٞ‬ل ‪٠‬ؾزبط ئٌ‪ ٝ‬اٌم‪ٛ‬ع‪CRectangle rectb(); // )( ٓ١‬‬

‫‪ -2‬فً التمرٌن ‪) 1‬الصفّ ‪ (Circle‬الذي أضفت إلٌه مشٌّد ا لقراءة نصف القطر هل العبارة التالٌة‬ ‫صحٌحة ‪:‬‬ ‫; ‪Circle circle‬‬ ‫‪ -3‬فً التمرٌن ‪) 3‬الصفّ ‪ (Point‬أضف مشٌّد ٌن األول هو مشٌّد ٌقبل وسٌطٌن من خبلله تصبح قادرا‬ ‫على أن تسند قٌمتً المتغٌّرٌن ‪ , x , y‬و المشٌّد العادي‪.‬‬ ‫‪ -4‬تؤمّل البرنامج التالً‪:‬‬

‫اجعل البرنامج ٌطبع الشكل التالً‪:10‬‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫)(‪int main‬‬ ‫{‬ ‫;"‪cout<<"Sweat plus sacrifice equals success.‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪Give the world the best you have, and the best will come to you.‬‬ ‫‪Sweat plus sacrifice equals success.‬‬ ‫‪If man hasn’t discovered that he will die for, he isn’t fit to live.‬‬

‫وذلك دون أن تعدّل فً التابع ‪ main‬أبداا‪.‬‬ ‫)تذكر أنّ المتغٌّرات الشاملة تت ّم تبدبتها فً بداٌة البرنامج قبل التابع ‪ main‬و ٌت ّم هدمها بعد التابع ‪.( main‬‬

‫‪10‬‬

‫العبارة األولى لـ ‪ Madeline Bridge‬والثانٌة لـ ‪ , Charles O. Finley‬والثالثة لـ ‪Martin Luther King, JR‬‬

‫‪242‬‬


‫المؤ ّ‬ ‫شرات على الصفوف ‪Pointers to classes‬‬

‫بشكل حقٌقًٍ‪ ,‬ولفعل ذلك علٌنا ببساطة أن ُنعرِّ ف مإ ّ‬ ‫ٌمكننا أن ننشا مإ ّ‬ ‫شرا على كابن‬ ‫شرا لٌشٌر على صفّ ما‬ ‫ٍ‬ ‫من نوع الصفّ كما ٌلً‪:‬‬ ‫;‪CRectangle * prect‬‬ ‫شر السابق مإ ّ‬ ‫ٌمثل المإ ّ‬ ‫شرا على كابن من النوع ‪ ,CRectangle‬ولكً نشٌر بشكل مباشر إلى عضو ما من‬ ‫ضح بعض العبارات الممكنة‪.‬‬ ‫أعضاء هذا الكابن ٌنبغً أن نستخدم المعامل >‪ -‬والمثال التالً ٌو ّ‬ ‫‪a area: 2‬‬ ‫‪*b area: 12‬‬ ‫‪*c area: 2‬‬ ‫‪d[0] area: 30‬‬ ‫‪d[1] area: 56‬‬

‫‪// pointer to classes example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫;)‪void set_values (int, int‬‬ ‫};)‪int area (void) {return (width * height‬‬ ‫;}‬ ‫{ )‪void CRectangle::set_values (int a, int b‬‬ ‫;‪width = a‬‬ ‫;‪height = b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪CRectangle a, *b, *c‬‬ ‫;]‪CRectangle * d = new CRectangle[2‬‬ ‫;‪b= new CRectangle‬‬ ‫;‪c= &a‬‬ ‫;)‪a.set_values (1,2‬‬ ‫;)‪b->set_values (3,4‬‬ ‫;)‪d->set_values (5,6‬‬ ‫;)‪d[1].set_values (7,8‬‬ ‫;‪cout << "a area: " << a.area() << endl‬‬ ‫;‪cout << "*b area: " << b->area() << endl‬‬ ‫;‪cout << "*c area: " << c->area() << endl‬‬ ‫;‪cout << "d[0] area: " << d[0].area() << endl‬‬ ‫;‪cout << "d[1] area: " << d[1].area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫وهذه قابمة مختصرة بطرق قراءة المإ ّ‬ ‫شرات والمعامبلت )] [ ‪: (*, &,. , ->,‬‬ ‫المثال‬ ‫‪*x‬‬ ‫‪&x‬‬ ‫‪x.y‬‬ ‫‪(*x).y‬‬ ‫‪x->y‬‬ ‫]‪x[0‬‬ ‫]‪x[1‬‬ ‫]‪x[n‬‬

‫ٌقرأ كاآلتً‬ ‫القٌمة التً ٌشٌر إلٌها المإ ّشر ‪x‬‬ ‫عنوان الكابن ‪x‬‬ ‫العضو ‪ y‬من المإ ّشر ‪x‬‬ ‫العضو ‪ y‬من الكابن المشار إلٌه بالمإ ّشر ‪x‬‬ ‫العضو ‪ y‬من الكابن المشار إلٌه بالمإ ّشر ‪x‬‬ ‫الكابن األول الذي ٌشٌر إلٌه المإ ّ‬ ‫شر‬ ‫الكابن الثانً الذي ٌشٌر إلٌه المإ ّ‬ ‫شر‬ ‫الكابن رقم ‪ n‬الذي ٌشٌر إلٌه المإ ّشر‬

‫رأ ّوذ ِٓ أّٔه رّ ّىٕذ ِٓ ف‪ ُٙ‬وً ٘زٖ اٌؼٍّ‪١‬بد ثشىً ربَ‪ٚ ,‬ئرا وبْ ٌذ‪٠‬ه أ‪ّ٠‬خ شى‪ٛ‬ن ؽ‪ٌٙٛ‬ب فٕ​ٕظؾه ثمشاءح فظٍ‪ٟ‬‬ ‫ّ‬ ‫‪ٚ‬اٌغغالد ‪.struct‬‬ ‫اٌّإ ّششاد ‪pointers‬‬

‫‪243‬‬


‫الكلمة المفتاحٌة ‪this‬‬ ‫اٌظف اٌز‪ُٕ٠ ٞ‬فّز ؽبٌ‪١‬بً‪ ٟ٘ٚ .‬رّضًّ ِإ ّششاً‬ ‫ّ‬ ‫ّ‬ ‫اٌظف رش‪١‬ش ئٌ‪ ٝ‬اٌؼٕ‪ٛ‬اْ ف‪ ٟ‬اٌزاوشح ٌٍىبئٓ ِٓ ٘زا‬ ‫٘زٖ اٌىٍّخ داخً‬ ‫ل‪ّ١‬زٗ دائّب ً ػٕ‪ٛ‬اْ ٘زا اٌىبئٓ‪.‬‬ ‫عضو ما من الكابن هو الكابن نفسه‪.‬‬ ‫تابع‬ ‫ٍ‬ ‫ٌمكن أن تستخدم هذه الكلمة لمعرفة فٌما إذا كان الوسٌط الممرر إلى ٍ‬ ‫مثال‪:‬‬ ‫‪yes, &a is b‬‬

‫‪// this‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CDummy‬‬ ‫‪public:‬‬ ‫;)‪int isitme (CDummy& param‬‬ ‫;}‬ ‫)‪int CDummy::isitme (CDummy& param‬‬ ‫{‬ ‫;‪if (&param == this) return 1‬‬ ‫;‪else return 0‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪CDummy a‬‬ ‫;‪CDummy* b = &a‬‬ ‫) )‪if ( b->isitme(a‬‬ ‫;"‪cout << "yes, &a is b\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫ّ‬ ‫اٌظف ‪٠ٚ‬ؼ‪١‬ذ وبئٕب ً ِٕٗ‪ .‬رزجّغ‬ ‫ػبدحً رغزخذَ ٘زٖ اٌىٍّخ ف‪ ٟ‬اٌّؼبًِ = اٌز‪٠ ٞ‬مجً ‪ٚ‬ع‪١‬طب ً ثبٌّشعغ ِٓ ٔفظ ٔ‪ٛ‬ع‬ ‫اٌّضبي اٌزبٌ‪ٚ ٟ‬لؽع و‪١‬ف إّٔٔب اعزخذِٕب اٌىٍّخ ‪ٌٍ this‬زخٍّض ِٓ اٌّزؾ‪ٛ‬ي اٌّ‪ٛ‬ػؼ‪ ٟ‬وّب فؼٍٕب ف‪ ٟ‬اٌّضبي األخ‪١‬ش‬ ‫ِٓ اٌفمشح اٌغبثمخ ‪:‬‬ ‫)‪CVector& CVector::operator= (const CVector& param‬‬ ‫{‬ ‫; ‪x = param.x‬‬ ‫; ‪y = param.y‬‬ ‫; ‪return *this‬‬ ‫}‬ ‫ّ‬ ‫طف ئرا ٌُ ٔمُ ٔؾٓ ثاػبدح رؾّ‪ ً١‬اٌّؼبًِ =‬ ‫‪٘ٚ‬زٖ اٌش‪١‬فشح ٘‪ ٟ‬اٌش‪١‬فشح الفزشاػ‪١‬خ ٌٍّؼبًِ = ِٓ أعً أ‪ٞ‬‬ ‫‪ٚ‬رغ‪١١‬ش اٌش‪١‬فشح‪.‬‬ ‫مالحظت‪ :‬األػؼبء ِٓ إٌ‪ٛ‬ع ‪ static‬ل ‪ّ٠‬ىٓ أْ ٔش‪١‬ش ئٌ‪ٙ١‬ب ثبٌّإ ّشش ‪.this‬‬ ‫ػٕذِب ‪ُ٠‬غزذػ‪ ٝ‬ػؼ‪ِ ٛ‬ب ‪١ٌ -‬ظ ِٓ إٌ‪ٛ‬ع ‪ ِٓ -static‬وبئٓ ّ‬ ‫فاْ ػٕ‪ٛ‬اْ اٌىبئٓ ‪ّ ّ٠‬شس و‪ٛ‬ع‪١‬ؾ خف‪ ٟ‬ئٌ‪٘ ٝ‬زا اٌؼؼ‪ٛ‬‬ ‫وّب ‪:ٍٟ٠‬‬ ‫;) ‪myDate.setMonth( 3‬‬ ‫‪ ٚ‬اٌز‪٠ ٞ‬ؼٕ‪: ٟ‬‬ ‫;) ‪setMonth( &myDate, 3‬‬ ‫اٌزؼج‪١‬ش (‪٠ )*this‬غزخذَ ػبدح ِٓ أعً ئػبدح اٌىبئٓ اٌؾبٌ‪ ٟ‬وم‪ّ١‬خ ٌٍزبثغ اٌؼؼ‪ ٛ‬وّب فؼٍٕب عبثمبً‪.‬‬ ‫‪244‬‬


.‫ّخ‬٠‫ اٌمذ‬C++ ‫ ٔغخ‬ٟ‫دح ف‬ٛ‫ع‬ِٛ ‫غذ‬١ٌ this ‫ اٌىٍّخ‬:‫مالحظت‬ : this َ‫ػؼ اٌطشق اٌّ​ّىٕخ لعزخذا‬ٛ٠ ‫ِضبي‬ // Example of the this pointer class Date{itn month ; void setMonth(int);} void Date::setMonth( int mn ) { month = mn; // ‫٘زٖ اٌؼجبساد اٌضالس ِزىبفئخ‬ this->month = mn; (*this).month = mn; } : ٌٟ‫ٕب اٌّضبي اٌزب‬٠‫ٌٕفزشع أْ ٌذ‬ // this keyword example #include <iostream> using namespace std; class Example { int x; public: void setX(int x){ x = x; } void printX(){cout<< x << endl; } }; int main() { Example ex ; ex.setX(5); ex.printX(); return 0; }

-858993460

// this keyword example #include <iostream> using namespace std; class Example { int x ; public: void set_x(int x) { this->x = x; } void printX(){cout<< x << endl ;} };

5

x ٛ‫ّش اٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ل‬ٟ٘ ً‫طجغ ٘زا اٌجشٔبِظ قٍمتً عشىائٍّت‬١‫مخ األِش ع‬١‫ ؽم‬ٟ‫ما هً وتٍجت هزا انبروامج ؟ ف‬ ‫ّش‬١‫ّخ اٌّزغ‬١‫ ؟ ٘زا اٌزبثغ لبَ ثاعٕبد ل‬set_x(int x) ‫نكه كٍف؟ و مانزي فعهه انتابع‬ٚ .‫ّخ‬١‫ّخ ل‬٠‫ٗ أ‬١ٌ‫ ٌُ رُغٕذ ئ‬ٞ‫اٌز‬ ّ ‫ اٌّشىٍخ ٌزٌه‬ٟ٘ ٖ‫ؾ؟ ٘ز‬١‫ع‬ٌٛ‫ّش ا‬١‫ اٌّزغ‬ٛ٘ ‫ّب‬ّٙ٠‫أ‬ٚ ٛ‫ّش اٌؼؼ‬١‫ اٌّزغ‬ٛ٘ ٓ٠‫ّش‬١‫ اٌّزغ‬ٞ ّ ‫ ٌىٓ أ‬x ‫ّش‬١‫ اٌّزغ‬ٌٝ‫ ئ‬x ْ‫فا‬ ّ ‫طجغ اٌزبثغ‬١‫ّزٗ عشىائٍّت ٌزٌه ع‬١‫ثّب أْ ل‬ٚ ٗ‫ ٔفغ‬ٌٝ‫ ئ‬x ٛ‫ّشاٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ئعٕبد ل‬ٟ٘ ‫ّخ‬١ٍ‫ؼزجش ٘زٖ اٌزؼ‬٠ ُ‫اٌّزشع‬ :ٌٟ‫ اٌّضبي اٌزب‬ٟ‫ نكه ما هى انحم؟ سالت اٌفشق ف‬.‫ّخ‬١‫ائ‬ٛ‫ اٌؼش‬x ٛ‫ّش اٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ل‬print

int main() { Example ex ; ex.set_x(5); ex.printX(); return 0; }

245


‫انصفىف انمع ّرفت باستخذاو انكهمت انمحجىزة ‪struct‬‬ ‫اٌظف ‪ِ class‬بػذا ّ‬ ‫ّ‬ ‫أْ أػؼبء اٌغغً رى‪ِٓ ْٛ‬‬ ‫‪ٚ‬عّؼذ ‪ِ C++‬ف‪ َٛٙ‬اٌىٍّخ اٌّؾغ‪ٛ‬صح ‪ struct‬ئٌ‪ِ ٝ‬ف‪َٛٙ‬‬ ‫ّ‬ ‫اٌظف‪.‬‬ ‫اٌّغز‪ public ٜٛ‬ثشىً افزشاػ‪ ٟ‬ثذلً ِٓ أْ رى‪ ِٓ ْٛ‬اٌّغز‪ private ٜٛ‬وّب ف‪ٟ‬‬ ‫ّ‬ ‫اٌظف ‪ ٚ‬اٌغغً ٌ‪ّٙ‬ب ٔفظ اٌ‪ٛ‬ظبئف رمش‪٠‬جب ً ف‪ٌ , C++ ٟ‬ىٓ ‪٠ struct‬غزخذَ ػبدح ِٓ أعً‬ ‫ػٍ‪ ٝ‬أ‪٠‬خ ؽبي وًٌّ ِٓ‬ ‫اٌج‪١‬بٔبد فمؾ أ ِّب ‪ class‬ف‪ ٟٙ‬رغزخذَ ِٓ أعً اٌظف‪ٛ‬ف اٌز‪ ٟ‬رؾز‪ ٞٛ‬ػٍ‪ ٝ‬أػؼبء ِٓ اٌج‪١‬بٔبد ‪ٚ‬اٌز‪ٛ‬اثغ ‪ٚ‬‬ ‫اإلعشاءاد‪.‬‬

‫إعادة تحمٍم انمعامالث ‪Overloading operators‬‬ ‫أربؽذ ٌٕب ‪ C++‬اٌخ‪١‬بس ف‪ ٟ‬اعزخذاَ ِؼبِالر‪ٙ‬ب اٌم‪١‬بع‪١‬خ ث‪ ٓ١‬اٌظف‪ٛ‬ف اٌز‪ ٟ‬رٕشئ‪ٙ‬ب أٔذ ثبإلػبفخ ئٌ‪ ٝ‬ئِىبٔ‪ّ١‬خ‬ ‫اعزخذاِ‪ٙ‬ب ث‪ ٓ١‬األٔ‪ٛ‬اع األعبع‪١‬خ‪ِ .‬ضبي‪:‬‬ ‫;‪int a, b, c‬‬ ‫;‪a = b + c‬‬ ‫‪ّ٠‬ىٕه ثبٌزأو‪١‬ذ اعزخذاَ ِؼبًِ اٌغّغ ‪ +‬ث‪ِ ٓ١‬زغ‪ّ١‬ش‪( ٓ٠‬وبئٕ‪ ِٓ )ٓ١‬إٌ‪ٛ‬ع األعبع‪ٌ ٚ .int ٟ‬ىٓ ِبرا ػٓ اٌّضبي‬ ‫اٌزبٌ‪:ٟ‬‬ ‫;‪struct { char product [50]; float price; } a, b, c‬‬ ‫;‪a = b + c‬‬ ‫ّ‬ ‫ّ‬ ‫ف‪ ٟ‬اٌ‪ٛ‬الغ ل ‪٠‬غ‪ٛ‬ص أْ ٔفؼً رٌه ػٍ‪ ٝ‬اٌشغُ ِٓ ّ‬ ‫اٌظف ‪٠‬ؼ ّذ‬ ‫طف ِب ئٌ‪ ٝ‬وبئٓ آخش ِٓ ٔفظ‬ ‫أْ ئعٕبد وبئٓ ِٓ‬ ‫ُ‬ ‫ٌىٓ ػٍّ‪ّ١‬خ اٌغّغ اٌغبثمخ ٘‪ ٟ‬اٌز‪ ٟ‬عزٕزِظ اٌخطأ ّ‬ ‫أِشاً ِّىٕب ً (‪ٕ٠‬غخ اٌّش‪ّ١‬ذ ثشىً افزشاػ‪ّ , )ٟ‬‬ ‫اٌغّغ غ‪ُ ١‬ش‬ ‫ألْ ِؼبِ ًَ‬ ‫ِ‬ ‫ِزبػ ّئل ث‪ ٓ١‬األٔ‪ٛ‬اع األعبع‪١‬خ‪.‬‬ ‫ٍ‬ ‫ّئل إّٔٔب ٔ‪ّ ٛ‬د ٕ٘ب أْ ٔم ّذَ اٌشىش ئٌ‪ C++ ٝ‬ألّٔ‪ٙ‬ب رّ ّىٕ​ٕب ِٓ ئػبدح رؾّ‪ِ ً١‬ؼبِالر‪ٙ‬ب اٌم‪١‬بع‪١‬خ األِش اٌز‪٠ ٞ‬غؼٍٕب‬ ‫لبدس‪ َٓ٠‬ػٍ‪ ٝ‬أْ ٔىزت اٌّضبي اٌغبثك‪ ,‬فبٌىبئٕبد اٌّشزمّخ ِٓ أٔ‪ٛ‬اع ِش ّوجخ وّب ف‪ ٟ‬اٌّضبي اٌغبثك رغزط‪١‬غ أْ رمجً‬ ‫اٌّؼبِالد ثؼذ ئػبدح رؾّ‪ٍٙ١‬ب‪ ,‬وّب عٕى‪ ْٛ‬لبدس‪ ٓ٠‬ثزٌه ػٍ‪ ٝ‬أْ ٔغ‪ّ١‬ش ف‪ ٟ‬آٌ‪١‬خ ػًّ اٌّؼبِالد‪.‬‬ ‫٘زٖ ٘‪ ٟ‬اٌّؼبِالد اٌز‪ّ٠ ٟ‬ىٕ​ٕب أْ ٔؼًّ ػٍ‪ٙ١‬ب رؾّ‪١‬الً صائذاً‪:‬‬ ‫=<<‬ ‫=&‬

‫>>‬ ‫~ |‬

‫=‪/‬‬

‫<<‬ ‫!‬

‫=‬ ‫<‬ ‫>‬ ‫=‪+‬‬ ‫=‪-‬‬ ‫=*‬ ‫=>‬ ‫‪++‬‬ ‫‪-‬‬‫‪%‬‬ ‫&‬ ‫^‬ ‫=‪%‬‬ ‫][‬ ‫)(‬ ‫‪new delete‬‬

‫‪/‬‬ ‫=<‬ ‫||‬

‫*‬ ‫=!‬ ‫&&‬

‫‬‫==‬ ‫=|‬

‫‪+‬‬ ‫=>>‬ ‫=^‬

‫‪246‬‬


:‫خ‬١ٌ‫ ارّجبع اٌمبػذح اٌزب‬ٌٝ‫بَ ثزٌه ٔؾزبط فمؾ ئ‬١‫كٍف وقىو بعمم إعادة انتحمٍم عهى انمعامالث؟ ٌٍم‬ type operator sign(parameters); ‫ كما ٌمكننا أن نقوم بكتابة التابع بشكله العادي مباشرة داخل‬prototype ً‫وكما تبلحظ فقد التعرٌف المبدب‬ . ّ‫الصف‬ :ً‫ رأخز اٌشى‬ٟ‫اٌز‬ٚ ‫ّخ اٌجؼذ‬١‫ذاً ِٓ أعً األشؼّخ صٕبئ‬٠‫ذ أْ ٔىزت طفّب ً عذ‬٠‫و اآلن لنقل إ ّننا ٔش‬ ⃗ ‫ اٌمبػذح‬ٌٝ‫ٓ ئ‬١‫خؼغ عّغ شؼبػ‬٠ ‫ش‬١‫ ؽ‬.ٓ١‫َ ثغّغ شؼبػ‬ٛ‫م‬١ٌ + ًِ‫ اٌّؼب‬ٍٝ‫ً صائذ ػ‬١ّ‫َ ثؼًّ رؾ‬ٛ‫ذ أْ ٔم‬٠‫ ٔش‬ٚ ⃗ ⃗​⃗​⃗ ⃗ ⃗ ⃗​⃗​⃗ ⃗ :‫خ‬١ٌ‫اٌزب‬ ⃗

⃗​⃗​⃗

⃗​⃗​⃗

// vectors: overloading operators example #include <iostream> using namespace std; class CVector { public: int x,y; CVector () {}; CVector (int,int); CVector operator + (CVector); }; CVector::CVector (int a, int b) { x = a; y = b; } CVector CVector::operator+ (CVector param) { CVector temp; temp.x = x + param.x; temp.y = y + param.y; return (temp); } int main () { CVector a (3,1), b (1,2), c; c = a + b; cout<<"a(3,1) + b(1,2) = "; cout<<"c("<< c.x << "," << c.y <<")\n"; return 0; }

:‫ِضبي‬

a(3,1) + b(1,2) = c(4,3)

: ّ‫حٍث أن‬ ّ CVector ‫ٌٍظف‬ ‫ّذ‬١‫ اعُ اٌزبثغ اٌّش‬: CVector (int, int); ٟ‫بػ‬٠‫ اٌّؼبًِ اٌش‬ٍٝ‫ً ػ‬١ّ‫َ ثاػبدح اٌزؾ‬ٛ‫م‬٠ ٞ‫ ربثغ ِؼبًِ اٌغّغ اٌز‬: CVector operator+ (CVector); .CVector ‫ع‬ٌٕٛ‫ذ ا‬١‫ؼ‬٠ ٛ٘ ٚ +

247


‫‪ّ٠‬ىٓ أْ ٔم‪ َٛ‬ثبعزذػبء ٘زا اٌزبثغ ثأؽذ اٌشىٍ‪ ٓ١‬اٌزبٌ‪:ٓ١١‬‬ ‫;‪c = a + b‬‬ ‫أ‪ٚ‬‬ ‫;)‪c = a.operator+ (b‬‬ ‫لؽع أ‪٠‬ؼب ً إٔٔب أػفٕب اٌّش‪ّ١‬ذ اٌؼبد‪٠ CVector(){ }; ٞ‬ؼ ّذ ٘زا أِشاً ػش‪ٚ‬س‪٠‬ب ً ع ّذاً ألّٕٔب لّٕب ثزؼش‪٠‬ف اٌّش‪ّ١‬ذ‬ ‫;)‪ِ CVector(int, int‬ب ‪٠‬ؼٕ‪ ٟ‬أّٔٗ ٌٓ ‪٠‬ى‪ٕ٘ ْٛ‬بن أ‪ّ٠‬ب ً ِٓ اٌّش‪ّ١‬ذ‪ ٓ٠‬الفزشاػ‪( ٓ١١‬ساعغ فمشح اٌّش‪ّ١‬ذ اد ف‪ ٟ‬اٌذسط اٌغبثك)‬ ‫‪ٌٚ‬زٌه لثّذ ٌٕب ِٓ ئػبفزٗ ثأٔفغٕب ؽزّ‪٠ ٝ‬ؼًّ اٌجشٔبِظ‪ ,‬فؼذَ ئػبفزٗ رؼٕ‪ّ ٟ‬‬ ‫ِّىٓ‬ ‫أْ اٌزظش‪٠‬ؼ اٌزبٌ‪ CVecotr c; ٟ‬غ‪١‬ش‬ ‫ٍ‬ ‫داخً اٌزبثغ )(‪ main‬أ‪ ٚ‬غ‪١‬شٖ‪( .‬ث‪ّٕ١‬ب ‪٠‬ى‪ ْٛ‬اٌزظش‪٠‬ؾبْ ا‪٢‬خشاْ ِّىٕ‪ ٓ١‬ثغجت ‪ٚ‬ع‪ٛ‬د ِش‪ّ١‬ذ ‪٠‬أخز ‪ٚ‬ع‪١‬ط‪)ٓ١‬‬ ‫ػٍ‪ ٝ‬أ‪ّ٠‬خ ؽبي ‪٠ ,‬غت ػٍ ّ‪ ٟ‬أْ أُػٍِّه أّٔٗ ِٓ األفؼً ػذَ رشن اٌّش‪ّ١‬ذ اٌؼبد‪ ٞ‬أ‪ nop Constructor ٚ‬ثذ‪ ْٚ‬رؼٍ‪ّ١‬بد ألّٔٗ‬ ‫‪ٚ‬وّب ف‪ِ ٟ‬ضبٌٕب ٌ‪ ٛ‬إّٔٔب طشؽٕب ػٓ وبئٓ ِب ثبعزخذاَ اٌّش‪ّ١‬ذ اٌؼبد ّ‬ ‫‪ ٞ‬وب‪٢‬ر‪: ٟ‬‬ ‫;‪CVector c‬‬ ‫ّ‬ ‫فاْ ل‪ ٌٓ x, y ُ١‬رى‪ِ ْٛ‬ؼش‪ٚ‬فخ (ػش‪ٛ‬ائ‪١‬خ)‪ٚ ,‬ثبٌزبٌ‪٠ ٟ‬فؼًّ أْ ٔم‪ َٛ‬ث‪ٛ‬ػغ ثؼغ اٌزؼٍ‪ّ١‬بد اٌز‪ ٟ‬رغبػذٔب ػٍ‪ ٝ‬اٌزؾىُ‬ ‫ثبألػؼبء ‪ٚ‬رجذئز‪ٙ‬ب‪ .‬وّب ‪:ٍٟ٠‬‬ ‫;} ;‪CVector () { x=0; y=0‬‬ ‫ٌُ ٔمُ ثزٌه ف‪ ٟ‬اٌّضبي اٌغبثك ٌٍغ‪ٌٛٙ‬خ فمؾ‪.‬‬

‫وّب ّ‬ ‫أْ اٌظف‪ٛ‬ف رؾز‪ ٞٛ‬ثشىً افزشاػ‪ ٟ‬ػٍ‪ِ ٝ‬ش‪ّ١‬ذ‪( ٓ٠‬وّب ِش ِؼٕب عبثمبً) ف‪ ٟٙ‬رؾز‪ ٞٛ‬أ‪٠‬ؼب ً ػٍ‪ ٝ‬رؼش‪٠‬ف‬ ‫ّ‬ ‫اٌظف‪ .‬ؽ‪١‬ش ‪٠‬ؼٕ‪ :ٟ‬أِغخ وً األػؼبء غ‪١‬ش اٌضبثزخ(‪ِٓ )non-static‬‬ ‫ٌّؼبًِ اإلعٕبد = ث‪ ٓ١‬وبئٕ‪ٔ ِٓ ٓ١‬فظ‬ ‫اٌىبئٓ اٌز‪ ٞ‬ػٍ‪ ٓ١ّ٠ ٝ‬اٌّؼبًِ ئٌ‪ِ ٝ‬ب ‪٠‬مبثٍ‪ٙ‬ب ِٓ أػؼبء اٌىبئٓ اٌز‪ ٞ‬ػٍ‪٠ ٝ‬غبسٖ‪.‬‬ ‫‪ّ٠ ٚ‬ىٕه اٌزؾىُ ثزٌه ؽ‪١‬ش ‪ّ٠‬ىٕه أْ رؾذد األػؼبء اٌز‪ ٟ‬ر‪ٛ‬د ٔغخ‪ٙ‬ب‪.‬‬ ‫ل رفشع ػٍ‪١‬ه ئػبدح رؾّ‪ ً١‬اٌّؼبِالد أْ رغزخذِ‪ٙ‬ب ‪ٚ‬فمب ً ٌّؼٕ ً‪ ٝ‬ػب ٍَّ أ‪ٌ ٚ‬ؼالل ٍخ س‪٠‬بػ‪ٍ ١‬خ‪ ٚ ,‬ػٍ‪ ٝ‬اٌشغُ ِٓ رٌه‬ ‫ّ‬ ‫فاْ اعزخذاَ اٌّؼبِالد ‪ٚ‬فمب ً ٌ‪ٛ‬ظبئف‪ٙ‬ب ‪٠‬ؼ ّذ أفؼً‪ ,‬ئر ٌ‪١‬ظ ِٓ إٌّطم‪ ٟ‬أْ رؼ‪١‬ذ رؾّ‪ ً١‬اٌّؼبًِ ‪١ٌ +‬م‪ َٛ‬ثطشػ‬ ‫ِّىٓ ثشِغ‪ّ١‬ب‪ً.‬‬ ‫ّ‬ ‫ٌ‬ ‫وبئٕ‪ٔ ِٓ ٓ١‬فظ إٌ‪ٛ‬ع ػٍ‪ ٝ‬اٌشغُ ِٓ أْ ٘زا‬

‫فً تمرٌن الصفّ ‪ point‬أعد تحمٌل معامل الجمع لٌقوم بجمع نقطتٌن‪ .‬حٌث‬

‫‪248‬‬


‫األعضاء الثابتة من النوع ‪static‬‬ ‫ّ‬ ‫ّ‬ ‫اٌظف"‪ ,‬ألٔ‪ٙ‬ب‬ ‫اٌظف ػٍ‪ ٝ‬أػؼبء ِٓ إٌ‪ٛ‬ع ‪ٚ , static‬اٌز‪ ٟ‬رُؼ َشف أ‪٠‬ؼب ً ثـ "ِزغ‪ّ١‬شاد‬ ‫‪ّ٠‬ىٓ أْ ‪٠‬ؾز‪ٞٛ‬‬ ‫اٌّؾز‪ ٜٛ‬اٌز‪ ٞ‬ل ‪٠‬ؼزّذ ػٍ‪ ٝ‬أ‪ ٞ‬وبئٓ‪ ٟ٘ٚ .‬رّضً فمؾ لِ‪َّ١‬ب ً فش‪٠‬ذح ‪ِٛ ٚ‬ؽّذح ٌىً اٌىبئٕبد ِٓ ٔفظ إٌ‪ٛ‬ع‪.‬‬ ‫وّضبي‪ ,‬عٕم‪ َٛ‬ثبٌزظش‪٠‬ؼ ػٓ ِزغ‪ّ١‬ش ِٓ إٌ‪ٛ‬ع ‪ٌٕ static‬غزخذِٗ ف‪ ٟ‬ئؽظبء ػذد اٌىبئٕبد اٌز‪ ٟ‬ع‪١‬زُ ئٔشبؤ٘ب‬ ‫(٘ذِ‪ٙ‬ب) خالي اٌجشٔبِظ‪:‬‬ ‫‪7‬‬ ‫‪6‬‬

‫‪// static members in classes‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CDummy‬‬ ‫‪public:‬‬ ‫;‪static int n‬‬ ‫;} ;‪CDummy () { n++‬‬ ‫;} ;‪~CDummy () { n--‬‬ ‫;}‬ ‫;‪int CDummy::n=0‬‬ ‫{ )( ‪int main‬‬ ‫‪CDummy a; // create 1th instance‬‬ ‫‪CDummy b[5]; // create 2ed to 6th instances‬‬ ‫‪CDummy * c = new CDummy; //create 7th instance‬‬ ‫‪cout << a.n << endl; //n = 7‬‬ ‫‪delete c; //delet 7th instance‬‬ ‫‪cout << CDummy::n << endl; //n = 6‬‬ ‫;‪return 0‬‬ ‫}‬

‫ّ‬ ‫اٌظف‪ٌٙٚ .‬زا اٌغجت ‪ٌ ٚ‬زغّٕت‬ ‫ف‪ ٟ‬اٌ‪ٛ‬الغ رزّزّغ األػؼبء ِٓ ٘زا إٌ‪ٛ‬ع ثخظبئض اٌّزغ‪ّ١‬شاد اٌشبٍِخ ػٍ‪ ٝ‬وبًِ‬ ‫ّ‬ ‫اٌزظش‪٠‬ؼ ػٓ أ ّ‬ ‫اٌظف اٌ‪ٛ‬اؽذ‪ٚ​ٚ ,‬فمب ً ٌم‪ٛ‬اػذ ‪ ANSI-C++‬اٌم‪١‬بع‪١‬خ ‪ّ٠‬ىٕ​ٕب أْ ٔظ ّشػ ػٕ‪ٙ‬ب‬ ‫‪ِٕٙ ٞ‬ب ػ ّذح ِ ّشاد ف‪ٟ‬‬ ‫ّ‬ ‫اٌظف ‪ٔٚ‬زشن عغُ اٌزبثغ اٌؼؼ‪ ٛ‬أ‪ ٚ‬ئعٕبد اٌم‪ ُ١‬ئٌ‪ ٝ‬اٌّزغ‪ّ١‬شاد‬ ‫ثبعزخذاَ اٌزؼش‪٠‬ف اٌّجذئ‪ prototype ٟ‬داخً‬ ‫ّ‬ ‫اٌظف وّب فؼٍٕب ف‪ ٟ‬اٌّضبي اٌغبثك‪.‬‬ ‫خبسط‬ ‫ٌظف األعبع‪ٚ ٟ‬ل ‪٠‬ز ُّ ٔغخ‪ٙ‬ب ئٌ‪ ٝ‬اٌىبئٕبد اٌّشزمّخ ّ‬ ‫ّ‬ ‫ألْ ٘زٖ‬ ‫األػؼبء اٌضبثزخ ر‪ٛ‬عذ ِٕ‪ٙ‬ب ٔغخخ ‪ٚ‬اؽذح فمؾ ف‪ ٟ‬ا‬ ‫األػؼبء فش‪٠‬ذح ‪ِ ٚ‬شزشوخ ث‪ ٓ١‬عّ‪١‬غ اٌىبئٕبد ِٓ ٔفظ إٌ‪ٛ‬ع‪ ,‬ف‪ّ١‬ىٕ​ٕب أْ ٔش‪١‬ش ئٌ‪ ٝ‬أ‪ِٕٙ ٞ‬ب وؼؼ‪ ِٓ ٛ‬أ‪ ٞ‬وبئٓ‬ ‫ّ‬ ‫ّ‬ ‫اٌظف ص ُّ اٌّؼبًِ ‪ ::‬ص ُّ اعُ اٌؼؼ‪ ِٓ ٛ‬إٌ‪ٛ‬ع ‪( static‬ؽجؼب ً ٘زا‬ ‫اٌظف ٔفغٗ ‪ٚ‬رٌه ثزوش اعُ‬ ‫أ‪ِ ٚ‬جبششح ِٓ‬ ‫اٌش‪ٟ‬ء ‪٠‬ظٍؼ فمؾ ِٓ أعً األػؼبء ِٓ إٌ‪ٛ‬ع ‪ )static‬وّب ‪:ٍٟ٠‬‬ ‫;‪cout<<a.n‬‬ ‫;‪cout<< CDummy::n‬‬ ‫ف‪ ٟ‬ؽبي وبْ اٌؼؼ‪ ٛ‬ربثؼب ً ِٓ إٌ‪ٛ‬ع ‪ static‬ػٕذئز ّ‬ ‫فاْ ٘زا اٌزبثغ ل ‪ّ٠‬ىٕٗ أْ ‪٠‬زؼبًِ ّئل ِغ اٌّزغ‪ّ١‬شاد ِٓ إٌ‪ٛ‬ع‬ ‫ّ‬ ‫ّ‬ ‫ثأْ األػؼبء ‪ static‬ل رّزٍه اٌّإشش ‪ّ this‬‬ ‫‪ .static‬وّب ٔزوش ّ‬ ‫ألْ ٘زٖ األػؼبء ل رّضً أػؼبء خبطخ ثبٌىبئٓ‬ ‫‪ٚ‬ئّٔ​ّب ٘‪ ٟ‬أػؼبء ِشزشوخ ث‪ ٓ١‬عّ‪١‬غ اٌىبئٕبد ِٓ ٘زا إٌ‪ٛ‬ع‪.‬‬

‫‪249‬‬


:ً‫ أوجد األخطاء فً البرنامج التال‬:

class Example { public: Example ( int y = 10 ) : data( y ) { // empty body } // end Example constructor int getIncrementedData() const { return data++; } // end function getIncrementedData static int getCount() { cout << "Data is " << data << endl; return count; } // end function getCount private: int data; static int count; }; // end class Example

24:


‫الفصل الثامن شصر‪:‬‬

‫تعتمد البرمجة الكائنٌة على ثالثة مبادئ أساسٌة هً ‪:‬‬ ‫‪ -2‬مبدأ التغلٌف ‪.Encapsulation‬‬ ‫‪.Inheritance‬‬ ‫‪ -3‬الوراثة‬ ‫‪ -4‬تعدد األشكال ‪.Polymorphism‬‬

‫‪ -1‬مبدأ التغلٌف ‪Encapsulation‬‬ ‫تكون ظاهرة لآلخرٌن‪.‬‬ ‫صة بصفّ ما وإخفابها ح ّتى ال‬ ‫ٌهدف هذا المبدأ إلى تجمٌع البٌانات الخا ّ‬ ‫َ‬ ‫وللقٌام بذلك فإ ّننا نمنع بٌانات الصفّ )متغٌّراته( من الظهور للمستخدم بشكل مباشر ونق ّدم له عوضا عن ذلك‬ ‫توابع )أو ما ٌعرف فً لغات أخرى مثل ‪ java‬و ‪ C#‬باسم الطرق ‪ (mehods‬لتقوم بالتواصل مع بٌانات‬ ‫الصفّ ‪ .‬لنفترض أن لدٌنا المثال التالً ‪:‬‬ ‫‪Enter Your age(1 to 110):21‬‬ ‫‪Your age is: 21‬‬

‫>‪#include<iostream‬‬ ‫;‪using namespace std‬‬ ‫‪class Person‬‬ ‫{‬ ‫‪public :‬‬ ‫;‪int age‬‬ ‫;}‬ ‫)(‪void main‬‬ ‫{‬ ‫;‪Person my_person‬‬ ‫;" ‪cout<<"Enter Your age(1 to 110):‬‬ ‫; ‪cin >> my_person.age‬‬ ‫‪cout<<"\nYour age is: " << my_person.age‬‬ ‫;‪<< endl‬‬ ‫}‬

‫تستطٌع أن ترى أ ّننا تمك ّنا من الوصول إلى المتغٌّر ‪ age‬فً الكابن ‪ my_person‬و تخزٌن القٌمة ‪ 12‬فٌه‬ ‫مباشرة وهذه هً المشكلة تصوّ ر أنّ المستخدم أدخل رقما من خارج مجال األعداد الصحٌحة ماذا لو أدخل‬ ‫المستخدم رمزا أو ح ّتى حرفا ؟ فً هذه الحالة سٌحدث خطؤ وقد ٌتسبب بتوقف البرنامج عن العمل‪ٌ .‬بدو مثل‬ ‫هذا الخطؤ مستبعدا فً حالتنا ولك ّنه من المحتمل أن ٌحدث ومه ّمتك عزٌزي المبرمج أن تمنعه من أن ٌحدث‪.‬‬ ‫ولكن كٌف ؟ ٌبدو هذا السإال ذكٌا واإلجابة علٌه ستكون سهلة ألنّ ما سنقوم به هو أ ّننا سنعمل تغلٌفا ألعضاء‬ ‫هذا الصفّ بحٌث نمنع بٌاناته )متغٌّراته( من الظهور للمستخدم بشكل مباشر وسنقدّم له بدال من ذلك إحدى‬ ‫الطرٌقتٌن التالٌتٌن‪:‬‬

‫‪251‬‬


: private ‫ للوصول إلى أعضاء‬public ‫ استخدام توابع‬-a #include<iostream> using namespace std; class Person { int m_age ; public : void SetAge(int p_age) { if (p_age > 100 || p_age < 1) { cout<< "you can't edit age like that"; m_age =1 ; } else { m_age = p_age; cout<< "done "; } } int GetAge() { return m_age; } }; void main() { Person my_person; int my_age =0; cout<<"Enter Your age(1 to 110): "; cin>> my_age; my_person.SetAge(my_age) ; cout<<"\nYourage is: "<<my_person.GetAge() << endl; }

Enter Your age(1 to 110):21 done Your age is: 21

‫ أضف المشٌّد التالً إلى البرنامج السابق )ال تنس أنّ المشٌّد العادي لن ٌكون موجودا بعدها‬: ‫ استخدام المش ٌّد ات‬-b (‫ح ّتى تضٌفه بنفسك‬

Person(int p_age) { if (p_age > 100 || p_age < 1) { cout<< "you can't edit age like that"; m_age =1 ; } else { m_age = p_age; cout<< "done"; } }

252


‫قبل الحدٌث عن الوراثة لنتعرّ ف على التوابع الصدٌقة ألنها مهمّة لنا فً دراسة الوراثة‬

‫التوابع ‪( friend‬الكلمة المفتاحٌة ‪)friend‬‬ ‫ٔؼٍُ ّ‬ ‫أْ ٕ٘بن صالصخ ِؼشّفبد ‪ٚ‬ط‪ٛ‬ي ٘‪ٚ private, public, protected :ٟ‬لٍٕب ف‪ ٟ‬اٌؾبٌخ اٌز‪٠ ٟ‬ى‪ ْٛ‬ف‪ٙ١‬ب ػؼ‪ٛ‬‬ ‫ّ‬ ‫اٌظف‪ٚ .‬ػٍ‪ ٝ‬اٌشّغُ ِٓ رٌه‬ ‫ِب ِٓ أؽذ اٌّغز‪ private ٓ١٠ٛ‬أ‪ protected ٚ‬فال ‪ّ٠‬ىٓ اٌ‪ٛ‬ط‪ٛ‬ي ئٌ‪ ِٓ ٗ١‬خبسط‬ ‫ّ‬ ‫اٌظف‪ ,‬ػٕذ٘ب ‪ّ٠‬ىٓ اٌ‪ٛ‬ط‪ٛ‬ي ئٌ‪٘ ٝ‬زا‬ ‫‪ّ٠‬ىٕه أْ رزؼ ّذ‪٘ ٜ‬زٖ اٌمبػذح ثبعزخذاَ اٌىٍّخ اٌّؾغ‪ٛ‬صح ‪ friend‬ف‪ٟ‬‬ ‫ّ‬ ‫ّ‬ ‫اٌظف‬ ‫اٌظف‪ٌٚ .‬فؼً رٌه ػٍ‪١‬ه فمؾ أْ رظشّػ ػٓ اٌؼؼ‪ ٛ‬اٌز‪ ٞ‬رش‪٠‬ذ اٌ‪ٛ‬ط‪ٛ‬ي ئٌ‪ ِٓ ٗ١‬خبسط‬ ‫اٌؼؼ‪ ِٓ ٛ‬خبسط‬ ‫ثبعزخذاَ اٌزؼش‪٠‬ف اٌّجذئ‪ prototype ٟ‬ص ُّ رزوش ٘زٖ اٌىٍّخ أِبِٗ‪ِ .‬ضبي‪:‬‬ ‫‪24‬‬

‫‪// friend functions‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CRectangle‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫;)‪void set_values (int, int‬‬ ‫};)‪int area (void) {return (width * height‬‬ ‫;)‪friend CRectangle duplicate (CRectangle‬‬ ‫;}‬ ‫{ )‪void CRectangle::set_values (int a, int b‬‬ ‫;‪width = a‬‬ ‫;‪height = b‬‬ ‫}‬ ‫)‪CRectangle duplicate (CRectangle rectparam‬‬ ‫{‬ ‫;‪CRectangle rectres‬‬ ‫;‪rectres.width = rectparam.width*2‬‬ ‫;‪rectres.height = rectparam.height*2‬‬ ‫;)‪return (rectres‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪CRectangle rect, rectb‬‬ ‫;)‪rect.set_values (2,3‬‬ ‫;)‪rectb = duplicate (rect‬‬ ‫;‪cout << rectb.area() << endl‬‬ ‫}‬

‫من تعرٌف التابع ‪ duplicate‬نجد أنه من النوع ‪ friend‬فً الصفّ ‪ ,CRectangle‬ما ٌجعلنا قادرٌن‬ ‫على الوصول إلى المتغٌّرٌن ‪ width‬و ‪ height‬علما أ ّنهما من المستوى ‪ private‬وذلك من أي كابن‬ ‫من النوع ‪.CRectangle‬‬ ‫الحظ أ ّننا لم نعتبر التابع ‪ duplicate‬عضوا من الصفّ ‪ CRectangle‬ال فً التصرٌح عنه وال فً‬ ‫االستخدام األخٌر فً التابع )(‪ .main‬كما ٌمكن له أن ٌؤخذ المستوى العام ‪ public‬أو الخاص‬ ‫‪ private‬فهذا لن ٌإثر على استخدامنا له‪.‬‬ ‫ٌمكن استخدام التوابع من هذا النوع من أجل القٌام بعملٌات على ص ّفٌن من نوعٌن مختلفٌن‪ .‬عموما هذا‬ ‫االستخدام لٌس من مبادئ البرمجة كابنٌة التوجه ‪ OOP‬لذلك من األفضل استخدام أعضاء من ضمن الصفّ‬ ‫فمثبل سٌكون من المفٌد )بغرض اختصار الشٌفرة( فً المثال السابق لو قمنا بكتابة التابع ‪ duplicate‬بشكل‬ ‫كامل على أنه عضو من الصفّ ‪.CRectangle‬‬ ‫‪253‬‬


friend ‫الصفوف من النوع‬ ً‫ كصدٌق لصفّ آخر كما فعلنا فً التوابع من هذا النوع ف‬friend ‫ٌمكننا أن نص ّرح عن صفّ من النوع‬ ‫ من الوصول إلى كا ّفة أعضاء الصفّ اآلخر ح ّتى التً من‬friend ‫الفقرة السابقة ممّا ٌم ّكن الصفّ الصدٌق‬ :‫ مثال‬.protected ‫ أو‬private ‫المستوى‬ // friend class #include <iostream> using namespace std; class CSquare; class CRectangle { int width, height; public: int area (void) {return (width * height);} void convert (CSquare a); }; class CSquare { private: int side; public: void set_side (int a) {side=a;} friend class CRectangle; }; void CRectangle::convert (CSquare a) { width = a.side; height = a.side; } int main () { CSquare sqr; CRectangle rect; sqr.set_side(4); rect.convert(sqr); cout << rect.area() << endl; return 0; }

16

ّ‫ لذلك فإن‬CSquare ّ‫ للصف‬friend ‫ على أ ّنه صدٌق‬CRectangle ّ‫صرّ حنا فً هذا المثال عن الصف‬ .CSquare ّ‫ ٌمكنه الوصول إلى كل أعضاء الصف‬CRectangle ّ‫الصف‬ ّ ‫ غرٌبة بعض الشًء فً الواقع‬class CSquare ; ‫ربما تجد التعلٌمة‬ ً‫تمثل هذه التعلٌمة التصرٌح المبدب‬ ‫ ولو لم‬convert() ‫ أل ّننا استخدمنا هذا الصفّ كوسٌط فً التابع‬CSquare ّ‫ عن الصف‬prototype ّ‫نقم بالتصرٌح عنه بهذا الشكل لكان من غٌر الممكن استدعاإه كوسٌط فً هذا التابع من الصف‬ .CRectangle ‫ ما ٌعنً أنّ بإمكانه أن‬CSquare ّ‫ للصف‬friend ‫ صدٌق‬CRectangle ّ‫فً حالتنا هذه اعتبرنا أن‬ ‫ أو‬private ‫ ح ّتى ولو كان من المستوى‬CSquare ّ‫ٌصل إلى أيّ عضو موجود فً الصف‬ ‫ صدٌقا‬SCquare ّ‫ممكن علما أ ّنه ال شًء ٌمنعنا من أن نجعل الصف‬ ‫العكس غٌ ُر‬ ّ‫ و لكن‬protected َ ٍ .CRectangle ّ‫ للصف‬friend

254


‫‪ -2‬الوراثة بٌن الصفوف ‪Inheritance between classes‬‬

‫آخر )أبٍ( حٌث‬ ‫تع ّد الوراثة ص ّفة مه ّمة من صفات الصفوف‪ .‬فهً تسمح لنا بإنشاء كابنا )ابنا( مشت ّقا من‬ ‫كابن َ‬ ‫ٍ‬ ‫ٌصبح الكابنُ االبنُ حاوٌا على بعض صفات )خصابص( الكابن األبّ باإلضافة إلى صفاته األساسٌة‪) .‬الصفات‬ ‫هً األعضاء العالمّة المعرّ فة فً الصفّ والتً تسمح بالتعامل معه(‪ .‬لنؤخذ مثاال على ذلك‪:‬‬ ‫لنفترض أ ّننا أردنا أن ننشا مجموعة من الصفوف تصف األشكال الهندس ٌّة ذوات األضبلع ‪ polygons‬كالتً‬ ‫أنشؤناها سابقا مثل ‪ CRectangle‬أو ‪ .CTriangle‬هذه األشكال تمتلك بعض الصفات األساس ٌّة المشتركة بٌنها‬ ‫جمٌعا‪ ,‬فك ٌّل هذه األشكال تمتلك قاعدة )عرض( وارتفاع‪.‬‬ ‫لذلك سنقوم بالتصرٌح عن صفّ ٌحوي الصفات المشتركة )عرض و ارتفاع( لك ِّل األشكال المضلّعة وسنسمٌه‬ ‫‪ CPolygon‬حٌث أنّ كل شكل مضلّع ٌستطٌع أن ٌرث صفاته األساس ٌّة من الصفّ ‪ .CPolygon‬كما فً‬ ‫الشكل‪:‬‬

‫الصفوف التً ُتش َت ّق من الصفوف األساسٌّة ترث جمٌع أعضابها الظاهرة‪ .‬وهذا ٌعنً أ ّنه لو كان الصفّ‬ ‫األساسًّ ٌمتلك عضوا ‪ S‬ولو صنعنا ص ّفا ّ جدٌدا فٌه العضو ‪ B‬وٌرث الصفّ األساسًّ فإنّ الصفّ الجدٌد‬ ‫سٌمتلك العضوٌن ‪ S‬و ‪ B‬معا‪.‬‬ ‫ا‬ ‫وراثة بٌن ص ّفٌن؟ ٌت ّم ذلك باستخدام المعامل ) ‪ ( :‬الذي ٌُخبر المترجم بؤنّ الصفّ الذي‬ ‫كٌف ٌمكننا أن نجري‬ ‫قبل )على ٌسار( هذا المعامل سٌرث الصفّ الذي بعده )على ٌمٌنه(‪ .‬بالطرٌقة التالٌة‪:‬‬ ‫;‪class derived_class_name : public base_class_name‬‬ ‫حٌث أن ‪:‬‬ ‫‪ :derived_class_name‬اسم الصفّ المشتق‪.‬‬ ‫‪ :base_class_name‬اسم الصفّ األساسً‪.‬‬ ‫‪ :public‬معرّ ف الوصول ٌمكن أن ٌُستب َدل بؤيٍّ من المعرّ فٌن اآلخرٌن )‪ .(private, protected‬وسنتعرّ ف‬ ‫على فابدته بعد المثال‪:‬‬ ‫‪20‬‬ ‫‪10‬‬

‫‪// derived classes‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CPolygon‬‬ ‫‪protected:‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫)‪void set_values (int a, int b‬‬ ‫};‪{ width=a; height=b‬‬ ‫;}‬ ‫{ ‪class CRectangle: public CPolygon‬‬ ‫‪public:‬‬ ‫)‪int area (void‬‬ ‫} ;)‪{ return (width * height‬‬ ‫;}‬

‫‪255‬‬


‫{ ‪class CTriangle: public CPolygon‬‬ ‫‪public:‬‬ ‫)‪int area (void‬‬ ‫} ;)‪{ return (width * height / 2‬‬ ‫;}‬ ‫{ )( ‪int main‬‬ ‫;‪CRectangle rect‬‬ ‫;‪CTriangle trgl‬‬ ‫;)‪rect.set_values (4,5‬‬ ‫;)‪trgl.set_values (4,5‬‬ ‫;‪cout << rect.area() << endl‬‬ ‫;‪cout << trgl.area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫كما ترى فإنّ ّ‬ ‫كبل من الص ّفٌن ‪ CRectangle‬و ‪ٌ CTriangle‬حتوي على األعضاء‬ ‫)(‪ width, height, set_values‬الموجودٌن أساسا فً الصفّ ‪.CPolygon‬‬ ‫ّ‬ ‫نشتق )نرث( الصفوف من بعضها‪.‬‬ ‫الكلمة ‪ protected‬مشابهة للكلمة ‪ private‬والفرق الوحٌد ٌحدث عندما‬ ‫ّ‬ ‫نشتق )نرث( ص ّفا من صفّ ما آخر فإنّ األعضاء من النوع ‪ protected‬الموجودة فً الصفّ األساسً‬ ‫عندما‬ ‫ٌمكن الوصول إلٌها من قبل أعضاء الصفّ الجدٌد بٌنما تلك التً من النوع ‪ private‬فبل ٌمكن الوصول إلٌها‬ ‫ّإال من خبلل الصفّ األساسًّ نفسه‪.‬‬ ‫و ألننا نرٌد أن نتعامل مع ك ٍّل من العضوٌن ‪ width, height‬من خبلل الصفوف الجدٌدة المشت ّقة من الصفّ‬ ‫‪ CPolygon‬لذلك صرّ حنا عنهما على أ ّنهما من النوع ‪.protected‬‬ ‫الحظ الجدول التالً الذي ٌح ِّدد الفرق بٌن مع ّرفات الوصول‪.‬‬ ‫إمكانٌة الوصول إلى‬ ‫صف‬ ‫األعضاء من نفس ال ّ‬ ‫األعضاء من الصفوف المشتقة‬

‫‪public‬‬

‫‪protected‬‬

‫‪‬‬ ‫‪‬‬

‫‪‬‬ ‫‪‬‬

‫‪private‬‬

‫‪‬‬ ‫‪‬‬

‫فً مثالنا ‪ ,‬األعضاء الموروثة فً ك ّل من الص ّفٌن ‪ CTriangle, CRectangle‬تتبع نفس مستوٌات الوصول‬ ‫فً الصفّ األساسً ‪.CPolygon‬‬ ‫‪CPolygon::width‬‬ ‫‪// protected access‬‬ ‫‪CRectangle::width‬‬ ‫‪// protected access‬‬ ‫‪CPolygon::set_values() // public access‬‬ ‫‪CRectangle::set_values() // public access‬‬ ‫وذلك أل ّننا استخدمنا المعرف ‪ public‬الشتقاقهما )لٌرثا( من الصفّ ‪ CPolygon‬كما ٌلً ‪:‬‬ ‫;‪class CRectangle : public CPolygon‬‬ ‫إنّ الكلمة المفتاحٌة ‪ّ public‬‬ ‫تمثل أدنى مستوى من الحماٌة لؤلعضاء الموروثة من الصفّ األساسًّ وٌمكن‬ ‫تغٌ​ٌر هذا المستوى لٌكون أحد المستوٌ​ٌن اآلخرٌن‪ .‬كمثال لنفترض أ ّننا عرّ فنا الصفّ الجدٌد ‪daughter‬‬ ‫ّ‬ ‫المشتق من الصفّ األساسًّ ‪ mother‬وفق المستوى ‪ protected‬كاآلتً‪:‬‬ ‫;‪class daughter : protected mother‬‬ ‫هذا ما سٌجعل المستوى ‪ protected‬هو المستوى األدنى لحماٌة أعضاء الصفّ األساسً ألنّ ك ّل أعضابه‬ ‫التً كانت من النوع ‪ public‬فً الصفّ ‪ mother‬ستصبح من النوع ‪ protected‬فً الصفّ ‪.daughter‬‬ ‫صة به من النوع ‪ public‬ألنّ التغٌ​ٌر فً‬ ‫بالطبع هذا ال ٌمنع من أن ٌحوي الصفّ ‪ daughter‬على أعضاء خا ّ‬ ‫مستوى الوراثة سٌطبق على أعضاء الصفّ األساسًّ ‪ mother‬فقط‪.‬‬ ‫‪256‬‬


‫أمّا استخدام الكلمة ‪ private‬ف ٌُعتبر األكثر انتشارا بعد الكلمة ‪ public‬وذلك أل ّنها تإ ِّمن تغلٌفا كامبل ألعضاء‬ ‫الصفّ األساسً حٌث ال ٌمكن الوصول إلى أعضاء الصفّ األساسً ّإال من داخله‪.‬‬ ‫على ك ٍّل إذا لم تذكر معرّ ف الوصول بشكل صرٌح أثناء تعلٌمة الوراثة فإنّ المعرّ ف االفتراضً هو ‪private‬‬ ‫وذلك من أجل الصفوف المعرّ فة باستخدام الكلمة ‪ ,class‬أ ّما تلك المعرفة باستخدام الكلمة ‪ struct‬فإنّ المعرّ ف‬ ‫االفتراضً لها هو ‪.public‬‬ ‫صف األساسً؟ بحسب مبادئ الوراثة فإنّ ك ّل أعضاء الصفّ األساسً‬ ‫ما هً األشٌاء التً ٌت ّم وراثتها من ال ّ‬ ‫ستورَّ ُ‬ ‫ّ‬ ‫)المشتق( ما عدا األعضاء التالٌة‪:‬‬ ‫ث إلى الصفّ االبن‬ ‫‪ Constructor and destructor‬‬ ‫‪ operator=() member‬‬ ‫‪ friends‬‬ ‫على الرغم من أنّ المشٌّد والهادم ال تت ّم وراثته ّإال أ ّنه سٌت ّم استدعاء المشٌّد االفتراضً )كالمشٌّد العادي مثبل(‬ ‫ّ‬ ‫مشتق من الصفّ األساسًّ ‪ .‬أمّا إذا لم ٌكن فً الصفّ‬ ‫أو الهادم من الصفّ ألساسً عند إنشاء أو هدم أيّ صفّ‬ ‫األساسًّ مشٌّد افتراضً )أل ّنك قمت بإعادة تحمٌل المشٌّد بطرٌقة ما( و أردت أن ٌت ّم استدعاء المشٌّد الجدٌد فً‬ ‫ك ّل مرّ ة ٌت ّم فٌها إنشاء صفّ جدٌد فعلٌك أن تصرّ ح عن ذلك بالشكل ‪:‬‬ ‫}…{ (‪derived_class_name )parameters( : base_class_name )parameters‬‬ ‫‪mother:‬‬ ‫‪no‬‬ ‫‪parameters‬‬ ‫‪daughter: int parameter‬‬ ‫‪mother:‬‬ ‫‪int‬‬ ‫‪parameter‬‬ ‫‪son: int parameter‬‬

‫‪// constructors and derivated classes‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class mother‬‬ ‫‪public:‬‬ ‫)( ‪mother‬‬ ‫} ;"‪{ cout << "mother: no parameters\n‬‬ ‫)‪mother (int a‬‬ ‫} ;"‪{ cout << "mother: int parameter\n‬‬ ‫;}‬ ‫{ ‪class daughter : public mother‬‬ ‫‪public:‬‬ ‫)‪daughter (int a‬‬ ‫};"‪{cout<< "daughter: int parameter\n\n‬‬ ‫;}‬

‫{ ‪class son : public mother‬‬ ‫‪public:‬‬ ‫)‪son (int a) : mother (a‬‬ ‫} ;"‪{ cout << "son: int parameter\n\n‬‬ ‫;}‬ ‫{ )( ‪int main‬‬ ‫;)‪daughter x (1‬‬ ‫;)‪son y (1‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪257‬‬


‫راقب الفرق بٌن المشٌّد من الصفّ األساسً الذي ت ّم استدعاإه عندما أنشؤنا الكابن ‪ x‬من الصفّ ‪ daughter‬و‬ ‫المشٌّد الذي ت ّم استدعاإه عندما أنشؤنا الكابن ‪ y‬من الصفّ ‪ son‬هذا الفرق سببه أ ّننا عرّ فنا المشٌّد فً الصفّ‬ ‫‪ daughter‬بالشكل التالً‪:‬‬ ‫)‪daughter (int a‬‬ ‫فً هذه الحالة سٌت ّم استدعاء المشٌّد االفتراضً من الصفّ األساسً وهو )(‪ mother‬وذلك أل ّننا لم نخبر‬ ‫المترجم أيّ المشٌّدات علٌه أن ٌستدعٌه فهو ٌقوم باستدعاء المشٌّد االفتراضً‪.‬‬ ‫أ ّما فً الصفّ ‪ son‬فإنّ المشٌّد كان بالشكل التالً‪:‬‬ ‫)‪son (int a) : mother (a‬‬ ‫فً هذه الحالة أخبرنا المترجم أنّ علٌه أن ٌستدعً المشٌّد الذي ٌقبل وسٌطا من النوع ‪ int‬وذلك باستخدام‬ ‫المعامل ‪ :‬عند التصرٌح عن المشٌّد فً الصفّ الجدٌد‪.‬‬

‫الوراثة المتعددة‬

‫‪Multiple inheritance‬‬

‫ٌمكنك فً ‪ C++‬أن تصنع ص ّفا ٌرث صفاته من أكثر من صفّ فً نفس الوقت وهذا ٌشبه تماما ما ٌحدث‬ ‫لئلنسان فكلنا ٌعلم أنّ الصفات التً تكون فً المولود الصغٌر بعضُها قاد ٌم من األب و بعضُها اآلخر من األم أي‬ ‫أ ّنه لو افترضنا أنّ لدٌنا ص ّفا ٌمثل المولود وآخر ّ‬ ‫ٌمثل األب وثالث ٌمثل األم فإنّ بإمكان الصفّ المولود أن ٌرث‬ ‫من األب واألم معا‪ .‬تت ّم هذه العملٌة بؤن نضع فاصلة ) ‪ ( ,‬بٌن أسماء الصفوف التً نرٌد من الصفّ الجدٌد أن‬ ‫ٌرثها كما ٌلً‪:‬‬ ‫; ‪class derived_class_name : public base_class_name1 , base_class_name2‬‬ ‫مثال آخر‪ ,‬لو عرّ فنا ص ّفا جدٌدا أسمٌناه ‪ COutput‬و أردنا من الص ّفٌن ‪ CTriangle, CRectangle‬أن ٌرثا‬ ‫الصفات الموجودة فً هذ الصفّ باإلضافة إلى تلك التً ورثاها سابقا من الصفّ ‪ CPolygon‬فبإمكاننا أن نكتب‬ ‫عندها ‪:‬‬ ‫{ ‪class CRectangle : public CPolygon, public COutput‬‬ ‫{ ‪class CTriangle : public CPolygon, public COutput‬‬ ‫إلٌك المثال كامبل‪:‬‬ ‫‪20‬‬ ‫‪10‬‬

‫‪// multiple inheritance‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CPolygon‬‬ ‫‪protected:‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫)‪void set_values (int a, int b‬‬ ‫};‪{ width=a; height=b‬‬ ‫;}‬ ‫{ ‪class COutput‬‬ ‫‪public:‬‬ ‫;)‪void output (int i‬‬ ‫;}‬

‫‪258‬‬


void COutput::output (int i) { cout << i << endl; } class CRectangle: public CPolygon, public COutput { public: int area (void) { return (width * height); } }; class CTriangle: public CPolygon, public COutput { public: int area (void) { return (width * height / 2); } }; int main () { CRectangle rect; CTriangle trgl; rect.set_values (4,5); trgl.set_values (4,5); rect.output (rect.area()); trgl.output (trgl.area()); return 0; }

Polymorphism ‫ تعدد األشكال‬-3 ‫ٌسمح هذا المبدأ بكتابة صفّ ٌحتوي على الهٌكل العام للصفّ من دون أٌّة تعلٌمات )تضمٌنات( لكً ٌجبر‬ .‫المبرمجٌن الذٌن سٌشت ّقون هذا الصفّ على تضمٌن الكابنات التً ٌنشإنها من هذا الصفّ من جدٌد‬ ّ ‫من أجل فهم أفضل للفقرات التالٌة ننصح بالتم ّكن من المفاهٌم التالٌة )المإ‬ ‫ إذا‬.( ‫شرات – الوراثة بٌن الصفوف‬ : ‫كانت إحدى العبارات التالٌة غٌر مفهومة عندك ننصحك بالتم ّرن على المفاهٌم السابقة الذكر بشكل أفضل‬ int a::b(c) {}; // Classes a->b // pointers and objects class a: public b; // Relationships between classes

ّ ‫المؤ‬ Pointers to base class ً‫صف األساس‬ ّ ‫شرات على ال‬ ّ ‫واحدة من أه ّم المٌزات التً نحصل علٌها باشتقاق أصناف جدٌدة من أصناف أساسٌّة هً أنّ المإ‬ ٍّ‫شر على أي‬ ّ ‫من األصناف المشت ّقة متوافق مع مإ‬ .‫شر على الصفّ األساسً الذي اش ُت ّق منه هذا الصف‬ ‫ سنقوم بكتابة برنامج‬,‫ كمثال‬.C++ ‫هذه الفقرة مخصّصة بالكامل للحدٌث عن قوّ ة هذه المزاٌا التً تقدمها‬ : ‫األشكال الهندسٌة السابق باستخدام هذه المزٌّة‬ // pointers to base class #include <iostream> using namespace std; class CPolygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } }; class CRectangle: public CPolygon { public: int area (void)

259

20 10


‫} ;)‪{ return (width * height‬‬ ‫;}‬ ‫{ ‪class CTriangle: public CPolygon‬‬ ‫‪public:‬‬ ‫)‪int area (void‬‬ ‫} ;)‪{ return (width * height / 2‬‬ ‫;}‬ ‫{ )( ‪int main‬‬ ‫;‪CRectangle rect‬‬ ‫;‪CTriangle trgl‬‬ ‫;‪CPolygon * ppoly1 = &rect‬‬ ‫;‪CPolygon * ppoly2 = &trgl‬‬ ‫;)‪ppoly1->set_values (4,5‬‬ ‫;)‪ppoly2->set_values (4,5‬‬ ‫;‪cout << rect.area() << endl‬‬ ‫;‪cout << trgl.area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫فً التابع الربٌسً )(‪ main‬أنشؤنا مإ ّ‬ ‫شرٌن ‪ * ppoly1 , * ppoly2‬على كابنٌن من الصفّ ‪.CPolygon‬‬ ‫و أسندنا ألٌهما عنوانً الكابنٌن ‪ rect, trgl‬وأل ّنهما كابنٌن من ص ّفٌن مشت ّقٌن من الصفّ األساسًّ ‪CPolygon‬‬ ‫فإنّ هذا اإلسناد ممكن‪ .‬نستطٌع أن نستخدم المإ ّ‬ ‫شرات من نوع الصفّ األساسً لنشٌر بها على األعضاء‬ ‫الموروثة فً الصفوف المشت ّقة منه فقط لذلك لم نقم باستخدامهما فً استدعاء التابع )(‪ area‬وقمنا باستدعابه‬ ‫بالطرٌقة المعتادة‪.‬‬

‫األعضاء من النوع ‪virtual‬‬ ‫فً المثال السابق كً نستطٌع التؤشٌر على التابع )(‪ٌ area‬جب أن نجعله عضوا فً الصفّ األساسً ولكن هذا‬ ‫سٌتسبب بمشكلة جدٌدة هً أنّ كبل من الص ّفٌن ‪ٌ CRectangle, CTriangle‬رثان صفاتهما من الصفّ‬ ‫األساسً و التابع )(‪ area‬هو واحد من هذه الصفات ّإال أنّ مساحة المستطٌل ناتجة عن ضرب الطول‬ ‫بالعرض‪ ,‬ومساحة المثلث ناتجة عن ضرب الطول بالعرض وتقسٌم الناتج على ‪ ,3‬فما هو الحل؟‪.‬‬ ‫الحل ٌكمن فً أن نقوم بكتابة التابع )(‪ area‬فً كل من الصفٌّن ‪ CRectangle, CTriangle‬ولكً نصبح‬ ‫قادرٌن على التؤشٌر علٌهما باستخدام مإ ّ‬ ‫شر من نفس نوع الصفّ األساسً سنقوم بتعرٌفه فً الصفّ األساسً‬ ‫ّ‬ ‫أٌضا لكن سٌكون تعرٌفه من نوع خاصّ هو النوع ‪ ,virtual‬ث ّم نقوم بتعرٌفه بنفس االسم فً ك ّل من الصفٌن‬ ‫‪ CRectangle, CTriangle‬ونقوم بكتابة التعلٌمات المناسبة لك ّل منهما من جدٌد وهذا ما ٌُعرف بإعادة القٌادة‬ ‫‪.Overriding‬‬ ‫إذن األعضاء من النوع ‪ virtual‬هً األعضاء المشتركة التً نرغب بؤن ترثها كل الصفوف المشتقة من‬ ‫الصفّ األساسً والتً سنعٌد كتابة تعلٌماتها )‪ (overriding‬داخل بعض أو كل الصفوف التً ترث الصفّ‬ ‫األساسً‪.‬‬ ‫و بعد التعدٌل ٌصبح المثال بالشكل‪:‬‬ ‫‪20‬‬ ‫‪10‬‬ ‫‪0‬‬

‫‪// virtual members‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CPolygon‬‬ ‫‪protected:‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫)‪void set_values (int a, int b‬‬ ‫} ;‪{ width=a; height=b‬‬ ‫)‪virtual int area (void‬‬ ‫} ;)‪{ return (0‬‬

‫‪25:‬‬


‫;}‬ ‫{ ‪class CRectangle: public CPolygon‬‬ ‫‪public:‬‬ ‫)‪int area (void‬‬ ‫} ;)‪{ return (width * height‬‬ ‫;}‬ ‫{ ‪class CTriangle: public CPolygon‬‬ ‫‪public:‬‬ ‫)‪int area (void‬‬ ‫} ;)‪{ return (width * height / 2‬‬ ‫;}‬ ‫{ )( ‪int main‬‬ ‫;‪CRectangle rect‬‬ ‫;‪CTriangle trgl‬‬ ‫;‪CPolygon poly‬‬ ‫;‪CPolygon * ppoly1 = &rect‬‬ ‫;‪CPolygon * ppoly2 = &trgl‬‬ ‫;‪CPolygon * ppoly3 = &poly‬‬ ‫;)‪ppoly1->set_values (4,5‬‬ ‫;)‪ppoly2->set_values (4,5‬‬ ‫;)‪ppoly3->set_values (4,5‬‬ ‫;‪cout << ppoly1->area() << endl‬‬ ‫;‪cout << ppoly2->area() << endl‬‬ ‫;‪cout << ppoly3->area() << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫تستطٌع أن ترى اآلن أنّ ّ‬ ‫كبل من الصفوف (‪ )CPolygon, CTriangle, CRectangle‬تمتلك نفس األعضاء‬ ‫( )(‪.) width, height, set_value(), area‬‬ ‫و اآلن جرّ ب أن تزٌل الكلمة المحجوزة ‪ virtual‬ث ّم ش ّغل البرنامج‪ ,‬ماذا ترى؟ النتٌجة ستكون ‪ 0‬فً الحاالت‬ ‫الثبلث بدال من ‪ ,20, 10, 0‬ولكن لماذا؟ أل ّنك عندما أزلت الكلمة ‪ virtual‬من أمام التصرٌح عن التابع‬ ‫)(‪ area‬فً الصفّ ‪ CPolygon‬ث ّم استخدمت مإ ّ‬ ‫شرا من نوع هذا الصفّ لتشٌر إلى التابع )(‪ area‬فً ك ّل‬ ‫من الكابنٌن ‪ rect , trgl‬فإنّ المإ ّ‬ ‫شر سٌشٌر إلى التابع فً الصفّ األساسً والذي ٌعٌد القٌمة ّ كما هو واضح‬ ‫من تعرٌفه أمّا الكابن ‪ poly‬فهو أصبل من النوع ‪ CPolygon‬والتابع المعرّ ف فٌه ٌعٌد ‪ 0‬دابما‪.‬‬ ‫إنّ ما تفعله هذه الكلمة هو أ ّنها تسمح باستدعاء العضو من الصفّ المشتق والذي ٌمتلك نفس اسم العضو فً‬ ‫الصفّ األساسً عندما ٌستخدم المإ ّ‬ ‫شر‪ ,‬كما فً المثال السابق‪.‬‬ ‫ال ٌقتصر األمر فقط على استخدام المإ ّ‬ ‫شرات ففً هذه الحالة التابع )(‪ area‬هو أصبل من الصفات المشتركة‬ ‫فً كل األشكال الهندسٌة المضلّعة المغلقة لذلك علٌنا أن نقوم بوضعه فً الصفّ األساسً ‪ CPolygon‬وألنّ‬ ‫طرٌقة حساب مساحة كل شكل تختلف عن الطرق األخرى فإ ّننا نصرّ ح عن التابع )(‪ area‬فً الصفّ األساسًّ‬ ‫على أ ّنه من النوع ‪ virtual‬ث ّم نعٌد قٌادته فً الصفوف المشت ّقة‪.‬‬ ‫ومثال ذلك لو افترضنا أنّ لدٌنا ص ّفا أساسٌّا للمركبات ث ّم اشت ّقٌنا منه ص ّفا للسٌارة وآخر للدراجة النارٌة‪ ,‬معلو ٌم‬ ‫أنّ ك ّل المركبات تستخدم الوقود لكً تسٌر لذلك سنعرّ ف التابع )(‪ fuel‬فً الصفّ األساسً لٌحسب كمٌة الوقود‬ ‫البلزمة لقطع مسافة معٌّنة لكن هل تستهلك السٌارة نفس الكمٌة من الوقود التً تستهلكها الدراجة لتقطعا‬ ‫نفس المسافة؟ بالطبع ال و هذا االختبلف ٌجعل من األفضل أن نستخدم الكلمة ‪ virtual‬لنعٌد قٌادة التابع‬ ‫)(‪ fuel‬ضمن الصفّ المشتق كلّما دَ َعت الحاجة لذلك‪.‬‬

‫‪261‬‬


// virtual members #include <iostream > using namespace std; class Vehicle { protected: float distance ; public: Vehicle() { distance = 0.0; } void SetDistance(float d) { distance = d; } virtual float fuel() { return distance/5; } }; class Car: public Vehicle { public: float fuel() { return distance/10; } }; class Cycle:public Vehicle { public: float fuel() { return distance/15; } }; int main() { Vehicle myvehicle; Car mycar; Cycle mycycle; myvehicle.SetDistance(10); mycar.SetDistance(10); mycycle.SetDistance(10); cout<<"Vehikle need: "<<myvehicle.fuel() <<" leters of fuel in 10 KM\n"; cout<<"Car need: "<<mycar.fuel() <<" leters of fuel in 10 KM\n"; cout<<"Cycle need: "<<mycycle.fuel() <<" leters of fuel in 10 KM\n"; return 0; }

262

Vehikle need: 2 leters of fuel in 10 KM Car need: 1 leters of fuel in 10 KM MotoCicle need: 0.666667 leters of fuel in 10 KM


‫الصفوف األساس ٌّة المجردة ‪Abstract base classes‬‬ ‫الصفوف المجرّ دة البسٌطة هً ص ّفوف تشبه إلى ح ّد كبٌر الصفّ ‪ CPolygon‬الذي أنشؤناه سابقا والفرق‬ ‫البسٌط ٌكمن فً التابع )(‪ area‬المعرّ ف فً الصفّ ‪ CPolygon‬حٌث ال ٌمكن للص ّفوف المجرّ دة أن تحوي‬ ‫على تعلٌمات فً توابعها التً من النوع ‪ virtual‬وبدال من كتابة التابع بك ّل تعلٌماته فً الصفّ األساسً‬ ‫سنكتفً فقط بالتصرٌح عن التابع دون كتابة أيّ تعلٌمة فٌه ولن نضٌف له األقواس }{ أٌضا لكن ٌمكننا فً‬ ‫حالتنا هذه أن نضٌف إلى التعرٌف قٌمة ابتدابٌة لٌعٌدها التابع وذلك بإضافة اإلسناد التالً‪:‬‬ ‫; ‪virtual int area (void) = 0‬‬ ‫لٌصٌر عندها شكل الصفّ ‪ CPolygon‬كاآلتً‪:‬‬ ‫‪// abstract class CPolygon‬‬ ‫{ ‪class CPolygon‬‬ ‫‪protected:‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬ ‫)‪void set_values (int a, int b‬‬ ‫} ;‪{ width=a; height=b‬‬ ‫;‪virtual int area (void) =0‬‬ ‫;}‬ ‫الحظ كٌف أ ّننا أضفنا المساواة ‪ = 0‬إلى التعرٌف عن التابع عوضا عن كتابة جسمه كامبل‪ .‬هذا النوع من التوابع‬ ‫ٌدعى ‪ ,pure virtual function‬وك ّل الصفوف التً تحتوي على مثل هذا النوع من التوابع تدعى صفوفا‬ ‫مجرّ دة ‪.abstract classes‬‬ ‫االختبلف األكبر لهذه الصفوف عن غٌرها أ ّنه ال ٌمكننا أن ننشا منها نسخا جدٌدة فهً غٌر قابلة لبلشتقاق‪,‬‬ ‫لك ّنه ٌمكننا أن نشٌر إلٌها باستخدام مإ ّ‬ ‫شر ‪.‬‬ ‫عند ذلك فإن التعلٌمة ‪:‬‬ ‫; ‪CPolygon poly‬‬ ‫غٌر صحٌحة ألنّ الصفّ ‪ CPolygon‬أصبح اآلن من النوع المجرّ د ‪.abstract class‬‬ ‫لكن ٌمكننا أن نقوم بالتصرٌحٌن اآلتٌ​ٌن‪:‬‬ ‫;‪CPolygon * ppoly1‬‬ ‫;‪CPolygon * ppoly2‬‬ ‫وهذا ألنّ التوابع من النوع ‪ pure virtual function‬ال تحتوي على تعلٌمات بداخلها وهذا ٌجعل من‬ ‫المستحٌل إنشاء ُنسخ من الصفّ المجرّ د إذ أنّ بعض أعضابه ال تمتلك تعرٌفات كاملة لوظابفها‪ّ ,‬إال أ ّنه ٌمكننا‬ ‫أن نشٌر إلى الصفّ الذي ٌرث الصفّ األساسً المجرّ د باستخدام مإ ّ‬ ‫شر كما فً المثال التالً‪:‬‬ ‫‪20‬‬ ‫‪10‬‬

‫‪// virtual members‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪class CPolygon‬‬ ‫‪protected:‬‬ ‫;‪int width, height‬‬ ‫‪public:‬‬

‫‪263‬‬


void set_values (int a, int b) { width=a; height=b; } virtual int area (void) =0; }; class CRectangle: public CPolygon { public: int area (void) { return (width * height); } }; class CTriangle: public CPolygon { public: int area (void) { return (width * height / 2); } }; int main () { CRectangle rect; CTriangle trgl; CPolygon * ppoly1 = ▭ CPolygon * ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); cout << ppoly1->area() << endl; cout << ppoly2->area() << endl; return 0; }

‫لو أعدت النظر فً المثال السابق لرأٌت أ ّننا استطعنا أن نشٌر إلى كابنات من أنواع )صفوف( مختلفة باستخدام‬ ّ ‫نوع واحد من المإ‬ ً‫عضو ف‬ ‫تابع‬ ٍ ٍ ‫ تصوّ ر أ ّننا نرٌد اآلن إنشاء‬.‫ هذا الشًء مفٌ ٌد للغاٌة‬.* CPolygon ‫شرات‬ ‫ لٌطبع المساحة على الشاشة دون أن نع ّرف نوع الصفّ الذي ورث هذا التابع من‬CPolygon ً‫الصفّ األساس‬ .ً‫الصفّ األساس‬ // virtual members #include <iostream> using namespace std; class CPolygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } virtual int area (void) =0; void printarea (void) { cout << this->area() << endl; } }; class CRectangle: public CPolygon { public: int area (void) { return (width * height); } }; class CTriangle: public CPolygon { public: int area (void) { return (width * height / 2); } };

264

20 10


‫{ )( ‪int main‬‬ ‫;‪CRectangle rect‬‬ ‫;‪CTriangle trgl‬‬ ‫;‪CPolygon * ppoly1 = &rect‬‬ ‫;‪CPolygon * ppoly2 = &trgl‬‬ ‫;)‪ppoly1->set_values (4,5‬‬ ‫;)‪ppoly2->set_values (4,5‬‬ ‫;)(‪ppoly1->printarea‬‬ ‫;)(‪ppoly2->printarea‬‬ ‫;‪return 0‬‬ ‫}‬

‫تذكر‪ :‬تشٌر الكلمة)المإ ّ‬ ‫شر( ‪ this‬إلى الكابن الذي ٌت ّم تنفٌذه فً الذاكرة حالٌا‪.‬‬

‫إنّ الصفوف المجرّ دة و األعضاء ‪ virtual‬هً التً تمنح لغة ‪ C++‬خاصٌّة تعدد األشكال ‪Polymorphism‬‬ ‫التً تع ّد إحدى أه ّم مبادئ البرمجة كابن ٌّة التوجّ ه ‪.OOP‬‬ ‫بالطبع التطبٌقات التً أنشؤناها بسٌطة للغاٌة و لك ّنها فقط لتوضٌح هذه المبادئ و المٌزات ‪ ,‬و لكن تخٌل لو‬ ‫أكثر نفعا‪.‬‬ ‫أكثر إثارة و َ‬ ‫ط ّبقناها على مصفوفة من الكابنات بالطبع سٌكون األم ُر َ‬

‫‪265‬‬


‫الفصل التاسع شصر‪:‬‬

‫مالحظة‪ :‬القوالب من المٌزات الحدٌثة التً ت ّم إنتاجها مع لغة ‪ ANSI-C++‬القٌاس ٌّة‪ .‬لذلك إذا كنت‬ ‫تستعمل مترجما ا ال ٌدعم هذه اللغة القٌاس ٌّة فمن الممكن ّأال تكون قادراا على استخدامها‪.‬‬

‫تابع القوالب‬ ‫تسمح القوالب بإنشاء توابع عموم ٌّة تستطٌع أن تقبل أي نوع من البٌانات كوسطاء وتعٌد القٌمة المطلوبة من‬ ‫دون إعادة تحمٌل التابع أبدا‪ .‬وهذه التوابع العمومٌة تخضع للقاعدة التالٌة‪:‬‬ ‫; ‪template < typename identifier > function_declaration‬‬ ‫‪ : typename‬هو نوع البٌانات الممرّ رة و قد ٌكون نوعا أساس ٌّا أو نوعا معرّ فا )مثل الصفوف(‪.‬‬ ‫‪ : identifier‬اسم الوسٌط‪.‬‬ ‫مثال‪ :‬هذا التابع ٌعٌد أكبر كابن من الكابنٌن الممررٌن إلٌه )من النوع)الصفّ ( ‪.(GenericType‬‬ ‫> ‪template < class GenericType‬‬ ‫{ )‪GenericType GetMax (GenericType a, GenericType b‬‬ ‫; ) ‪return ( a > b ? a : b‬‬ ‫}‬ ‫كما ٌب ٌّن السطر األوّ ل فقد أنشؤنا قالبا لنوع )صفّ ( عا ّم من البٌانات دعوناه ‪ .GenericType‬لذلك فالتابع‬ ‫الذي تبل التصرٌح األوّ ل سٌؤخذ النوع المذكور ‪ GenericType‬كما اس ُتخ ِدم هذا النو ُع لتمرٌر وسٌطٌن منه‬ ‫إلى التابع )(‪ GetMax‬و الذي سٌعٌد أكبرهما‪.‬‬ ‫حتى اآلن لم ٌمثل النوع المعرف ‪ GenericType‬أي نوع منفصل من البٌانات‪ ,‬ولكن عندما سٌستدعى التابع‬ ‫سنكون قادرٌن على استبدال هذا النوع بؤي نوع آخر والذي سندعوه نموذجا ‪ .pattern‬للقٌام بذلك ٌمكننا أن‬ ‫نستدعً التابع العمومًّ بالطرٌقة التالٌة‪:‬‬ ‫; )‪function <pattern> (parameters‬‬ ‫‪ : pattern‬نوع البٌانات الذي سٌتم استبدال النوع ‪ GenericType‬به‪.‬‬ ‫فمثبل‪ :‬الستدعاء هذا التابع لٌقارن بٌن عددٌن صحٌحٌن نكتب‪:‬‬ ‫; ‪int x,y‬‬ ‫; )‪GetMax <int> (x,y‬‬ ‫واآلن س ٌُستدعى التابع )(‪ GetMax‬وكؤ ّنه أصبل من النوع ‪ .int‬لنكتب المثال بشكله النهابً‪:‬‬

‫‪266‬‬


‫‪6‬‬ ‫‪10‬‬

‫‪// function template‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫>‪template <class S‬‬ ‫{ )‪S GetMax (S a, S b‬‬ ‫;‪S result‬‬ ‫;) ‪return ( result = (a>b)? a : b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪int i=5, j=6, k‬‬ ‫;‪float l=10.0, m=5.0, n‬‬ ‫;)‪k=GetMax<int>(i,j‬‬ ‫;)‪n=GetMax<float>(l,m‬‬ ‫;‪cout << k << "\n" << n << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫فً هذه الحالة دعونا النوع العام باالسم ‪ S‬بدال من االسم ‪ GenericType‬كما وٌمكننا أن نستخدم أي اسم آخر‬ ‫علما أنّ االسم ‪ T‬هو األكثر شهرة مع القوالب )أل ّنه أوّ ل حرف من الكلمة ‪.(template‬‬ ‫تستطٌع أن ترى كٌف استخدمنا التابع )(‪ GetMax‬مع نوعٌن مختلفٌن من البٌانات (‪ )int , float‬مع أ ّننا لم نقم‬ ‫بإعادة تحمٌل التابع لٌستقبل أكثر من نوع‪.‬‬ ‫تستطٌع أن ترى أٌضا أ ّننا تمك ّنا من تعرٌف متغٌّر من النوع ‪ S‬داخل التابع )(‪GetMax‬‬ ‫;‪S result‬‬ ‫سٌت ّم استبدال المتغٌّر من النوع ‪ S‬بآخر من النوع المذكور بٌن القوسٌن >< عند استدعاء التابع )(‪.GetMax‬‬ ‫مالحظة‪ :‬فً هذه الحالة الوسطاء الممرّ رة إلى التابع هً من النوع ‪ S‬وهو نفس نوع البٌانات التً‬ ‫سٌعٌدها التابع لذلك فإنّ المترجم ٌستطٌع أن ٌعرف نوع البٌانات من خبلل الوسطاء الممرّ رة‬ ‫مباشرة دون أن نذكره بٌن القوسٌن <>‪ .‬كما ٌلً‪:‬‬ ‫; ‪int i, j‬‬ ‫;) ‪GetMax ( i , j‬‬ ‫‪6‬‬ ‫‪10‬‬

‫‪// function template‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫>‪template <class S‬‬ ‫{ )‪S GetMax (S a, S b‬‬ ‫;‪S result‬‬ ‫;))‪return (result = ((a>b)? a : b‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪int i=5, j=6, k‬‬ ‫;‪float l=10.0, m=5.0, n‬‬ ‫;)‪k=GetMax(i,j‬‬ ‫;)‪n=GetMax(l,m‬‬ ‫;‪cout << k << "\n" << n << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪267‬‬


‫بٌنما ال ٌمكننا كتابة التعلٌمات التالٌة بسبب االختبلف بٌن األنواع الممرّ رة إلى التابع ‪:‬‬ ‫;‪int i‬‬ ‫;‪long l‬‬ ‫;)‪k = GetMax (i,l‬‬ ‫حٌث أنّ التابع ٌنتظر م ّنا أن نمرر إلٌه متغٌّرٌن )كابنٌن( من نفس النوع )الصفّ (‪.‬‬ ‫ٌمكننا أن نصنع تابعا عموم ٌّا ٌقبل أكثر من نوع من البٌانات كما فً المثال التالً ‪:‬‬ ‫>‪template <class T, class U‬‬ ‫{ )‪T GetMin (T a, U b‬‬ ‫; ) ‪return ( a < b ? a : b‬‬ ‫}‬ ‫فً هذه الحالة التابع )(‪ٌ GetMin‬قبل نوعٌن مختلفٌن من الوسطاء وٌعٌد كابنا من نوع الوسٌط األول )‪.(T‬‬ ‫نستطٌع استدعاء هذا التابع بؤحد الشكلٌن التالٌ​ٌن ‪:‬‬ ‫; ‪int i, j‬‬ ‫;‪long l‬‬ ‫‪ -0‬الشكل العام ‪:‬‬ ‫;)‪i = GetMin<int,long> (j,l‬‬ ‫‪ -3‬الشكل المختصر ‪:‬‬ ‫;)‪i = GetMin (j,l‬‬

‫صف القوالب‬ ‫ّ‬

‫ٌمكننا أن نكتب ص ّفا لٌقبل أعضاء من أنواع عا ّمة‪ ,‬و كمثال على ذلك‪:‬‬

‫>‪template <class T‬‬ ‫{ ‪class pair‬‬ ‫;]‪T values [2‬‬ ‫‪public:‬‬ ‫)‪pair (T first, T second‬‬ ‫{‬ ‫;‪values[0]=first‬‬ ‫;‪values[1]=second‬‬ ‫}‬ ‫;}‬ ‫ّ‬ ‫ّ‬ ‫لنخزن قٌمتٌن صحٌحتٌن‬ ‫ٌخزن عنصرٌن من أي نوع مقبول‪ ,‬فلو أردنا أن ننشؤ كابنا‬ ‫هذا الصفّ ٌستطٌع أن‬ ‫مثل ‪ 115‬و ‪ 36‬فعندها سنكتب‪:‬‬ ‫;)‪pair<int> myobject (115, 36‬‬ ‫و باستخدام نفس الصفّ السابق ٌمكننا أن ّ‬ ‫نخزن عنصرٌن من أي نوع آخر كاآلتً‪:‬‬ ‫;)‪pair<float> myfloats (3.0, 2.18‬‬

‫‪268‬‬


// class templates #include <iostream> using namespace std; template <class T> class mypair { T a, b; public: mypair (T first, T second) {a=first; b=second;} T getmax (); }; template <class T> T mypair<T>::getmax () { T retval; retval = a>b? a : b; return retval; } int main () { mypair <int> myobject (100, 75); cout << myobject.getmax()<<endl; return 0; }

100

:template <class T> ‫ بالتعلٌمة‬getmax() ‫ال حظ كٌف سبقنا سطر تضمٌن )كتابة تعلٌمات( التابع‬ template <class T> T pair<T>::getmax )( {…} ‫ أمّا‬template<…> ‫ فوجب علٌنا أن نسبقه بالسابقة‬prototype ً‫وهذا أل ّننا استخدمنا التصرٌح المبدب‬ .‫ فبل داعً من ذكر هذه السابقة أمامها‬inline ّ‫األعضاء المصرّ ح عنها كلٌّا داخل الصف‬

Template specialization ‫تخصٌص القالب‬ ‫ لنفترض‬,‫تسمح لنا هذه الخاص ٌّة بعمل مجموعة من األشٌاء مع نوع مع ٌّن دون األنواع األخرى من البٌانات‬ ‫ لكن لن ٌقوم بهذه العملٌّة ّإال‬,‫عضو ٌعٌد باقً قسمة كابنٌن‬ ‫تابع‬ ٍ ٍ ‫أننا أردنا أن نكتب المثال السابق لٌحتوي على‬ ّ ‫إذا كان الكابنان من النوع الصحٌح‬ :ً‫ نستطٌع فعل ذلك كما ٌل‬.0 ‫وإال سٌعٌد‬ // Template specialization #include <iostream> using namespace std; template <class T> class mypair { T a, b; public: mypair (T first, T second) {a=first; b=second;} T module () {return 0;} }; template <> int mypair<int>::module() { return a%b; }

269

25 0


int main () { mypair <int> myints (100,75); mypair <float> myfloats (100.0,75.0); cout << myints.module() << '\n'; cout << myfloats.module() << '\n'; return 0; }

:‫كما ترى فإنّ شٌفرة التخصٌص من الشكل‬ template <> class class_name <type> ‫ وال ٌمكننا أن نضع‬template <> ‫ٌعتبر التخصٌص جزءا من القالب لذلك علٌنا أن نبدأ التصرٌح بالكلمة‬ ‫النوع العام فً أول قوسٌن من الشكل >< وٌجب أن نبقٌهما فارغٌن وبعد اسم الصفّ علٌنا أن نضع النوع الذي‬ .<> ‫نرغب بتخصٌصه بٌن قوسٌن من نفس النوع‬

: ‫بعض األشكال الممكنة للقوالب‬ template <class T> template <class T, class U> template <class T, int N> template <class T = char> template <int Tfunc (int)>

26:

// The most usual: one class parameter. // Two class parameters. // A class and an integer. // With a default value. // A function as parameter.


‫الفصل العصرون ‪:‬‬

‫تم ّكننا فضاءات األسماء من تجمٌع ع ّدة صفوف عا ّمة فً مجموعة واحدة‪ ,‬من الكابنات و)أو( التوابع تحت اسم‬ ‫واحد لك ّل هذه المجموعة حٌث تصبح كلُّها أعضاء داخل المدى الذي ٌش ّكل فضاء االسم‪ ,‬وٌكون ك ّل عضو منها‬ ‫قادرا على الوصول إلى األعضاء األخرى‪.‬‬ ‫الشكل الذي ٌمكننا من خبلله التصرٌح عن فضاء اسم جدٌد هو ‪:‬‬ ‫‪namespace identifier‬‬ ‫{‬ ‫‪namespace-body‬‬ ‫}‬ ‫حٌث أنّ ‪:‬‬ ‫‪ :identifier‬هو أي اسم تختاره أنت شرٌطة أن ٌكون صحٌحا )ٌخضع لقواعد تسمٌة المتغٌّرات(‪.‬‬ ‫‪ :namespace-body‬مجموعة من الصفوف و)أو( الكابنات و)أو( التوابع‪.‬‬ ‫مثال ‪:‬‬ ‫‪namespace general‬‬ ‫{‬ ‫;‪int a, b‬‬ ‫;‪class S‬‬ ‫;}…{()‪void B‬‬ ‫}‬ ‫و لكً نصل إلى أحد أعضاء فضاء االسم ‪ general‬من خارج الفضاء علٌنا أن نستخدم معامل المدى ‪::‬‬ ‫مثال‪:‬‬ ‫;‪general::a‬‬ ‫;)(‪general::B‬‬ ‫الوظٌفة التً ٌشغلها فضاء االسم مفٌدة خصوصا فً الحاالت التً ٌُح َتمل فٌها وجود أعضاء أو كابنات شاملة‬ ‫تمتلك نفس االسم داخل نفس البرنامج ما ٌعنً أنّ علٌنا أن نعٌد تسمٌتها لكً نستطٌع أن نتعامل معها كلّها ّإال أنّ‬ ‫فضاءات األسماء تق ّدم ّ‬ ‫حبل مناسبا لهذه المشكلة‪ .‬راقب المثال التالً ‪:‬‬ ‫‪5‬‬ ‫‪3.1416‬‬

‫‪// namespaces‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫{ ‪namespace first‬‬ ‫;‪int var = 5‬‬ ‫}‬ ‫{ ‪namespace second‬‬ ‫;‪double var = 3.1416‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪cout << first::var << endl‬‬ ‫;‪cout << second::var << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪271‬‬


‫فً هذه الحالة لدٌنا متغٌّران شامبلن لهما نفس االسم ‪ var‬لكنّ األوّ ل موجو ٌد فً الفضاء ‪ first‬أ ّما الثانً فهو‬ ‫موجو ٌد فً الفضاء ‪ second‬لذلك لن ٌكون من الخطؤ وجود متغٌّرٌن لهما نفس االسم كما كان سٌحصل لو‬ ‫أزلنا الفضابٌن السابقٌن وأبقٌنا على المتغٌّرٌن فقط‪.‬‬

‫التعلٌمة ‪using namespace‬‬ ‫تؤخذ هذه التعلٌمة الشكل التالً ‪:‬‬ ‫;‪using namespace identifier‬‬ ‫مثال ‪:‬‬ ‫‪3.1416‬‬ ‫‪6.2832‬‬

‫‪// using namespace example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫‪namespace first‬‬ ‫{‬ ‫;‪int var = 5‬‬ ‫}‬ ‫‪namespace second‬‬ ‫{‬ ‫;‪double var = 3.1416‬‬ ‫}‬ ‫{ )( ‪int main‬‬ ‫;‪using namespace second‬‬ ‫;‪cout << var << endl‬‬ ‫;‪cout << (var*2) << endl‬‬ ‫;‪return 0‬‬ ‫}‬

‫تستطٌع أن ترى كٌف أ ّننا لم نقم بكتابة اسم الفضاء الذي ٌنتمً إلٌه المتغٌّر ‪ var‬فً المرّ تٌن‪ ,‬وذلك ألنّ التعلٌمة‬ ‫‪ using‬تقوم بتوجٌه المترجم كً ٌستخدم األعضاء الموجو ِدٌن فً فضاء االسم المذكور بعدها وبالتالً فإنّ‬ ‫المترجم ٌعلم اآلن أ ّنك تقصد المتغٌّر ‪ var‬الموجود فً الفضاء ‪.second‬‬ ‫مالحظة‪ :‬إنّ التعلٌمة ‪ using namespace‬تخضع لقاعدة المدى المعروفة من قبل‪.‬‬ ‫حٌث أنّ مدى هذه التعلٌمة هو األقواس }{ التً كتبت فٌها‪ .‬أ ّما إن ُك ِت َب ْ‬ ‫ت فً مكان التصرٌح‬ ‫عن المتغٌّرات الشاملة فإ ّنها ستكون ذات مدى شامل لك ّل البرنامج‪.‬‬ ‫مثال ‪:‬‬ ‫‪5‬‬ ‫‪3.1416‬‬

‫‪// scope of‬‬ ‫‪// namespace first‬‬

‫‪// scope of‬‬ ‫‪// namespace second‬‬

‫‪// using namespace example‬‬ ‫>‪#include <iostream‬‬ ‫;‪using namespace std‬‬ ‫‪namespace first‬‬ ‫} ;‪{ int var = 5‬‬ ‫‪namespace second‬‬ ‫} ;‪{ double var = 3.1416‬‬ ‫{ )( ‪int main‬‬ ‫{‬ ‫;‪using namespace first‬‬ ‫;‪cout << var << endl‬‬ ‫}‬ ‫{‬ ‫;‪using namespace second‬‬ ‫;‪cout << var << endl‬‬ ‫}‬ ‫} ;‪return 0‬‬

‫‪272‬‬


std ‫الفضاء‬ ‫ حٌث ت ّم تضمٌن كل صفوف‬.‫ القٌاسٌة نفسها‬C++ ‫ وهو مكتبة‬,‫واح ٌد من أفضل األمثلة حول فضاءات األسماء‬ .std ‫ القٌاسٌة فً الفضاء‬C++ ‫و كابنات وتوابع مكتبة‬ : ‫ِضبي‬ // ANSI-C++ compliant hello world #include <iostream> using namespace std; int main () { std::cout << "Hello world in ANSI-C++\n"; return 0; }

Hello world in ANSI-C++

.‫ رزّىٓ ِٓ اٌزؼبًِ ِغ أػؼبء ٘زا اٌفؼبء‬ٟ‫ ٌى‬ٜ‫غت أْ رغزخذَ اعُ اٌفؼبء ص ُّ ِؼبًِ اٌّذ‬٠ :‫مالحظة‬ ُ‫ ٌٕزّىٓ ِٓ العزغٕبء ػٓ روش اع‬using namespace std ; ‫ّخ‬١ٍ‫ّىٕ​ٕب أْ ٔغزخذَ اٌزؼ‬٠ ّٗٔ‫ّئل أ‬ : ٍٟ٠ ‫ب ِغ أػؼبء ٘زا اٌفؼبء وّب‬ٙ١‫ ِٓ أعً وً ِشّح عٕزؼبًِ ف‬ٜ‫ ِؼبًِ اٌّذ‬ٚ ‫اٌفؼبء‬ // ANSI-C++ compliant hello world (II) #include <iostream> using namespace std;

Hello world in ANSI-C++

int main () { cout << "Hello world in ANSI-C++\n"; return 0; }

‫ مارا تجذ؟ ما هى انسبب؟‬.‫ ص ُّ ش ّغً اٌجشٔبِظ‬using namespace std ; ‫ّخ‬١ٍ‫ً اٌزؼ‬٠‫عشّة أْ رض‬

273


274


‫حلول التنارين غري احمللولة‬ ‫بنية الربنامج يف لغة الـ ‪C++‬‬ ‫‪.2‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫‪.3‬‬

‫)(‪main‬‬ ‫بفاصلة منقوطة ) ; (‬ ‫تعلٌق‪.‬‬ ‫التعلٌق هو قطعة من الشٌفرة مهملة من قبل المترجم‪.‬‬ ‫إنهاء البرنامج بطرٌقة سلٌمة‪.‬‬ ‫القوسٌن }{‬ ‫تضمٌن الملف المصدري >‪ <iostream‬الستخدام التعلٌمات الموجودة فٌه‪.‬‬ ‫;"!‪cout<<"In the name of Allah. The peace upon you, Hello world‬‬

‫‪275‬‬


‫املتغيّرات‬ ‫‪ .2‬أجب عن األسبلة التالٌة ‪:‬‬ ‫‪ ‬ال ‪ ,‬ألنّ ‪ C++‬حسّاسة لحالة األحرف‪.‬‬ ‫‪ ‬نعم‪ .‬ألن التصرٌح ٌوجب ذكر نوع المتغٌّر‪.‬‬ ‫‪ ‬ال‪.‬‬ ‫‪ ‬نعم‪.‬‬ ‫‪ٌ signed ‬عنً أنّ المتغٌّر ذو إشارة سالبة أو موجبة ‪ ,‬بٌنما ‪ unsigned‬فالمتغٌّر ال ٌمكن أن ٌكون‬ ‫سالبا‪.‬‬ ‫‪ .3‬امؤل الفراغات التالٌة ‪:‬‬ ‫‪ ‬أماكن ‪ ,‬المإقتة ‪ ,‬اسم ‪ٌ ,‬مٌزه ‪ ,‬الذاكرة‪.‬‬ ‫‪.4‬‬ ‫‪ (a‬خاطبة ألن المتغٌّر ‪ f‬ال ٌقبل إشارة سالبة‪.‬‬ ‫‪ (b‬خاطبة ألن اسم المتغٌّر ٌجب أال ٌبدأ برقم‪.‬‬ ‫‪ (c‬خاطبة المتغٌّر ‪ d‬من النوع العشري ولٌس محرفا‪.‬‬ ‫‪ (d‬صحٌحة‪.‬‬ ‫‪ (e‬خاطبة اسم المتغٌّر ٌجب أال ٌحوي نقطة أو رموز خاصة‪.‬‬ ‫‪ (f‬صحٌحة‪.‬‬ ‫‪ .5‬معظم هذه األخطاء منطقٌّة لذلك قد ٌعمل البرنامج مع وجود بعضها‪:‬‬ ‫ نوع المتغٌّرٌن ‪ a, b‬عشري وتم اسنادهما لمتغٌّر من لنوع الصحٌح لذلك ٌجب تحوٌل نوع المتغٌّر ‪result‬‬‫إلى عشري ) سٌتجاهل األرقام العشرٌة بعد الفاصلة وٌخزن القسم الصحٌح فقط (‪.‬‬ ‫ المتغٌّر ‪ result‬ال ٌقبل أرقاما سالبة فً حٌن أن القٌمة المسندة إلٌه سالبة فٌجب تعدٌله لٌكون ‪.signed‬‬‫ التعلٌمة ;‪ result = A + b‬غٌر صحٌحة ألنه ال ٌوجد متغ ٌّر اسمه ‪A‬‬‫فٌجب أن نعدلها لتصبح ; ‪.result = a + b‬‬ ‫ التابع )(‪ main‬من النوع ‪ int‬لذلك ٌجب أن ٌعٌد قٌمة من النوع الصحٌح إال أنه ال ٌمتك التعلٌمة‬‫;‪ return 0‬فٌجب أن نضٌفها إلٌه ) ال ٌسبب خطؤ إال أنه ٌعطً تحذٌرا فقط (‪.‬‬

‫‪276‬‬


‫اإلدخال و اإلخراج‬ .2 * ** *** **** ***** .3 #include <iostream> using namespace std; int main () { float f = 0.0 , c = 0.0 ; cout<<"Enter celecius degree: "; cin>>c; f = (9/5)*c + 32 ; cout<<'\n'<<f<<"\n"; return 0; } .4 #include <iostream> using namespace std; int main () { float f = 0.0; cout<<"Enter fehrnhite degree: "; cin>>f; float c = 5*(f - 32)/9 ; cout<<'\n'<< c <<"\n"; return 0; } .5 #include <iostream> using namespace std; int main () { float a = 0.0 , d = 0.0,v =0.0 ; int t = 0; cout<<"Enter accelration of body by m.s^-2: "; cin>>a; cout<<"Enter time of movement by seconds: "; cin>> t; d = 0.5*a*t*t; 277


v = a*t; cout<<"distance = "<<d<<" meters\n"; cout<<"velocity = "<<v<<" m.s^-1\n"; return 0; } .6 #include <iostream> using namespace std; int main () { float f = 0.0 , x =0.0; cout<<"Enter x: "; cin>>x; f = 5 - x*x; cout<<"\nf("<<x<<") = "<<f<<endl; return 0; } .7 #include <iostream> using namespace std; int main () { int n = 0; cout<<"Enter n: "; cin>>n; cout<<"\nsum of numbers from (1 to "<<n<<") = "<<n*(n+1)/2<<endl; cout<<"\navg = "<<(float)(n*(n+1)/2)/n<<endl;//avg = sum / n return 0; } .8 #include <iostream> using namespace std; int main () { cout<<"Just remember \"Allah created You\'.\n"; return 0; }

278


.9 #include <iostream> using namespace std; int main () { int x1,x2,x3; cout<<"Enter three numbers plz: "; cin>>x1>>x2>>x3; cout<<"\nAverage of ["<<x1<<','<<x2<<','<<x3<<"] = " << float(x1+x2+x3)/3<<endl; return 0; }

279


‫املعامالت‬ .2 int x = 0, a = 0, b = 1, d = 3, c = 2; bool e = true , r = true, t = false; ‫العبارة‬ a += (b = c = d - 5) ; d %= 2 * c / ++b ; a = d - (b += (c * (1-a))); e = !e r = e || t t = e && r e = !( (e && r ) || (e && t ) ) ;

‫الجواب‬ -2 3 0 0 0 0 1 .3

‫العبارة‬ x=7+3*6/2-1; x = 2 % 2 + 2 * 2 -2 / 2 ; x=(3*9*(3+(9*3/(3)))); c = 2*b - 3/d + a++;

‫الجواب‬ 15 3 324 1 .4

cout<< cout<< cout<< cout<<

27:

++a ; a++ ; a++ / 2 ; ++a / 2 ;

1 0 0 0


‫بنى التخكه‬ .2 #include<iostream > using namespace std; float avg =0; int main() { cout<<"Enter Average: "; cin>>avg; if(avg > 89 && avg <= 100 ) cout<<"Excellent!\n"; else if(avg > 79 && avg <= 89) cout<<"Very Good\n"; else if(avg > 69 && avg <= 79) cout<<"Good\n"; else if(avg > 59 && avg <= 69) cout<<"Passed\n"; else cout<<"Not passed\n"; return 0; } .3 ‫البرنامج‬ while ( c <= 5 { product *= c; ++c; if ( gender == cout<< "Woman" else; cout<<"man"; while ( z >= 0 sum += z;

)

‫التصحٌح‬ while ( c <= 5 ) { product *= c; ++c;

} 1 ) ;

)

if ( gender == 1 ) cout<< "Woman" ; else // ‫ال ٌوجد فاصلة منقوطة هنا‬ cout<<"man"; while ( z >= 0 ) { sum += z;

z--; } // nested loop #include <iostream> using namespace std; int main () { int j = 1; for( int i = 1 ; i<=3 ; i++) while( j<i ) { cout <<"* " ; j++; } return 0; }

281

// nested loop #include <iostream> using namespace std; int main () { int j = 1; for( int i = 1 ; i<=5 ; i++) {while( j<=i ) {cout <<"* " ; j++; } cout<<endl; j = 1;} return 0; }


.4 #include <iostream> using namespace std; int main () { int x,y,z,max,med,min; cout<<"Enter three numbers: "; cin>>x>>y>>z; if (x > y && x > z && y > z) cout<<z<<"\t"<<y<<"\t"<<x<<endl; else if (x > y && x > z && z>y ) cout<<y<<"\t"<<z<<"\t"<<x<<endl; if (y > x && y > z && x > z) cout<<z<<"\t"<<x<<"\t"<<y<<endl; else if (y > x && y > z && z>x ) cout<<x<<"\t"<<z<<"\t"<<y<<endl; if (z > y && z > x && y > x) cout<<x<<"\t"<<y<<"\t"<<z<<endl; else if (z > y && z > x && x>y ) cout<<y<<"\t"<<x<<"\t"<<z<<endl; return 0; } .5 ‫البرنامج‬ #include <iostream> using namespace std; int main () { for(int i = 3;i<=6;i++) { for(int j = i;j<i+4;j++) cout<<j<<" "; cout<<"\n"; } return 0; } #include <iostream> using namespace std; int main () { for(int i = 0;i<=3;i++) { for(int j = 0;j<=3;j++) if(i>=j) cout<<j+3+i<<" "; cout<<"\n"; } return 0; }

282

‫الشكل‬ 3 4 5 6

4 5 6 7

5 6 7 8

6 7 8 9

3 4 5 5 6 7 6 7 8 9


#include <iostream> using namespace std; int main () { for(int i = 0;i<=3;i++) { for(int j = 0;j<=3;j++) if(i<=j) cout<<j+3+i<<" "; else cout<<" "; // 2 spaces cout<<"\n"; } return 0; } #include <iostream> using namespace std; int main () { for(int i = 0;i<=3;i++) { for(int j = 0;j<=3;j++) if(i+j>=4-1) cout<<j+3+i<<" "; else cout<<" ";//2 spaces cout<<"\n"; } return 0; } #include <iostream> using namespace std; int main () { for(int i = 0;i<=3;i++) { for(int j = 0;j<=3;j++) if(i<=j) cout<<j+3<<" "; cout<<"\n"; } return 0; } #include <iostream> using namespace std; int main () { for(int i = 0;i<=3;i++) { for(int j = 0;j<=3;j++) if(i == 0 || i == 3) cout<<j+3+i<<" ";//2 spaces else { 283

3 4 5 6 5 6 7 7 8 9

6 6 7 6 7 8 6 7 8 9

3 4 5 6 4 5 6 5 6 6

3 4 5 4 5 6 7 8

6 7 8 9


if(j == 0 || j == 3) cout<<j+3+i<<" "; else cout<<" ";// 2 spaces } cout<<"\n"; } return 0; } .6 #include <iostream> using namespace std; int main () { cout<<"Enter n: "; int n; cin>>n; if(n%10 == 0) cout << "yes\n"; else cout<<"no\n"; return 0; } .7 #include <iostream> #include<cmath > using namespace std; int main () { double x, fx =0.0 ; err: cout<<"Enter x ecept (1 or 3): "; cin>>x; if(x == 1 || x == 3) {cout << "Infinite Error You can't Enter 1 or 3\n"; goto err;} else{ fx = (pow(x,3) - 7)/(pow(x,2)-4*x+3); cout<<"f("<<x<<") = "<<fx<<endl; } return 0; }

284


.8 #include <iostream> using namespace std; int main() { int i,sum=0; for(i=1;i<=99;i++) if(i%2==0 && i%3==0) sum+=i; cout<<"sum="<<sum<<endl; return 0; }

.9 #include<iostream> using namespace std; void main() { int a,b,lcm ; cout << "enter a and b" << endl; cin>>a>>b; if (a == 0 || b == 0) lcm = 0; else if ( a>b && a%b==0 ) cout <<"lcm="<<a<<endl ; else if(b>a && b%a==0) cout <<"lcm="<<b<<endl; else lcm=a*b; cout <<"lcm="<<lcm<<endl; } .: #include<iostream > using namespace std; void main() { double x,p=1.0,y; cout <<"Enter x, y: "; cin >> x >> y; if(y>=0){ for(int i = 1; i<=y;i++) p *=x; cout<< p << endl; } }

285

#include<iostream > using namespace std; void main() { double x,p=1.0,y; cout<<"Enter x, y: "; cin>>x>>y; if(y>=0){ int i = 1; while( i<=y ) { p *=x; i++; } cout<< p << endl; } }


.21 #include<iostream > using namespace std; void main() { int n; char c; cout<<"Enter charactor then number: "; cin >> c >> n; for(int i = 0; i<n;i++){ for(int j = 0; j<n;j++) if(i>=j) cout<<c<<" "; cout<<endl;} } .22 #include<iostream.h> void main() { float x,y; char c = 'n'; while(c == 'n' ) { cout<<"Enter two numbers: "; cin>> x >> y; ZeroErr: if(y != 0) { cout<< x/y << endl; } else { cout<<"Error You can't enter 0"; cout<<"ReEnter second number without 0 plz: "; cin>> y; goto ZeroErr; } inputErr: cout<<"press n for new operation,(e to exit): "; cin>> c; if(c == 'n' || c == 'N') continue; else if(c == 'e' || c == 'E') break; else goto inputErr; } } .23 #include<iostream > using namespace std; void main() 286


{ int x; cout<<"Enter x: "; cin>>x; int i = 1; while(i<=x) { if(x%i == 0)cout<<i<<endl; i++; } }

‫التوابع‬ .0 ‫التابع‬ int Sum(int a , int b) { int sum = a + b; } int divide(int a , int b) { return (float)a/b; } void subtract(int a , int b) { return a-b; }

‫األخطاء‬ ‫ وٌجب أن ٌعٌد قٌمة إال أنه ال‬int ‫هذ التابع من النوع‬ return statement; ‫ٌحتوي على التعلٌمة‬ return sum; // return a+b; ‫ و هو ٌعٌد قٌمة من النوع‬int ‫هذا التابع من النوع‬ .float ‫ فعلٌنا أن نغٌر نوع التابع إلى‬float float divide(int a, int b({…} ‫ وٌجب ّأال ٌعٌد قٌمة لكنه‬void ‫هذ التابع من النوع‬ ‫ لذلك سنغٌر‬return a-b; ‫ٌحتوي على التعلٌمة‬ int ‫نوعه إلى‬ int subtract)int a, int b({…} .3

‫البرنامج‬ #include<iostream>

using namespace std; int x = 0; float b; float d(float a , float& b) { a--; b++; x = a/b; return (x+1)/2.0; } int main() { float a; cout<<"x\tb\ta\n"; cout<<x<<"\t"<<b<<"\t"<<a<<endl; a = b = ++x; cout<<d(a , b)<<endl; cout<<x<<"\t"<<b<<"\t"<<a<<endl; return 0; }

‫الناتج‬ x b 0 0 0.5 0 2 x b 0 0 0.5 1 2

a -1.07374e+008 1 : ‫أ ّما بعد التعدٌل‬ a -1.07374e+008 1

‫ هً قٌمة‬-1.07374e+008 ‫ القٌمة‬:‫مالحظة‬ ‫عشوابٌة تختلف دوما وهً عشوابٌة ألن المتغٌّر‬ ‫ متغٌّر موضعً ولقد قلنا إنّ المتغٌّرات‬a ‫الموضعٌة تؤخذ قٌما عشوابٌة إذا لم تت ّم تبدبتها أ ّما‬ ‫المتغٌّرات الشاملة فهً تؤخذ القٌم الصفرٌة للنوع‬

.2 287


#include<iostream> using namespace std; float sum(float a,float b); float sub(float a,float b); float mult(float a,float b); float divide(float a,float b); void main() { float x,y; char op ; cout<<"Enter x: "; cin>>x; cout<<"Enter operator from{+,-,*,/}: "; cin>>op; cout<<"Enter y: "; cin>>y; switch(op) { case '+': cout<<sum(x,y)<<endl; break; case '-': cout<<sub(x,y)<<endl; break; case '*': cout<<mult(x,y)<<endl; break; case '/': if(y!=0) cout<<divide(x,y); else cout<<"Error divide by 0\n"; break; } } float sum(float a,float b) { return a+b; } float sub(float a,float b) { return a-b; } float mult(float a,float b) { return a*b; } float divide(float a,float b) { return a/b; }

.1 #include<iostream > using namespace std; float rec_power(float a,int b); float frec_power(float a,int b); 288


void main() { float x; int y; cout<<"Enter x, y: "; cin>>x>>y; cout<<"Recutrivity power = "<<rec_power(x,y)<<endl; cout<<"Frecuently power = "<<frec_power(x,y)<<endl; } float rec_power(float a,int b) { if(b == 0) return 1; else if(b>0) return a*rec_power(a,b-1); else return 1/(a*rec_power(a,-b-1)); } float frec_power(float a,int b) { float res = 1; if(b==0) res = 1; else if(b>0) for(int i=1;i<=b;i++) res*=a; else{ for(int i=1;i<=-b;i++) res*=a; res = 1/res; } return res; } .5 #include<iostream > using namespace std; float frec_power(float a,int b); float pi(long n); void main() { long n ; cout<< "enter n: "; cin>>n; cout<<"\n"<<pi(n)<<endl; } float pi(long n) { float p = 0; for(long i = 0;i<n;i++) 289


p += 4*frec_power(-1,i)/(2*i+1); return p; } float frec_power(float a,int b) { float res = 1; if(b==0) res = 1; else if(b>0) for(int i=1;i<=b;i++) res*=a; else { for(int i=1;i<=-b;i++) res*=a; res = 1/res; } return res; } .6 #include<iostream > using namespace std; int frec_gcd(int a, int b); // frecuently int rec_gcd(int x, int y); // recursivity void main() { int a , b; cout<<"Enter a , b: "; cin>>a>>b; cout<<"\nfrequently result: "<< frec_gcd(a,b); cout<<"\nrecursivity result: "<< rec_gcd(a,b)<< endl; } int frec_gcd(int a, int b) { while(a != b) { if(a>b) a-=b; else b-=a; } return a; // or return b : a = b } int rec_gcd(int x, int y) { if(x == y) return x; else if (x>y) return rec_gcd(y,x-y); 28:


else return rec_gcd(x,y-x); //second way to finding gcd /*if(y == 0) return x; else return rec_gcd(y,x%y); */ }

.7 #include<iostream > #include<math.h> using namespace std; long fact(int a); double Compination(int n, int k); double Permitation(int n, int r); void main() { int n , k , r ; cout<<"Enter n: "; cin>>n; cout<<"\n"<<n<<"! = "<<fact(n); cout<<"\nEnter k < " << n << " : "; cin>>k; cout<<"\nc("<<n<<","<<k<<") = "<<Compination(n,k); cout<<"\nEnter r < " << n << " : "; cin>>r; cout<<"\np("<<n<<","<<r<<") = "<<Permitation(n,r)<<endl; } long fact(int a) { long f = 1; for(int i =1; i<=a ; i++) f*= i; return f; } double Compination(int n, int k) { double c = fact(n)/(fact(n-k)*fact(k)); return c; } double Permitation(int n, int r) { double p =Compination(n,r)*fact(r); return p; 291


} .8 #include<iostream > using namespace std; void multiple(int a, int b); bool multiple1(int a, int b); void main() { int n , k ; cout<<"Enter n, k: "; cin>>n>>k; if(multiple1(n,k)) cout<<"true\n"; else cout<<"false\n"; multiple(n,k); } void multiple(int a, int b) { if(b>a && b%a ==0) cout<<"true\n"; else cout<<"false\n"; } bool multiple1(int a, int b) { if(b>a && b%a ==0) return true; return false; // no need to else statement. why? } .9 #include<iostream > using namespace std; void print_primes(int a); bool is_prime(int a); void main() { int n; cout<<"Enter n: "; cin>>n; if(is_prime(n)) cout<<"true\n"; else cout<<"false\n"; print_primes(n); } bool is_prime(int a) { 292


if(a>0 && a != 1)//positive and not 1 (1 isn't prime) { int sum = 0; for(int i = 1; i <= a ; i++) { if(a%i == 0) sum++; } if(sum == 2) return true; } return false; } void print_primes(int a) { for(int i = 1; i <= a ; i++) if(is_prime(i)) cout<<i<<"\n"; } .01 #include<iostream> using namespace std; double abs_val(double x) { if(x>0) return x; else return -x; } void main() { double n; cout<<"Enter n: "; cin>>n; cout<<"| "<<n<<" | = "<<abs_val(n)<<endl; } .00 #include<iostream> using namespace std; const double pi = 3.141592; double Circl_space(double r) { return (pi*r*r); } double Rect_space(double a , double b) { return (a*b); } double Trgl_space(double b , double h) { return (0.5*b*h); } void main() { cout<<"1- Calculate circle spsace\n"; 293


cout<<"2- Calculate rectangle spsace\n"; cout<<"3- Calculate triangle spsace"; cout<<"\nEnter number from list above to select: "; int ch ; cin>>ch; cout<<"\n"; switch(ch) { case 1 : cout<<"Calculating circle space.. .\n"; double r ; cout<<"Enter r: "; cin>>r; cout<<"S ="<<Circl_space(r)<<endl; break; case 2 : cout<<"Calculating rectangle space.. .\n"; double a, b ; cout<<"Enter width: "; cin>>a; cout<<"Enter height: "; cin>>b; cout<<"S ="<<Rect_space(a,b)<<endl; break; case 3 : cout<<"Calculating triangle space.. .\n"; double h; cout<<"Enter base: "; cin>>b; cout<<"Enter height: "; cin>>h; cout<<"S ="<< Trgl_space(b,h)<<endl; break; default: cout<<"program will terminate now!."; break; } } .12

#include<iostream> using namespace std; int print(int h); int main() { int h;//h is hieght cin>>h; print(h); return 0; } int print(int h) { int i,j,k; 294


for(i=1;i<=h;i++)//number of rows { for(j=1;j<=h-i;j++)//from line beginning to the first star pos print space cout<<" ";// 2 spaces for(k=1;k<=2*i-1 ;k++)// from last space in line to (2*line number -1) cout<<"* "; // print * where (2*line number -1) is number of // * in each line (i) cout<<"\n"; // print new line } return 0; }

295


‫املصفوفات‬ -2 for ( int i = 0; i<= 10; i++ ) (a i<10 ‫ غٌر موجود إذا ٌجب أن ٌكون شرط التوقف‬b[10]‫ والعنصر‬21 ‫سٌؤخذ العداد القٌمة‬ int i = 1 ‫ أي‬2 ‫ القٌمة‬i ً‫أو ٌمكن أن نعط‬ cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl; (b .a[2] ‫ و‬a[1] ‫ و‬a[0] ً‫ ألن عناصرها ه‬a ‫غٌر موجود فً المصفوفة‬a[3] ‫العنصر‬ double f[ 3 ] = { 1.1, 10.01, 100.001, 1000.0001 }; )c ‫ عناصر فقط لذلك ٌجب حذف أحد العناصر على األقل‬4 ‫ تتسع لـ‬f ‫المصفوفة‬ d[ 1, 9 ] = 2.345; )d d[ 1][9] = 2.345; ‫ٌجب أن ٌكون كل دلٌل ضمن قوسٌن أي‬ -3 .p[3] ‫ و‬p[2] ‫ و‬p[1] ‫ و‬p[0] .‫تعرٌف‬ .d[2][4] .20

(a (b (c (d -4

const int arraySize = 10; (a double fractions[ arraySize ] = { 0.0 }; )b fractions[ 8 ] = 1.667; fractions[ 6 ] = 3.333; (c (d for(int i=0; i<arraySize;i++) cout<<"fractions["<<i<<"]="<<fractions[i]<<endl; -5 #include<iostream> using namespace std; const int n=8; void print(int a[]) { for(int i=0;i<n;i++) cout<<a[i]<<" "; } int main() { int A[n]={1,5,4,3,7,2,9,0},i,j,temp; for(i=0;i<n;i++)//ascending for(j=0;j<n-1;j++) if(A[j]>A[j+1]) {temp=A[j];A[j]=A[j+1];A[j+1]=temp;} cout<<"ascending: "; print(A);

296


for(i=0;i<n;i++)//descending for(j=0;j<n-1;j++) if(A[j]<A[j+1]) {temp=A[j];A[j]=A[j+1];A[j+1]=temp;} cout<<"\ndescending: "; print(A); cout<<endl; return 0; }

-6 #include<iostream> using namespace std; const int n=10; int a[n],b[n],c[2*n],i,j; void read(int arr[]) { for(i=0;i<n;i++) cin>>arr[i]; } void merge(int a[],int b[]) { for(i=0;i<n;i++) { c[i]=a[i]; c[i+n]=b[i]; } } void print(int arr[]) { for(int i=0;i<2*n;i++) cout<<a[i]<<" "; } int main() { cout<<"enter A members:\n"; read(a); cout<<"enter B members:\n"; read(b); merge(a,b); cout<<"C=[ "; print(c); cout<<"]\n"; return 0; }

-7 #include<iostream> using namespace std; const int n=10; int main() { int a[n],frq[4]={0},i; cout<<"enter array of 10 integers:\n"; for(i=0;i<n;i++)

297


cin>>a[i]; for(i=0;i<n-1;i++) { if(a[i]<a[i+1]) frq[0]++; else if(a[i]>a[i+1]) frq[1]++; else if(a[i]==a[i+1]) frq[2]++; else frq[3]++; } if(frq[0]==9) cout<<"the array else if(frq[1]==9) cout<<"the array else if(frq[2]==9) cout<<"the array else cout<<"the array return 0;

is growing.\n"; is decreasing.\n"; is constant.\n"; is growing and decreasing.\n";

}

-8 #include<iostream> #include<string> using namespace std; int main() { int n,mark[100],i,j,temp; string name[100],strTemp; cout<<"enter students number "; cin>>n; for(i=0;i<n;i++) { cout<<"student "<<i+1<<" name:"; cin>>name[i]; cout<<"student "<<i+1<<" mark:"; cin>>mark[i]; } for(i=0;i<n;i++) for(j=0;j<n-1;j++) if(mark[j]<mark[j+1]) { temp=mark[j];mark[j]=mark[j+1];mark[j+1]=temp; strTemp=name[j];name[j]=name[j+1];name[j+1]=strTemp; } cout<<"students ranks by marks:\n"; for(i=0;i<n;i++) cout<<name[i]<<endl; return 0; }

298


-9 // program to add matrix to another one //using functions #include <iostream> using namespace std; #define MAX 10 int a[MAX][MAX],b[MAX][MAX],c[MAX][MAX]; void add(int [][MAX],int [][MAX],int [][MAX],int ,int ); void print(int [][MAX],int,int); int main() { int m,n; cout<<"number of rows=";cin>>m; cout<<"number of columns=";cin>>n; add(a,b,c,m,n); print(a,m,n); cout<<"\n +\n\n"; print(b,m,n); cout<<"\n =\n\n"; print(c,m,n); return 0; } void print(int arr[][MAX],int m,int n) { int i,j; for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<arr[i][j]<<" "; cout<<"\n"; } } void add(int a[][MAX],int b[][MAX],int c[][MAX],int m,int n) { int i,j; for(i=0;i<m;i++) for(j=0;j<n;j++) { cout<<"a["<<i+1<<"]["<<j+1<<"]=";cin>>a[i][j]; cout<<"b["<<i+1<<"]["<<j+1<<"]=";cin>>b[i][j]; c[i][j]=a[i][j]+b[i][j]; } }

-: #include<iostream> #include<string> #include<cstdlib> #include<ctime> using namespace std;

299


int main() { cout<<"enter your Choice :\n"; cout<<"R\tfor Rock\n"; cout<<"P\tfor Paper\n"; cout<<"S\tfor Scissors\n"; cout<<"The computer chose\n"; int cmpCounter = 0; int YourCounter = 0; lbb: cout<<"\nYour points:\t\t" << YourCounter; cout<<"\nComputer points:\t" << cmpCounter; string mesg ; srand(time(0));//seed rand int r = rand() % 3 ; switch (r) { case 0: mesg = "Computer choice's Rock"; break; case 1: mesg = "Computer choice's Paper"; break; case 2: mesg = "Computer choice's Scissors"; break; } cout<<"\nChose please:"; string PlayerChosen ; cin>>PlayerChosen ; if (PlayerChosen == "R" || PlayerChosen == "r") { cout<<mesg; switch (r) { case 0: cout<<"\nNo Winner"; cmpCounter = cmpCounter; YourCounter = YourCounter; goto lbb; break; case 1: cout<<"\nComputer Won..."; cmpCounter+=1; goto lbb; break; case 2: cout<<"\nYou Won..."; YourCounter+=1; goto lbb; 29:


break; } } else if (PlayerChosen == "P" || PlayerChosen == "p") { cout<<mesg; switch (r) { case 0: cout<<"\nYou Won..."; YourCounter+=1; goto lbb; break; case 1: cout<<"\nNo Winner"; cmpCounter = cmpCounter; YourCounter = YourCounter; goto lbb; break; case 2: cout<<"\nComputer Won..."; cmpCounter+=1; goto lbb; break; } } else if (PlayerChosen == "S" || PlayerChosen == "s") { cout<<mesg; switch (r) { case 0: cout<<"\nComputer Won..."; cmpCounter+=1; goto lbb; break; case 1: cout<<"\nYou Winner"; YourCounter+=1; goto lbb; break; case 2: cout<<"\nNo Winner..."; cmpCounter = cmpCounter; YourCounter = YourCounter; goto lbb; break; } } else if (PlayerChosen == "E" || PlayerChosen == "e") { 2:1


cout<<"Do you want to exit the game? (y/n)"; string anser; cin>>anser; if (anser == "Y" || anser == "y") return 0;//exit main func else goto lbb; } else { cout<<"\nBe sure from your inserting..."; goto lbb; } return 0; }

2:2


‫الربدلة كائنية التوجه‬ .2 #include<iostream> using namespace std; const double pi = 3.141592; class Circle { private : double radius; public: void set_radius(double r); double calc_space(); double calc_perimeter(); }; void Circle::set_radius(double r) { radius = r; } double Circle::calc_space() { return pi*radius*radius; } double Circle::calc_perimeter() { return 2*pi*radius; } void main() { Circle c1; double r; cout<<"Enter radius: "; cin>>r; c1.set_radius(r); cout<<"c1 Space = "<<c1.calc_space()<<endl; cout<<"c1 perimeter = "<<c1.calc_perimeter()<<endl; } .3 #include<iostream> #include<math.h> using namespace std; class Point { public: double x, y; void set_point(double p_x, double p_y); double distance(Point p1, Point p2); }; 2:3


void Point::set_point(double p_x, double p_y) { x = p_x; y = p_y; } double Point::distance(Point p1, Point p2) { return( sqrt( pow( (p2.x-p1.x),2) + (pow((p2.y-p1.y),2) ) ) ); } void main() { Point p1,p2; double x1,y1,x2,y2; cout<<"Enter x1, y1: "; cin>>x1>>y1; cout<<"Enter x2, y2: "; cin>>x2>>y2; p1.set_point(x1,y1); p2.set_point(x2,y2); cout<<"Distance between p1 and p2 is :" <<p1.distance(p1,p2)<<endl; } .4 #include<iostream> using namespace std; const double pi = 3.141592; class Circle { private : double radius; public: Circle(){} Circle(double r){radius =r;} void set_radius(double r); double calc_space(); double calc_perimeter(); }; void Circle::set_radius(double r) { radius = r; } double Circle::calc_space() { return pi*radius*radius; } double Circle::calc_perimeter() { return 2*pi*radius; } void main() 2:4


{ Circle c1; double r; cout<<"Enter radius: "; cin>>r; Circle c2(r); c1.set_radius(r); cout<<"c1 Space\t"<<"c2 Space\t"<<"c1 perimeter\t"<<"c2 perimeter\n"; cout<<c1.calc_space()<<"\t\t"<<c2.calc_space() <<"\t\t"<<c1.calc_perimeter()<<"\t\t"<<c2.calc_perimeter()<<endl; } .‫ لٌست صحٌحة أل ّننا لم نضف المشٌد العادي‬Circle circle; ‫العبارة‬

#include<iostream> #include<math.h> using namespace std; class Point { public: double x, y; Point(){} Point(double p_x, double p_y) { x = p_x ; y = p_y ; } void set_point(double p_x, double p_y); double distance(Point p); }; void Point::set_point(double p_x, double p_y) { x = p_x; y = p_y; } double Point::distance(Point p) { return sqrt( pow( (p.x-this->x),2) + (pow((p.y-this->y),2) ) ); } int main() { Point p1,p2; p1.set_point(1,2); p2.set_point(2,1); cout<<p1.distance(p2)<<endl; return 0; }

2:5

.5 .6


.7 #include<iostream.h> class Printing {public: Printing(){ cout<< "Give the world the best you have, and the best will come to you.\n"; } ~Printing(){ cout<< "\nIf man hasn't discovered that he will die for, he isn't fit to live.\n"; } }print_that; int main() { cout<<"Sweat plus sacrifice equals success."; return 0; } ‫( قد ال ٌعمل البرنامج‬using namespace std; ‫ )ال تستخدم‬#include<iostream.h> ‫ ال تغ ٌّر التعلٌمة‬:‫مالحظة‬ ( ‫بشكل كامل ) قد ال ٌطبع العبارة الثالثة الموجودة فً الهادم‬ .8 #include<iostream> #include<math.h> using namespace std; class Point { public: double x, y; void set_point(double p_x, double p_y); double distance(Point p1, Point p2); Point operator+ (Point p); }; void Point::set_point(double p_x, double p_y) { x = p_x; y = p_y; } double Point::distance(Point p1, Point p2) { return sqrt( pow( (p2.x-p1.x),2) + (pow((p2.y-p1.y),2) ) ); } Point Point::operator+(Point p) { Point temp; temp.x = this->x + p.x; temp.y = this->y + p.y; return temp; } void main() { Point p1,p2; 2:6


double x1,y1,x2,y2; cout<<"Enter x1, y1: "; cin>>x1>>y1; cout<<"Enter x2, y2: "; cin>>x2>>y2; p1.set_point(x1,y1); p2.set_point(x2,y2); cout<<"Distance between p1 and p2 is : "<<p1.distance(p1,p2)<<endl; cout<<"c(x,y) = ("<<(p1+p2).x<<", "<<(p1+p2).y<<")\n"; } .9 .getIncrementedData ‫ من أمام التصرٌح عن التابع‬const ‫أزل الكلمة‬ .‫ لذلك علٌك أن تزٌل التعلٌمة الخاصة بالطباعة منه‬static ‫ من النوع‬getcount ‫التابع‬

2:7

 


‫اخلامتة‬ ‫كل ما عليك أن تتعلّمو في البرمجة‪ ,‬وليس ىذا ىو آخر الكتب التي ألفت‬ ‫أخيراً ال يحوي ىذا الكتاب على ّ‬

‫في ىذا المجال؛ لذلك إن كنت ترى أ ّن البرمجة ىي الشي الذي كنت تبحث عنو فعليك أن تبحث عن كتاب‬ ‫آخر لتكمل معو رحلتك‪.‬‬

‫هم اجعلو في ميّان حسناتنا وال تحرمنا أجره‪.‬‬ ‫اللّ ّ‬ ‫هم من كان سبباً في إنجاز ىذا الكتاب فحرمو على النار وارزقو الجنّة برحمتك يا أرحم الراحمين‪.‬‬ ‫اللّ ّ‬ ‫هم ما كان من صواب فمنك وحدك ال شريك لك‪ ,‬وما كان من زلل أو نسيان فمن أنفسنا والشيطان‪.‬‬ ‫اللّ ّ‬ ‫محمد وعلى آلو وصحبو أجمعين‪.‬‬ ‫وصلّى اهلل على سي ّدنا ّ‬ ‫رب العالمين‪.‬‬ ‫وآخر دعوانا أن الحمد هلل ّ‬ ‫***‬

‫ٌرجى زٌارة الرابط التالً إلبداء رأٌكم بالكتاب‬ ‫‪https://docs.google.com/spreadsheet/viewform?formkey=dDVxYmV5UFgwaHBFZkQ0U3RiO‬‬ ‫‪TNNSUE6MQ&ifq‬‬

‫‪2:8‬‬


‫املراجع‬ 1- The cplusplus.com tutorial ) http://www.cplusplus.com/doc/ ( Author: Juan Soulie 2- C++ How to Program Fifth Edition 3- The C+ + Programming Language Third Edition, Author: Bjarne Stroustrup(the creator of c++) 4- Java How to Program C# And VB.net 8002 ٛ٠‫د‬ٛ‫اي عز‬ٛ‫غ‬١‫ح ِغ ف‬ٛ‫ح ثخط‬ٛ‫ خط‬-5 ‫فخ‬١ٍ‫أؽّذ عّبي خ‬

2:9


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.