Download as pdf or txt
Download as pdf or txt
You are on page 1of 198

C++

3
‫فهرس انمحتىٌاث‬
‫‪9‬‬ ‫مقدمة إلى البرمجة‬
‫‪10‬‬ ‫البداٌة مع البرمجة‬
‫‪10‬‬ ‫لغة البرمجة‬
‫‪11‬‬ ‫لمحة تارٌخٌّة عن ‪C++‬‬
‫‪11‬‬ ‫لمن هذا الكتاب ؟‬
‫‪11‬‬ ‫كٌف أقرأ هذا الكتاب ؟‬
‫‪23‬‬ ‫فصول الكتاب‬
‫‪14‬‬ ‫التعامل مع المترجم ‪visual c++ 6.0‬‬
‫‪17‬‬ ‫الفصل األول‪ :‬بنٌة البرنامج فً لغة الـ ‪C++‬‬ ‫القسم األول‬
‫‪18‬‬ ‫تنسٌق الكتابة‬
‫‪19‬‬ ‫التعلٌقات‬
‫‪19‬‬ ‫تمارٌن‬
‫‪20‬‬ ‫الفصل الثانً‪ :‬المتغ ٌّرات ( ‪( Variables‬‬
‫‪21‬‬ ‫حساسٌة اللغة لحالة األحرف‬
‫‪21‬‬ ‫أنواع البٌانات )‪(Data types‬‬
‫‪24‬‬ ‫مقدّمة إلى السبلسل ) ‪( strings‬‬
‫‪25‬‬ ‫تمارٌن‬
‫‪26‬‬ ‫الفصل الثالث‪ :‬اإلدخال و اإلخراج ) ‪( Input and Output‬‬
‫‪26‬‬ ‫تعلٌمة اإلخراج )‪(cout‬‬
‫‪28‬‬ ‫تعلٌمة اإلدخال )‪(input cin‬‬
‫‪28‬‬ ‫بعض الرموز الخاصة‬
‫‪29‬‬ ‫تمارٌن‬
‫‪30‬‬ ‫الفصل الرابع‪ :‬الثوابت (‪)Constants‬‬
‫‪31‬‬ ‫الفصل الخامس‪ :‬المعامالت )‪(Operators‬‬
‫‪31‬‬ ‫اإلسناد )=(‬
‫‪31‬‬ ‫المعامبلت الرٌاضٌّة ) ‪( + , - , * , / , %‬‬
‫‪32‬‬ ‫معامبلت اإلسناد المركبة ) =| ‪( += , -= , *= , /= , %= , &= , ^= ,‬‬
‫‪32‬‬ ‫معامبلت الزٌادة والنقصان )‪(++ , --‬‬
‫‪32‬‬ ‫معامبلت المقارنة ) => ‪( == , != , < , > , <= ,‬‬
‫‪33‬‬ ‫المعامبلت المنطق ٌّة ) || ‪( ! , && ,‬‬
‫‪33‬‬ ‫المعامل الشرطً ) ؟ (‬
‫‪34‬‬ ‫معامل تحوٌل البٌانات‬

‫‪4‬‬
‫‪34‬‬ ‫المعامل )(‪sizeof‬‬
‫‪34‬‬ ‫أولوٌات تنفٌذ المعامبلت‬
‫‪36‬‬ ‫تمارٌن‬
‫‪37‬‬ ‫الفصل السادس‪ :‬بنى التحكم (‪)Control Structures‬‬
‫‪37‬‬ ‫بنٌة الشرط ‪condition structure‬‬
‫‪39‬‬ ‫بنى التكرار ‪loops or repetition structures‬‬
‫‪42‬‬ ‫التعلٌمة ‪break‬‬
‫‪42‬‬ ‫التعلٌمة ‪continue‬‬
‫‪43‬‬ ‫التعلٌمة ‪goto‬‬
‫‪43‬‬ ‫التعلٌمة ‪switch‬‬
‫‪46‬‬ ‫الحلقات المتداخلة ‪nested loops‬‬
‫‪48‬‬ ‫تمارٌن محلولة‬
‫‪56‬‬ ‫تمارٌن‬
‫‪58‬‬ ‫الفصل السابع‪ :‬التوابع (‪)Functions‬‬
‫‪60‬‬ ‫التوابع التً ال تعٌد قٌمة ) استخدام الكلمة ‪( void‬‬
‫‪61‬‬ ‫تمر ٌر الوسطاء بالقٌمة وبالمرجع )العنوان(‬
‫‪63‬‬ ‫المدى ‪Scope‬‬
‫‪63‬‬ ‫المتغٌرات الشاملة ‪ Global variables‬و المتغٌرات الموضعٌة ‪Local variables‬‬
‫‪64‬‬ ‫المتغٌرات الثابتة ‪static‬‬
‫‪64‬‬ ‫تعٌٌن القٌمة االفتراضٌة للوسطاء‬
‫‪65‬‬ ‫إعادة تحمٌل التوابع ‪functions overloading‬‬
‫‪65‬‬ ‫التعرٌف المبدبً للتوابع ‪functions prototype‬‬
‫‪67‬‬ ‫الفصل الثامن‪ :‬التعاودٌة (‪)Recursion‬‬
‫‪72‬‬ ‫تمارٌن محلولة‬
‫‪86‬‬ ‫تمارٌن‬

‫‪78‬‬ ‫الفصل التاسع‪ :‬المصفوفات (‪)Arrays‬‬ ‫القسم الثانً‬


‫‪79‬‬ ‫التعامل مع المصفوفات‬
‫‪80‬‬ ‫المصفوفات المتعددة األبعاد‬
‫‪82‬‬ ‫المصفوفات كمعامبلت )وسطاء( للتوابع‬
‫‪83‬‬ ‫األعداد العشوابٌة‬
‫‪85‬‬ ‫تمارٌن محلولة‬
‫‪90‬‬ ‫تمارٌن‬

‫‪5‬‬
‫‪92‬‬ ‫الفصل العاشر‪ :‬سالسل الرموز (‪)Strings of Characters‬‬
‫‪92‬‬ ‫التعامل مع السبلسل‬
‫‪95‬‬ ‫الفصل الحادي عشر‪ :‬المؤشرات (‪)pointers‬‬
‫‪95‬‬ ‫معامل العنوان ) & (‬
‫‪95‬‬ ‫معامل المرجع ) * (‬
‫‪:7‬‬ ‫التصرٌح عن المإ ّ‬
‫شرات‬
‫‪:8‬‬ ‫المإ ّ‬
‫شرات والمصفوفات‬
‫‪:9‬‬ ‫تبدبة المإ ّ‬
‫شرات‬
‫‪:9‬‬ ‫مصفوفة المإ ّ‬
‫شرات‬
‫‪99‬‬ ‫العملٌات الحسابٌة على المإ ّ‬
‫شرات‬
‫‪100‬‬ ‫شرات على المإ ّ‬
‫شرات‬ ‫المإ ّ‬
‫‪100‬‬ ‫المإ ّ‬
‫شرات الخالٌة ‪void pointers‬‬
‫‪101‬‬ ‫المإ ّ‬
‫شرات على التوابع‬
‫‪103‬‬ ‫الفصل الثانً عشر‪ :‬الذاكرة الدٌنامٌكٌة (‪)Dynamic Memory‬‬
‫‪103‬‬ ‫المعامل ‪new‬‬
‫‪104‬‬ ‫المعامل ‪delete‬‬
‫‪105‬‬ ‫الفصل الثالث عشر‪ :‬التراكٌب (‪)Structures‬‬
‫‪105‬‬ ‫تراكٌب المعطٌات‬
‫‪107‬‬ ‫مصفوفة التراكٌب‬
‫‪108‬‬ ‫التراكٌب و المإ ّ‬
‫شرات‬
‫‪109‬‬ ‫التراكٌب المتداخلة‬
‫‪113‬‬ ‫الفصل الرابع عشر‪ :‬األنواع المعرفة من قبل المستخدم‬
‫‪113‬‬ ‫تعرٌف أنواع خاصّة ) ‪( typedef‬‬
‫‪113‬‬ ‫الوحدات ) ‪( Unions‬‬
‫‪114‬‬ ‫المر ّقمات ) ‪Enumerations ( enum‬‬
‫‪114‬‬ ‫الفصل الخامس عشر‪ :‬اإلدخال و اإلخراج فً الملفات‬
‫‪115‬‬ ‫فتح ملف‬
‫‪116‬‬ ‫إغبلق ملف‬
‫‪116‬‬ ‫الملفات النصٌّة‬
‫‪117‬‬ ‫التحقق من الحالة‬
‫‪117‬‬ ‫مإ ّ‬
‫شرا التدفق ) ‪ put‬و ‪( get‬‬
‫‪119‬‬ ‫الفصل السادس عشر‪ :‬معالجة االستثناءات ( ‪) Exceptions handling‬‬

‫‪6‬‬
‫‪122‬‬ ‫التوجه (‪)OOP‬‬
‫ّ‬ ‫الفصل السابع عشر‪ :‬البرمجة كائن ٌّة‬ ‫القسم الثالث‬
‫‪122‬‬ ‫مقدّمة‬
‫‪123‬‬ ‫معرّ فات الوصول ‪Access modifieres‬‬
‫‪125‬‬ ‫معامل المدى ‪::‬‬
‫‪125‬‬ ‫التوابع األعضاء ‪inline‬‬
‫‪128‬‬ ‫المشٌّدات ‪Constructors‬‬
‫‪129‬‬ ‫الهادمات ‪Destructors‬‬
‫‪129‬‬ ‫إعادة تحمٌل المشٌّدات ‪Overloading Constructors‬‬
‫‪132‬‬ ‫المإ ّ‬
‫شرات على الصفوف ‪Pointers to classes‬‬
‫‪133‬‬ ‫الكلمة المفتاحٌّة ‪this‬‬
‫‪135‬‬ ‫الصفوف المعرّ فة باستخدام الكلمة المحجوزة ‪struct‬‬
‫‪135‬‬ ‫إعادة تحمٌل المعامبلت ‪Overloading operators‬‬
‫‪138‬‬ ‫األعضاء الثابتة من النوع ‪static‬‬
‫‪140‬‬ ‫التوجه (‪)OOP principles‬‬
‫ّ‬ ‫الفصل الثامن عشر‪ :‬مبادئ البرمجة كائن ٌّة‬
‫‪140‬‬ ‫مبدأ التغلٌف ‪Encapsulation‬‬
‫‪142‬‬ ‫التوابع ‪ friend‬الكلمة المفتاحٌّة ) ‪( friend‬‬
‫‪143‬‬ ‫الصفوف من النوع ‪friend‬‬
‫‪144‬‬ ‫الوراثة بٌن الصفوف ‪Inheritance between classes‬‬
‫‪147‬‬ ‫الوراثة المتعددة ‪Multiple inheritance‬‬
‫‪148‬‬ ‫تعدد األشكال ‪Polymorphism‬‬
‫‪148‬‬ ‫المإ ّ‬
‫شرات على الصفّ األساسً ‪Pointers to base class‬‬
‫‪149‬‬ ‫األعضاء من النوع ‪virtual‬‬
‫‪152‬‬ ‫الصفوف األساسٌّة المجردة ‪Abstract base classes‬‬
‫‪155‬‬ ‫الفصل التاسع عشر‪ :‬القوالب (‪)Templates‬‬
‫‪155‬‬ ‫تابع القوالب‬
‫‪157‬‬ ‫صفّ القوالب‬
‫‪158‬‬ ‫تخصٌص القالب ‪Template specialization‬‬
‫‪061‬‬ ‫الفصل العشرون‪ :‬فضاءات األسماء (‪)Namespaces‬‬
‫‪272‬‬ ‫التعلٌمة ‪using namespace‬‬
‫‪273‬‬ ‫الفضاء ‪std‬‬
‫‪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‬‬
‫الفصل األوّل ‪:‬‬

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

‫افتح المترجم واكتب فٌه النصّ الذي على ٌسار الشكل ث ّم اضغط على أزرار التشغٌل‬

‫‪// my first program in C++‬‬ ‫!‪Hello World‬‬


‫>‪#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‬‬
‫ب بلغة ‪ .C++‬وهذا الٌعتمد على كون هذا التابع مكتوبا‬ ‫إنّ التابع ‪ main‬هو النقطة األولى لبداٌة أي برنامج مكتو ٍ‬
‫فً أوّ ل الشٌفرة أو فً وسطها أو فً آخرها فؤٌنما كان هذا التابع مكتوبا فإنّ التنفٌذ سٌبدأ منه أي أ ّنه ضروريّ‬
‫ج ّدا لٌعمل البرنامج ومن دونه ال ٌوجد برنامج‪.‬‬
‫فً التصرٌح عن التابع ‪ 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++‬تنتهً بالفاصلة المنقوطة كما ذكرنا‪ .‬لذلك ال فرق فً أن تكتب ال ّتعلٌمات على سطر واحد‬
‫أو فً ع ّدة أسطر‪ ,‬فطالما أ ّنك لم تضع فاصلة منقوطة فهذا ٌعنً أنّ ال ّتعلٌمة لم تنت ِه بعد‪.‬‬
‫لك ّننا كتبناه كما فً الجدول لكً تسهل قراءته‪.‬‬

‫واآلن سنكتب المثال التالً بطرٌقة أخرى ممكنة‬

‫‪// my second program in C++‬‬ ‫‪Hello World! I'm a C++ program‬‬


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

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

‫‪29‬‬
‫التعلٌقات‬
‫ال ّتعلٌق هو قطعة من الشٌفرة مهملة من قبل المترجم‪ .‬إذن التعلٌقات ال تقوم بؤ ٌّة وظٌفة برمجٌة‪ ,‬وإ ّنما هً‬
‫موجودة فقط لتذ ّكر المبرمج ببعض المبلحظات حول شٌفرته‪.‬‬

‫تق ّدم ‪ C++‬نوعٌن من التعلٌقات هما كاآلتً‪:‬‬

‫‪// line comment‬‬ ‫تعلٌق على نفس السطر‬

‫‪/* block comment */‬‬ ‫تعلٌق على سطر أو أكثر‬

‫واآلن لنضف بعض التعلٌقات إلى برنامجنا السابق‬

‫‪/* my second program in C++‬‬ ‫‪Hello World! I'm a C++ program‬‬


‫‪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++‬‬

‫مالحظات‬ ‫المدى (ٌمثل القٌم التً ٌمكن للمتغ ٌّر أن ٌأخذها)‬ ‫الحجم بالباٌت‬ ‫نوع المتغ ٌّر‬
‫حرف واحد أو رقم طوله‬ ‫بإشارة ]‪[-128,127‬‬ ‫‪2‬‬ ‫‪char‬‬
‫‪ 8‬بِت‬ ‫دون إشارة ]‪[0,255‬‬
‫رقم صحٌح طوله ‪06‬‬ ‫بإشارة ]‪[-32768 , 32767‬‬ ‫‪3‬‬ ‫‪short‬‬
‫بِت‬ ‫دون إشارة ]‪[0,65535‬‬
‫رقم صحٌح طوله ‪23‬‬ ‫بإشارة ]‪[-2147483648 , 2147483647‬‬ ‫‪5‬‬ ‫‪long‬‬
‫ِبت‬ ‫دون إشارة ]‪[0,53:5:783:6‬‬
‫رقم صحٌح‬ ‫إما ‪ short‬أو ‪long‬‬ ‫‪ 3‬أو ‪5‬‬ ‫‪int‬‬
‫رقم عشري‬ ‫)‪ 8‬أرقام(‬ ‫إلى‬ ‫‪5‬‬ ‫‪float‬‬
‫رقم ذو دقة عشرٌة‬ ‫)‪ 26‬رقم(‬ ‫إلى‬ ‫‪9‬‬ ‫‪double‬‬
‫مضاعفة عن ‪float‬‬
‫رقم ذو دقة عشرٌة‬ ‫)‪ 26‬رقم(‬ ‫إلى‬ ‫‪21‬‬ ‫‪long double‬‬
‫مضاعفة عن ‪double‬‬
‫متغ ٌّر منطقً بإحدى‬ ‫‪ true‬أو ‪false‬‬ ‫‪2‬‬ ‫‪bool‬‬
‫القٌمتٌن ‪ 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‬‬
‫وهذا هو الشكل المعتاد لهذه الحالة‪.‬‬

‫واآلن لنكتب المثال الذي بدأنا به درسنا‬

‫‪// operating with variables‬‬ ‫‪16‬‬


‫>‪#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 enter your name: Basil


#include <iostream> Hello Basil
#include <string>
using namespace std;

int main ()
{
string name;
cout<<"enter your name: ";
cin>>name;
cout << "Hello "<<name<<endl;
return 0;
}
ّ ‫ تقوم بنقل المإ‬endl ‫التعلٌمة‬
.‫شر إلى السطر التالً كما سنرى فٌما بعد‬

(<,>) ‫( والمقارنة‬+=) ‫( واإلضافة‬+) ‫ كالجمع‬string ّ‫هناك مجموعة من العمل ٌّات المعرّ فة فً الصف‬

:‫مثال‬

// my second string enter your first name: Ahmad


#include <iostream> enter your last name: Sami
#include <string> Hello Ahmad Sami
using namespace std; Ahmad

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
‫‪ .2‬أجب عن األسبلة التالٌة ‪:‬‬
‫‪ ‬هل المتغٌّر ‪ Num‬هو نفس المتغٌّر ‪ num‬فً ‪ C++‬؟‬
‫‪ ‬هل ٌجب أن ٌعطى المتغٌّر نوعا من البٌانات عند التصرٌح عنه ؟‬
‫‪ ‬هل ٌمكن أن تكون أسماء المتغٌّرات أي مجموعة من الرموز ؟‬
‫‪ ‬هل نستطٌع أن نعرّ ف متغٌّرا ونعطٌه قٌمة فً نفس اللحظة ؟‬
‫‪ ‬ما الفرق بٌن المتغٌّرات ‪ signed‬و ‪. unsigned‬‬
‫‪ .3‬امؤل الفراغات التالٌة ‪:‬‬
‫‪ ‬المتغ ٌّرات هً ______ فً ذاكرة الحاسب ______فٌها البٌانات‪ ,‬وٌت ّم الوصول إلٌها من خبلل‬
‫______المتغٌّر الذي ______عن باقً المتغٌّرات فً ______‪.‬‬

‫‪ .4‬اختر اإلجابة الصحٌحة؟‬

‫)‪a‬‬ ‫; ‪unsigned long f = -1.25‬‬


‫)‪b‬‬ ‫; ‪int 4men‬‬
‫)‪c‬‬ ‫;'‪double d = 'S‬‬
‫)‪d‬‬ ‫; ‪long _2u‬‬
‫)‪e‬‬ ‫; ‪short hi.‬‬
‫)‪f‬‬ ‫; "‪char u = "U‬‬

‫‪ .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‬‬

‫; ‪cout<< 120‬‬ ‫‪// print number 120 on screen‬‬

‫; ‪cout<< x‬‬ ‫‪// print the content of variable x on screen‬‬

‫مالذي تفعله هذه التعلٌمات؟‬

‫‪ -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‬‬

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


‫‪\n‬‬ ‫‪New line‬‬ ‫سطر جدٌد‬
‫‪\r‬‬ ‫‪Enter‬‬ ‫ٌكافا الضغط على زر‬
‫‪\t‬‬ ‫‪Tabulation‬‬ ‫مسافة جدولة أفقٌة‬
‫‪\b‬‬ ‫‪Back space‬‬ ‫تراجع‬
‫‪\a‬‬ ‫‪Beep‬‬ ‫ٌصدر صوتا‬
‫'\‬ ‫'‬ ‫تطبع الرمز‬
‫"\‬ ‫"‬ ‫تطبع الرمز‬

‫‪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‬‬ ‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬ ‫;‪using namespace std‬‬
‫‪#define pi 3.14159265‬‬ ‫;‪const double pi = 3.14159265‬‬
‫)(‪int main‬‬ ‫)(‪int main‬‬
‫{‬ ‫{‬
‫; ‪float R ,r‬‬ ‫; ‪float r‬‬
‫‪r = 0 ;//initial to‬‬ ‫‪0‬‬ ‫‪r = 0 ;//initial to 0‬‬
‫‪cout<<"enter circle‬‬ ‫;" ‪radius plz:‬‬ ‫;" ‪cout<<"enter circle radius plz:‬‬
‫; ‪cin>> r‬‬ ‫; ‪cin>> r‬‬
‫‪cout<< "circle area‬‬ ‫" =‬ ‫" = ‪cout<< "circle area‬‬
‫‪<< 0.5 * pi * r‬‬ ‫;‪* r << endl‬‬ ‫;‪<< 0.5 * pi * r * r << endl‬‬
‫; ‪return 0‬‬ ‫; ‪return 0‬‬
‫}‬ ‫}‬

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

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

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

‫‪ .1‬اإلسناد (=)‬
‫ٌقبله(كأن نضع رقم صحٌح فً متغٌّر من النوع العشري مثالا)‬ ‫نستخدم معامل اإلسناد = كً نعطً المتغٌّر قٌمة من نوع‬
‫; ‪float a = 3‬‬
‫أسند العدد الصحٌح ‪ 4‬إلى المتغٌّرالعشري ‪ٌ .a‬قوم معامل اإلسناد بإسناد القٌمة على ٌمٌنه إلى المتغٌّر الذي على‬
‫ٌساره حٌث أنّ القٌمة على الٌمٌن ٌمكن أن تكون متغٌّرا أو عددا ثابتا أو نتٌجة لعدد من العملٌات على قٌم‬
‫موافقة لنوع المتغٌّر على ٌسارمعامل اإلسناد‪ .‬واإلسناد المعاكس لٌس ممكنا‪.‬‬

‫أمثلة‪:‬‬

‫; ‪int a , b‬‬ ‫? ‪// a :‬‬ ‫?‪b:‬‬


‫; ‪a = 10‬‬ ‫‪// a : 10‬‬ ‫?‪b:‬‬
‫;‪b=4‬‬ ‫‪// a : 10‬‬ ‫‪b:4‬‬
‫;‪a=b‬‬ ‫‪// a : 4‬‬ ‫‪b:4‬‬
‫;‪b=7‬‬ ‫‪// a : 4‬‬ ‫‪b:7‬‬
‫)‪a = 2 + ( b = 5 ) ; // 1‬‬ ‫)‪b = 5 ; 2‬‬ ‫; ‪a = 2 + b ; 3) a = 7‬‬

‫أسند القٌمة ‪ 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‬‬ ‫;‪value = value + increase‬‬


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

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


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

‫مالحظة‪:‬‬

‫ٌمكن استخدام هذٌن المعاملٌن بطرٌقتٌن مختلفتٌن و المثال التالً ٌبٌن ذلك‪:‬‬

‫الفرق‬ ‫الطرٌقة الثانٌة‬ ‫الطرٌقة األولى‬


‫فً كبل الطرٌقتٌن بدأنا مع ‪b = 3‬‬ ‫;‪b = 3‬‬ ‫;‪b = 3‬‬
‫فً الطرٌقة‪ 0‬تصبح ‪ a = 3‬ث ّم‬ ‫;‪a = ++b‬‬ ‫; ‪a = b++‬‬
‫تزداد قٌمة ‪ b‬فتصبح ‪ b = 4‬أما فً‬ ‫‪// a = 4 , b = 4‬‬ ‫‪// a = 3 , b = 4‬‬
‫الطرٌقة‪ 2‬تزداد قٌمة ‪ b‬ث ّم تصبح‬
‫‪a=b=4‬‬ ‫ُتسند ‪ b‬إلى ‪ a‬ث ّم تزداد ‪ b‬بمقدار ‪ 1‬تزداد ‪ b‬بمقدار ‪ 1‬ث ّم ُتسند ‪ b‬إلى ‪a‬‬

‫‪ .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‬‬

‫ٌعٌد ‪ false‬ألن ‪ 6‬تساوي ‪6‬‬ ‫) ‪!( 5 == 5‬‬


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

‫المعامالن && و || ‪:‬‬

‫&& ّ‬
‫ٌمثل معامل الربط المنطقً ) َو ( ‪and‬‬

‫|| ّ‬
‫ٌمثل معامل الربط المنطقً ) أو ( ‪or‬‬

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

‫‪ .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‬‬
‫من الٌسار‬ ‫) ( األقواس ‪sizeof() ,‬‬
‫من الٌسار‬ ‫*‪%,/,‬‬ ‫‪3‬‬
‫‪++ , --‬‬
‫~‬
‫من الٌمٌن‬ ‫!‬ ‫‪2‬‬
‫*‪& ,‬‬
‫)‪(type‬‬
‫‪+,-‬‬
‫من الٌسار‬ ‫> ‪<= , >= , < ,‬‬ ‫‪1‬‬
‫من الٌسار‬ ‫== ‪!= ,‬‬ ‫‪5‬‬
‫من الٌسار‬ ‫&‪|,^,‬‬ ‫‪6‬‬
‫&& ‪|| ,‬‬ ‫‪7‬‬
‫من الٌمٌن‬ ‫‪?:‬‬ ‫‪8‬‬
‫من الٌمٌن‬ ‫= ‪&= , ^= , |= %= , /= , *= , -= , += ,‬‬ ‫‪9‬‬
‫من الٌسار‬ ‫‪,‬‬ ‫‪01‬‬

‫‪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) cout<< ++a ;
b) cout<< a++ ;
c) cout<< a++ / 2 ;
d) cout<< ++a / 2 ;

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

‫إنّ البرنامج لٌس عبارة عن مجموعة من تعلٌمات اإلسناد أو المقارنات أو اإلدخال واإلخراج التً تعلّمناها ح ّتى‬
‫اآلن‪ ,‬فنحن وكما تعلم نتحدّث عن البرمجة التً إ ّنما نستخدمها كً تساعدنا فً حل مشاكلنا الٌومٌة ومن األشٌاء‬
‫المهمّة التً نحتاج إلٌها هً اتخاذ القرارت المناسبة إلجراء عملٌات مع ٌّنة دون أخرى‪ .‬توفّر ‪ 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‬‬

‫الٌزال هناك حالة أخٌرة للشرط وسنحتاجها بكثرة أٌضا وهً من الشكل‪:‬‬
‫)‪if (condition 1‬‬ ‫( شرط‪ ) 0‬عندها ِافعل األشٌاء‪1‬‬ ‫إذا كان‬
‫{‬ ‫و إال إذا كان ( شرط‪ ) 2‬عندها ِافعل األشٌاء‪2‬‬
‫; ‪statements 1‬‬ ‫‪.‬‬
‫}‬ ‫‪.‬‬
‫)‪else if (condition 2‬‬ ‫‪.‬‬
‫; ‪statement 2‬‬ ‫وإال ِافعل األشٌاء‪n‬‬
‫‪.‬‬
‫‪.‬‬
‫‪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‬تنازل ٌّا كما هو موضح‪:‬‬
‫‪// custom countdown using while‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬
‫>‪#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‬تنازل ٌّا كما هو موضح‪:‬‬
‫‪// custom countdown using while‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬
‫>‪#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‬تنازل ٌّا كما هو موضح‪:‬‬
‫‪// custom countdown using for‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬
‫>‪#include <iostream‬‬
‫;‪using namespace std‬‬
‫)( ‪int main‬‬
‫{‬
‫) ‪for ( int n=10 ; n>0 ; n--‬‬
‫{‬
‫;" ‪cout << n << ",‬‬
‫}‬
‫;"!‪cout << "Fire‬‬
‫;‪return 0‬‬
‫}‬

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

‫‪Initialization‬‬

‫‪Condition‬‬
‫( ‪for‬‬ ‫‪n=0 , i=100‬‬ ‫‪; n!=i‬‬ ‫‪; n++ , i--‬‬ ‫)‬
‫‪Increase‬‬
‫{‬
‫‪// whatever here...‬‬
‫}‬

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

‫كما ٌمكن أن تكتب هذه الحلقة باألشكال التالٌة أٌضا‪:‬‬


‫);‪for (;n<10‬‬ ‫لم نعطً العداد قٌمة ابتدابٌة ولم نحدد مقدار خطوة الزٌادة ‪//‬‬

‫لم نعطً العداد قٌمة ابتدابٌة فقط ‪for (;n<10;n++) //‬‬

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

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

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

‫‪// number echoer‬‬ ‫‪Enter number (0 to end): 5‬‬


‫>‪#include <iostream‬‬ ‫‪You entered: 5‬‬
‫;‪using namespace std‬‬ ‫‪Enter number (0 to end): 0‬‬
‫)( ‪int main‬‬ ‫‪You entered: 0‬‬
‫{‬
‫;‪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 Enter number (0 to end): 5
#include <iostream> You entered: 5
using namespace std; Enter number (0 to end): 0
int main () You entered: 0
{
unsigned long n;
do
{
cout << "Enter number (0 to end): ";
cin >> n;
cout << "You entered: " << n<< "\n";
} while (n != 0);
return 0;
}

// number echoer Enter number (0 to end): 5


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

‫ تستخدم هذه التعلٌمة للخروج من البنٌة التً ُكتِبت فٌها كما فً الحالة الثالثة من‬:break ‫) التعلٌمة‬3
(n == 0) ‫ فنحن نرٌد أن نخرج من الحلقة)البنٌة(التكرارٌة بمجرّ د أن ٌتح ّقق الشرط‬,‫المثال السابق‬

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

53
‫البداٌة من التابع )(‪ٌ .main‬دخل المترجم الحلقة التكرارٌة وعندها تكون قٌمة العدّاد ‪ n = 12‬ث ّم ٌختبر‬
‫الشرط )‪ (n == 5‬وبالطبع لن ٌكون الشرط مح ّققا ألنّ ‪ 10 != 5‬وعندها ٌتجاهل التعلٌمة الموجودة داخل‬
‫بنٌة الشرط ‪ if‬ث ّم ٌنتقل إلى التعلٌمة التالٌة وهً تعلٌمة طباعة العدد ‪ n‬وبعدها تنتهً الحلقة للمرّ ة األولى‬
‫فٌعود المترجم إلى معامل النقصان فً الحلقة وٌغٌر قٌمة العداد ‪ n‬بحسب قٌمة النقصان المطلوبة )فً حالتنا ‪ (1‬ث ّم‬
‫ٌختبر الشرط ‪ n>0‬فإن كان محققا فسٌعود إلى داخل الحلقة مرّ ة أخرى وٌستمر فً هذه العملٌات حتى تصبح‬
‫قٌمة ‪ n = 5‬عندها سٌختبرالشرط ‪ n == 5‬والذي أصبح محققا لذلك سٌن ّفذ التعلٌمة الموجودة داخل تعلٌمة‬
‫الشرط وهً التعلٌمة ‪ continue‬والتً ستجبر المترجم على تجاهل التعلٌمات التً تلٌها مما ٌعنً تجاهل‬
‫التعلٌمة ;" ‪ cout << n << ",‬والعودة إلى بداٌة الحلقة إلنقاص الع ّداد واختبار الشرط ث ّم الدخول فً‬
‫الحلقة من جدٌد وهكذا حتى نهاٌة الحلقة‪.‬‬
‫‪ )5‬التعلٌمة ‪ :goto‬بهذه التعلٌمة تستطٌع إجبار المترجم على القفز من السطر الذي هو فٌه إلى السطر‬
‫الذي ترٌده لٌكمل التنفٌذ من المكان الذي أرسلته إلٌه‪ .‬الستخدام هذه التعلٌمة نحتاج إلى الفتة ‪label‬‬
‫الستعمالها كدلٌل على السطر الذي سنرسل المترجم إلٌه‪ ,‬وهذه البلفتة ٌجب أن تتبع بالنقطتٌن ) ‪.( :‬‬
‫مثال‪:‬‬
‫‪// goto loop example‬‬ ‫!‪10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE‬‬
‫>‪#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 // if
#include<iostream> #include<iostream>
using namespace std; using namespace std;
int main() int main()
{ unsigned short dnum ; {
cout<< "Enter number of day(1-7): "; unsigned short dnum ;
cin>> dnum; cout<< "Enter number of day(1-7): ";
cout<< "\n"; cin>> dnum;
switch(dnum){ cout<< "\n";
case 1: // if dnum = 1 if(dnum == 1)
cout << "the day is Friday"; cout << "the day is Friday";
break; else if(dnum == 2)
case 2: // if dnum = 2 cout << "the day is Saturday";
cout << "the day is Saturday"; else if(dnum == 3)
break; cout << "the day is Sunday";
case 3: // if dnum = 3 else if(dnum == 4)
cout << "the day is Sunday"; cout << "the day is Monday";
break; else if(dnum == 5)
case 4: // if dnum = 4 cout << "the day is Tuesday";
cout << "the day is Monday"; else if(dnum == 6)
break; cout << "the day is Tuesday";
case 5: // if dnum = 5 else if(dnum == 7)
cout << "the day is Tuesday"; cout << "the day is Thursday";
break; else
case 6: // if dnum = 6 cout << "Sorry we're closed ";
cout << "the day is Wednesday"; cout<<'\n';
break; return 0;
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
‫لنشرح ما حصل فً التعلٌمة ‪switch‬‬
‫وخز ّناه فً‬
‫ّ‬ ‫كما عوّ دتنا ‪ c++‬بدأ البرنامج من التابع )(‪ main‬ث ّم صرّحنا عن المتغٌّر ‪ ,dnum‬ث ّم قرأنا الرقم‬
‫المتغٌّر ‪ ,dnum‬واآلن جاء دور التعلٌمة ‪ switch‬التً أخذت المتغٌّر ‪ dnum‬وسٌطا‪ .‬بعد ذلك قمنا بذكر‬
‫الحاالت التً ٌمكن للمتغٌّر أن ٌحملها وهً األرقام }‪ {1,2,..,7‬وذكرنا كل عنصر منها لوحده بعد الكلمة‬
‫‪ case‬ث ّم وضعنا التعلٌمة التً تناسب كل حالة على حدة وفً نهاٌة كل حالة كتبنا التعلٌمة ‪ break‬التً‬
‫شرحناها سابقا والتً لها أهمٌّة كبٌرة فً التعلٌمة ‪ switch‬فعندما ٌقارن المترجم قٌمة المتغٌّر الوسٌط مع‬
‫الحالة األولى و تكون القٌمتٌن متساوٌتٌن عندها سٌنفذ التعلٌمات الخاصة بهذه الحالة وعندما سٌنتهً منها نرٌد‬
‫وأال ٌختبر باقً الحاالت لذلك وضعنا التعلٌمة ‪ break‬ولو لم نضعها‬ ‫منه أن ٌخرج من التعلٌمة ‪ّ switch‬‬
‫الخبتر المترجم كل الحاالت الباقٌة وهذا ٌعنً مضٌعة للوقت وبطؤ للبرنامج ال نرٌده أن ٌحصل طبعا‪ .‬أمّا‬
‫التعلٌمة ‪ default‬فهً تخصّ باقً االحتماالت الممكنة إذ قد ٌدخل المستخدم رقما غٌر األرقام المذكورة‬
‫لذلك نرٌد من البرنامج أن ٌخبر المستخدم أ ّنه أدخل رقما خاطبا‪ .‬جرّ ب البرنامجٌن‪ ,‬وستجد أن لهما نفس الناتج‬
‫تماما كما فً الشكل‪:‬‬
‫‪Enter number of day: 5‬‬
‫‪the day is Tuesday‬‬

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

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

‫‪1 2 3 4 5‬‬

‫>‪#include <iostream‬‬ ‫‪1 2 3 4 5‬‬


‫;‪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‬ثبلث مرّ ات متتالٌة على ثبلثة أسطر متتالٌة أٌضا أي‬
‫أ ّننا سنقوم بتكرار عمل الحلقة السابقة ثبلث مرّات كما فً الشكل التالً‪:‬‬
‫‪// nested loop‬‬ ‫‪1 2 3 4 5‬‬
‫>‪#include <iostream‬‬ ‫‪1 2 3 4 5‬‬
‫;‪using namespace std‬‬ ‫‪1 2 3 4 5‬‬
‫)( ‪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‬‬
‫‪ (a‬اقرأ الرقم األول ‪.n1‬‬
‫‪ (b‬اقرأ العملٌة ‪.op‬‬
‫‪ (c‬اقرأ الرقم الثانً ‪.n2‬‬
‫‪ (d‬افحص العملٌة ‪op‬‬
‫'‪ op = '+‬اطبع المجموع‬ ‫إذا كانت‬ ‫‪‬‬
‫وإال إذا كانت '–' = ‪ op‬اطبع الفرق‬ ‫‪‬‬
‫وإال إذا كانت '*' = ‪ op‬اطبع الجداء‬ ‫‪‬‬
‫وإال إذا كانت '‪op = '/‬‬ ‫‪‬‬
‫‪ ‬إذا كان الرقم الثانً ال ٌساوي الصفر‬
‫اطبع القسمة‬
‫‪ ‬و ّإال اطبع عبارة ‪. Infinite‬‬
‫الشٌفرة‬ ‫‪.2‬‬
‫>‪#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 ‫ عندها‬i = 1


a = 1.0 + 1 / 2 = 1.0 + 0 = 1.0 ‫ عندها‬i = 2
...
a = 1.0 + 1 / n = 1.0 + 0 = 1.0 ‫ عندها‬i = n

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

‫;‪fact = fact * j‬‬ ‫;‪fact = 0 * j‬‬ ‫; ‪fact = 0‬‬

‫‪ .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‬‬
‫‪.‬‬ ‫‪ b‬فإنّ‬ ‫إذا كان ‪0‬‬
‫وإال اطبع ‪.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‬اكتب برنامجا لك ّل شكل من األشكال التالٌة‪:‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬ ‫‪6‬‬

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

‫‪ .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‬‬
‫تابع لنا فً هذا الكتاب‪:‬‬
‫و اآلن لنكتب أوّ َل ٍ‬
‫‪// function example‬‬ ‫‪The result is 8‬‬
‫>‪#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‬‬

‫(‪z = adition‬‬ ‫‪5 ,‬‬ ‫‪3‬‬ ‫;)‬

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

‫لكنّ ‪ 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‬‬

‫(‪z = adition‬‬ ‫‪5 ,‬‬ ‫‪3‬‬ ‫;)‬


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

‫‪6:‬‬
‫مثال‪:‬‬
‫‪// function example‬‬ ‫‪The‬‬ ‫‪1st‬‬ ‫‪result‬‬ ‫‪is‬‬ ‫‪5‬‬
‫>‪#include <iostream‬‬ ‫‪The‬‬ ‫‪2nd‬‬ ‫‪result‬‬ ‫‪is‬‬ ‫‪5‬‬
‫;‪using namespace std‬‬ ‫‪The‬‬ ‫‪3rd‬‬ ‫‪result‬‬ ‫‪is‬‬ ‫‪2‬‬
‫)‪int sub(int a, int b‬‬ ‫‪The‬‬ ‫‪4th‬‬ ‫‪result‬‬ ‫‪is‬‬ ‫‪6‬‬
‫{‬
‫;)‪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‬‬
‫‪. . ..‬‬
‫}‬
‫مثال‪:‬‬
‫>‪#include <iostream‬‬ ‫!‪I'm a function‬‬
‫;‪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‬‬


‫‪5‬‬ ‫‪3‬‬
‫(‪z = adition‬‬ ‫‪x ,‬‬ ‫‪y‬‬ ‫;)‬

‫إنّ استدعاء الوسطاء بالقٌمة ٌمنع حدوث أي تغٌٌر على المتغٌّر الذي ت ّم تمرٌره إلى التابع خارج هذا التابع‬
‫ولتوضٌح هذه المسؤلة نقدّم هذا المثال‪:‬‬
‫‪// 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‬‬
‫‪x‬‬ ‫‪y‬‬ ‫‪z‬‬
‫( ‪duplicate‬‬ ‫‪x‬‬ ‫‪,‬‬ ‫‪y‬‬ ‫‪,‬‬ ‫) ‪z‬‬

‫‪72‬‬
:‫المثال التالً ٌوضح ذلك‬
// passing parameters by reference x,y,z before calling duplicate
#include <iostream> x=1, y=3, z=7
using namespace std; x,y,z after calling duplicate
void duplicate (int& a, int& b, int& c) x=2, y=6, z=14
{
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;
}

‫ أ ُ ْت ِب َع نوعُه بالرمز & الذي ٌعنً أنّ هذا الوسٌط‬duplicate ‫ٌجب أن تنتبه إلى أنّ ك ّل وسٌط فً التابع‬
.‫سٌمرّ ر بالمرجع و لٌس بالقٌمة كما فً الحالة األولى‬

‫ ولكنّ تمرٌر الوسطاء‬,‫كما قلنا فً بداٌة هذا الدرس إنّ التوابع تعٌد قٌمة وحٌدة بٌنما ال تعٌد الطرق أ ٌّة قٌمة‬
.‫بالمرجع ٌع ّد أداة قوٌة تستطٌع من خبللها أن تجعل التابع )الطرٌقة( ٌعٌد أكثر من قٌمة‬
:‫والمثال التالً ٌوضّح هذا‬
‫ الذي ٌقبل ثبلثة وسطاء حٌث ٌؤخذ الوسٌط األوّ ل وٌعٌد الرقم الذي ٌسبقه كقٌمة له من‬prevnext ‫لدٌنا التابع‬
.‫خبلل الوسٌط الثانً كما ٌعٌد الرقم الذي ٌلً الوسٌط األول كقٌمة له من خبلل الوسٌط الثالث‬

// more than one returning value Previous=99, Next=101


#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;
}

:‫ بالشكل‬prevnext ‫ ٌمكنك كتابة التابع‬: ‫مالحظة‬

int prevnext (int x,int& prev, int& next)


{ prev = x-1; next = x+1; return 0;}

73
‫المدى ‪Scope‬‬

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

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

‫)(‪int main‬‬
‫{‬
‫; ‪unsigned short Age‬‬
‫; ‪float ANumber , AnotherOne‬‬ ‫‪Local Variables‬‬
‫متغيراث موضعيت‬
‫;" ‪cout << "Enter Your age:‬‬
‫;‪cin >> Age‬‬ ‫‪Instructions‬‬
‫…‬
‫; ‪return 0‬‬
‫}‬
‫المتغ ٌّرات الشاملة ‪ Global variables‬و المتغ ٌّرات الموضع ٌّة ‪:Local variables‬‬
‫المتغ ٌّرت الشاملة هً المتغٌّرات التً ٌُصرّ ح عنها أعلى البرنامج خارج كل التوابع كما هو واضح فً الشكل‬
‫السابق فالمتغٌّرات ]‪ Integer , aCharacter , string [20‬كلّها متغٌّرات شاملة‪.‬‬

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

‫صرح عنها داخل القوسٌن‬


‫وهذا ماال تستطٌع المتغٌّرات الموضعٌّة أن تفعله‪ ,‬والمتغ ٌّرات الموضع ٌّة هً التً ٌ ّ‬
‫}{ لتابع أو إجراء أو بنٌة برمجٌة ما فً البرنامج‪.‬‬

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

‫فً ‪ C++‬المدى للمتغٌّر الموضعًّ محدّد فقط فً البنٌة البرمجٌة التً صُرِّ َح عنه فٌها‬
‫(البنٌة البرمجٌة المقصودة هً‬

‫ف فٌه‪ ,‬ولو أ ّنه‬


‫مجموعة التعلٌمات المحصورة بٌن القوسٌن }{) أي لو أ ّنه عُرِّ ف ضمن التابع فإنّ مداه هو التابع الذي عُرِّ َ‬
‫ف ضمن إحدى البنى التكرارٌة فإنّ مداه هو تلك البنٌة التكرارٌّة وحسب‪.‬‬ ‫عُرِّ َ‬

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

‫‪74‬‬
‫المتغٌرات الثابتة ‪static‬‬
‫هذا النوع من المتغٌرات تت ّم تبدأته مرة واحدة فقط وٌمكن أن تتغٌر قٌمته )ٌوجد منه نسخة واحدة فقط(‬
‫مثال‪:‬‬
‫‪// Example static variables‬‬ ‫‪n‬‬ ‫==‬ ‫‪0‬‬ ‫‪,‬‬ ‫‪x‬‬ ‫==‬ ‫‪0‬‬
‫>‪#include <iostream.h‬‬ ‫‪n‬‬ ‫==‬ ‫‪1‬‬ ‫‪,‬‬ ‫‪x‬‬ ‫==‬ ‫‪0‬‬
‫)‪void f(int a‬‬ ‫‪n‬‬ ‫==‬ ‫‪2‬‬ ‫‪,‬‬ ‫‪x‬‬ ‫==‬ ‫‪0‬‬
‫{‬ ‫‪n‬‬ ‫==‬ ‫‪3‬‬ ‫‪,‬‬ ‫‪x‬‬ ‫==‬ ‫‪0‬‬
‫)‪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‬‬
‫}‬

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


‫عندما نصرّ ح عن متغٌّر فإ ّننا نستطٌع أن نعطٌه قٌمة ابتدابٌة ث ّم قد نرغب بتغٌٌر قٌمته فٌما بعد أثناء البرنامج‬
‫لكن هل نستطٌع أن نعطً قٌمة ابتدائٌة لوسٌط معرف داخل تابع ما؟‬
‫قلت لك‪" :‬نعم"‪ .‬فً الحقٌقة ٌع ّد هذا ممكنا من أجل ك ّل وسٌط ترٌد أن تعطٌه قٌمة ابتدابٌة لتكون‬ ‫ال تتعجّ ب إن ُ‬
‫قٌم َته االفتراضٌة فً حال لم تقم بوضع أيّ قٌمة فً مكان هذا الوسٌط عند استدعاء التابع‪ ,‬ولكن لو قمت بوضع‬
‫قٌمة أخرى أثناء استدعاء التابع فسٌعتبر المترجم أنّ قٌمة الوسٌط هً القٌمة التً أدخلتها عند استدعاء التابع‬
‫وسٌتجاهل القٌمة االفتراضٌة تلك‪.‬‬
‫مثال‪:‬‬
‫‪// default values in functions‬‬ ‫‪6‬‬
‫>‪#include <iostream‬‬ ‫‪5‬‬
‫;‪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‬‬
‫لو كان لدٌنا تابعان ٌقومان بنفس التعلٌمات تماما وٌمتلكان نفس االسم أٌضا لك ّنهما ٌختلفان عن بعضٌهما‬
‫ُعرفُ بإعادة التحمٌل‬
‫بالوسطاء وهذا االختبلف قد ٌكون فً األنواع أو فً عدد الوسطاء المطلوبة‪ ,‬فهذا ما ٌ َ‬
‫التوابع‪.‬‬
‫وإلٌك المثال التالً‪:‬‬
‫‪//overloaded function‬‬ ‫‪2‬‬
‫>‪#include<iostream‬‬ ‫‪2.5‬‬
‫;‪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 Type a number (0 to exit): 9
#include <iostream> Number is odd.
using namespace std; Type a number (0 to exit): 6
void odd (int a); Number is even.
void even (int a); Type a number (0 to exit): 1030
Number is even.
int main () Type a number (0 to exit): 0
{ Number is even.
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
‫الفصل الثامن‪:‬‬

‫التعاود ٌّة‪ :‬هً خاصٌّة ٌستطٌع التابع من خبللها أن ٌستدعً نفسه‪.‬‬

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

‫وٌُصطلح على أنّ ‪:‬‬

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

‫وكمثال لنؤخذ الرقم ‪ 6‬ونحسب العاملً له‪:‬‬


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

‫‪// factorial calculator‬‬ ‫‪Type a number: 4‬‬


‫>‪#include <iostream‬‬ ‫‪4! = 732‬‬
‫;‪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‬من أجل القٌمة ‪3‬‬ ‫التابع ‪ fact‬من أجل القٌمة ‪5‬‬

‫‪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‬‬
‫هل ٌجب علٌنا أن نستخدم هذا األسلوب دائماا؟ فً الحقٌقة إنّ استخدام هذا األسلوب مرب ٌ‬
‫ك كثٌرا وٌكمن البدٌل‬
‫فً استخدام البنى التكرارٌّة‪ ,‬فالقاعدة تقول‪" :‬البرنامج الذي ٌمكن كتابته بشكل تعاوديّ ٌمكن كتابته بشكل‬
‫تكراري وهذا أفضل وأسرع"‪ .‬لنكتب المثال السابق بشكل تكراري‪:‬‬

‫‪// factorial calculator‬‬ ‫‪Type a number: 9‬‬


‫>‪#include <iostream‬‬ ‫‪9! = 362880‬‬
‫;‪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‬باستخدام الحلقتٌن التكرارٌتٌن الباقٌتٌن‪.‬‬

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

‫>‪#include<iostream‬‬ ‫‪Enter n: 4‬‬


‫;‪using namespace std‬‬ ‫‪sum(4) = 10‬‬
‫)‪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> Enter n: 4
using namespace std; fib(4) = 3
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
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‬ماهو ناتج تنفٌذ التوابع التالٌة‪:‬‬
‫‪A‬‬ ‫‪B‬‬ ‫‪C‬‬
‫>‪#include<iostream‬‬ ‫>‪#include<iostream‬‬ ‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬ ‫;‪using namespace std‬‬ ‫;‪using namespace std‬‬
‫)‪int sum(int a‬‬ ‫)‪int sum(int a‬‬ ‫)‪int sum(int a‬‬
‫{‬ ‫{‬ ‫{‬
‫)‪if(a>1‬‬ ‫)‪if(a>1‬‬ ‫)‪if(a>1‬‬
‫;)‪return a+sum(--a‬‬ ‫;)‪return a+sum(a--‬‬ ‫;)‪return a+sum(a-1‬‬
‫)‪else if(a==1‬‬ ‫)‪else if(a==1‬‬ ‫)‪else if(a==1‬‬
‫;‪return a‬‬ ‫;‪return a‬‬ ‫;‪return a‬‬
‫;‪else return 0‬‬ ‫;‪else return 0‬‬ ‫;‪else return 0‬‬
‫}‬ ‫}‬ ‫}‬
‫)(‪int main‬‬ ‫)(‪int main‬‬ ‫)(‪int main‬‬
‫{‬ ‫{‬ ‫{‬
‫;‪cout<<sum(5)<<endl‬‬ ‫;‪cout<<sum(5)<<endl‬‬ ‫;‪cout<<sum(5)<<endl‬‬
‫;‪return 0‬‬ ‫;‪return 0‬‬ ‫;‪return 0‬‬
‫}‬ ‫}‬ ‫}‬

‫‪A‬‬ ‫‪B‬‬ ‫‪C‬‬


‫ٌطبع القٌمة ‪11‬‬ ‫ٌحدث خطؤ من النوع‬ ‫ٌطبع القٌمة ‪15‬‬
‫‪stack overflow‬‬

‫‪A‬‬ ‫‪B‬‬ ‫‪C‬‬


‫=‪ a‬االستدعاء‬ ‫=‪sum‬‬ ‫=‪ a‬االستدعاء‬ ‫=‪sum‬‬ ‫االستدعاء‬ ‫=‪a‬‬ ‫=‪sum‬‬
‫‪not‬‬
‫‪1‬‬ ‫‪5‬‬ ‫‪11‬‬ ‫‪1‬‬ ‫‪5‬‬ ‫‪calculated‬‬ ‫‪1‬‬ ‫‪5‬‬ ‫‪15‬‬
‫‪not‬‬ ‫‪+‬‬
‫‪3‬‬ ‫‪6‬‬ ‫‪+ 7‬‬ ‫‪3‬‬ ‫‪5‬‬ ‫‪calculated‬‬ ‫‪3‬‬ ‫‪6‬‬ ‫‪12‬‬
‫‪+ 6‬‬ ‫‪not‬‬ ‫‪+‬‬
‫‪2‬‬ ‫‪2‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪calculated‬‬ ‫‪2‬‬ ‫‪2‬‬ ‫‪4‬‬
‫‪+ 3‬‬ ‫‪not‬‬ ‫‪+‬‬
‫‪6‬‬ ‫‪3‬‬ ‫‪6‬‬ ‫‪5‬‬ ‫‪calculated‬‬ ‫‪6‬‬ ‫‪3‬‬ ‫‪2‬‬
‫‪+‬‬
‫‪5‬‬ ‫‪1‬‬ ‫‪+ 1‬‬ ‫‪...‬‬ ‫‪...‬‬ ‫‪not‬‬
‫‪calculated‬‬ ‫‪5‬‬ ‫‪1‬‬ ‫‪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 1to3


Move Disk (2) from 1to2
Move Disk (1) from 3to2
Move Disk (3) from 1to3
Move Disk (1) from 2to1
Move Disk (2) from 2to3
Move Disk (1) from 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‬‬
‫}‬
‫‪ .3‬ماذا سٌكون ناتج البرنامج السابق لو استبدلنا التعلٌمة ;‪ return (x+1)/2.0‬بالتعلٌمة‬
‫;‪ return ++x/2.0‬؟‪.‬‬
‫‪ .4‬اكتب برنامجا ٌقوم بالعملٌّات الرٌاضٌّة األربع وذلك باستخدام التوابع‪.‬‬
‫ث ّم اكتبه باستخدام تابع تكراري‪.‬‬ ‫‪ .5‬باستخدام تابع تعاوديّ اكتب برنامجا ٌحسب العدد‬
‫(‬ ‫و‬ ‫و‬ ‫َو‬ ‫)مع مالحظة أنّ ‪:‬‬
‫‪ .6‬اكتب برنامجا فٌه تابع ٌقوم بإٌجاد مجموع السلسلة التالٌة‪:‬‬
‫𝜋‬ ‫∑‬
‫اعتمد على التمرٌن السابق لحساب‪.‬‬

‫‪ .7‬اكتب برنامجا إلٌجاد القاسم المشترك األكبر لعددٌن باستخدام تابع تكراري و آخر تعاودي‬
‫علما أنّ ‪.GCD(x , y) = GCD(x , x % y) :‬‬

‫‪86‬‬
‫) (‬ ‫‪ .8‬اكتب برنامجا فٌه تابع لحساب !‪ n‬و آخر لحساب‬
‫) (‬ ‫و آخر لحساب‬

‫‪ .9‬اكتب تابعا )إجراء( اسمه ‪ multiple‬بحٌث ٌؤخذ عددٌن صحٌحٌن كوسٌطٌن ث ّم ٌعٌد )ٌطبع( ‪ true‬إذا‬
‫كان العدد الثانً من مضاعفات العدد األول وإال فٌعٌد )ٌطبع( ‪.false‬‬
‫‪ .10‬اكتب برنامجا ّ فٌه تابع ٌقوم بفحص رقم صحٌح ممرّ ر إلٌه وٌعٌد قٌمة منطقٌّة ‪ true‬إذا كان أولٌّا و‬
‫‪ false‬إذا لم ٌكن‪ ,‬ث ّم استخدم إجراء ٌقوم بطباعة كل األرقام األولٌّة بٌن ‪ 1‬والرقم المدخل‪ٌ).‬مكنك استخدام‬
‫التابع السابق داخل هذا اإلجراء(‪.‬‬
‫مبلحظة ‪ :‬الرقم األوّ لً هو الرقم الذي ٌقبل القسمة على نفسه وعلى ‪ 1‬فقط‪ .‬والرقم ‪ 1‬لٌس أولٌّا‪.‬‬
‫‪ .11‬اكتب برنامجا فٌه تابع لحساب القٌمة المطلقة لعدد ما‪ .‬علما أ ّنها تح ّقق الشكل التالً‪:‬‬
‫| |‬ ‫{‬
‫‪ .12‬اكتب برنامجا فٌه ثبلثة توابع كما ٌلً‪:‬‬
‫𝜋‬ ‫‪ٌ ‬حسب مساحة دابرة بعد إدخال نصف قطرها ‪r‬‬
‫‪ٌ ‬حسب مساحة مستطٌل بعد إدخال طولً ضلعٌه ‪a, b‬‬
‫ٌحسب مساحة مثلث بعد إدخال طول قاعدته ‪ b‬و ارتفاعه ‪h‬‬ ‫‪‬‬

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

‫‪1- Calculate‬‬ ‫‪circle space‬‬


‫‪2- Calculate‬‬ ‫‪rectangle space‬‬
‫‪3- Calculate‬‬ ‫‪triangle space‬‬
‫‪Enter number‬‬ ‫‪from list above to select: 2‬‬

‫… ‪Calculating rectangle space‬‬


‫‪Enter Rectangle width: 5‬‬
‫‪Enter Rectangle height: 3‬‬
‫‪S = 15‬‬

‫‪ .13‬اكتب برنامجا فٌه تابع ٌؤخذ وسٌطا ّ‬


‫ٌمثل ارتفاع مثلث ث ّم ٌطبعه بالشكل التالً‪:‬‬
‫*‬
‫*‬ ‫*‬ ‫*‬
‫* *‬ ‫*‬ ‫* *‬
‫* * *‬ ‫*‬ ‫* * *‬
‫* * * *‬ ‫*‬ ‫* * * *‬
‫فً هذا المثال االرتفاع ‪ h = 5‬كل سطر ٌحوي ‪) -1‬رقم السطر(*‪ 3‬نجمة‪.‬‬
‫اطبع فراغات ح ّتى أوّ ل نجمة فً السطر ث ّم استخدم العبلقة السابقة لطباعة عدد النجم المطلوبة فً كل‬
‫سطر‪.‬‬

‫‪87‬‬
‫القسم الثاني‬

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

‫لألمام الشافعي‬

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

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

‫;]‪type name [elements‬‬


‫‪ :elements‬عدد العناصر‪.‬‬ ‫‪ :name‬اسم الصفوفة‪.‬‬ ‫نوع البٌانات الخاص بالمصفوفة‪.‬‬ ‫‪:type‬‬

‫فمثبل ٌمكن أن نخزن ‪ 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=array[2‬‬ ‫فإذا أردنا إسناد قٌمة العنصر الثالث للمتحول ‪ a‬نكتب‬

‫; ‪array[0]=10‬‬ ‫ولِوضع القٌمة ‪ 10‬فً العنصر األول نكتب‬

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

‫;]‪int array[5‬‬ ‫التصرٌح عن مصفوفة جدٌدة ٌبدأ بتحدٌد نوعها ‪//‬‬

‫;‪array[0] = 10‬‬ ‫الوصول إلى العنصر األول من المصفوفة ‪//‬‬

‫هناك عبارات أخرى صحٌحة مثل‬


‫;‪array [0] = a‬‬
‫;‪array [a] = 75‬‬
‫;]‪b = array [a+2‬‬
‫;‪array [array [a]] = array [2] + 5‬‬
‫مثال‬
‫‪// arrays example‬‬ ‫‪12206‬‬
‫>‪#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 [3][5‬‬ ‫)‪int a [15]; (3 * 5 = 15‬‬

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

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

‫‪#define WIDTH 5‬‬ ‫‪#define WIDTH 5‬‬


‫‪#define HEIGHT 3‬‬ ‫‪#define HEIGHT 3‬‬

‫;]‪int a [HEIGHT][WIDTH‬‬ ‫;]‪int a [HEIGHT * WIDTH‬‬


‫;‪int n,m‬‬ ‫;‪int n,m‬‬

‫)( ‪int main‬‬ ‫)( ‪int main‬‬


‫{‬ ‫{‬
‫)‪for (n=0;n<HEIGHT;n++‬‬ ‫)‪for (n=0;n<HEIGHT;n++‬‬
‫)‪for (m=0;m<WIDTH;m++‬‬ ‫)‪for (m=0;m<WIDTH;m++‬‬
‫{‬ ‫{‬
‫;)‪a[n][m]=(n+1)*(m+1‬‬ ‫;)‪a[n*WIDTH+m]=(n+1)*(m+1‬‬
‫}‬ ‫}‬
‫;‪return 0‬‬ ‫;‪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‬‬ ‫ث ّم نستدعً التابع كما ٌلً‬

‫مثال‬

‫‪// arrays as parameters‬‬ ‫‪5 10 15‬‬


‫>‪#include <iostream‬‬ ‫‪2 4 6 8 10‬‬
‫;‪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 + rand() % 6‬‬ ‫مثال‪:‬‬


‫إنّ القٌم المحتملة للمتغٌّر ‪ number‬هً ضمن المجال ]‪.[1,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: 50


your guess is too high!. try again: 25
your guess is too low!. try again: 37
your guess is too high!. try again: 31
your guess is too high!. try again: 28
congratulations. you guessed it!!!.
you tried 5 times to guess it

95
: ‫ ذات النوع الصحٌح قم بطباعتها ث ّم اطبع مجموع عناصرها‬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‬أوجد األخطاء فً كل من العبارات التالٌة‪:‬‬
‫)‪a‬‬ ‫بفرض ; } ‪int b[ 10 ] = { 0‬‬
‫) ‪for ( int i = 0; i<= 10; i++‬‬
‫;‪b[ i ] = 1‬‬

‫)‪b‬‬ ‫;] ‪int a[ 3‬‬ ‫بفرض‬


‫;‪cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl‬‬

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

‫)‪d‬‬ ‫;] ‪double d[ 2 ][ 10‬‬ ‫بفرض‬


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

‫‪ -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‬‬

‫مثال‬

‫‪// setting value to string‬‬ ‫‪Basil‬‬


‫>‪#include <iostream‬‬
‫;‪using namespace std‬‬
‫>‪#include <string‬‬
‫)( ‪int main‬‬
‫{‬
‫;]‪char MyName[20‬‬
‫;)"‪strcpy (MyName,"Basil‬‬
‫;‪cout << MyName‬‬
‫;‪return 0‬‬
‫}‬
‫استخدمنا المكتبة >‪ <string‬لنتمكن من التعامل مع التابع ‪strcpy‬‬
‫ٌمكن أن نكتب التابع ‪ setstring‬المإدي نفس الوظٌفة دون االستعانة بـ ‪strcpy‬‬
‫‪// setting value to string‬‬ ‫‪Basil‬‬
‫>‪#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‬‬

‫فمثبل ٌقوم هذا البرنامج بتكرار ماتكتبه على لوحة المفاتٌح‬


‫‪// cin with strings‬‬ ‫?‪What's your name‬‬
‫>‪#include <iostream‬‬ ‫‪Sameer‬‬
‫;‪using namespace std‬‬ ‫‪Hello Sameer.‬‬
‫)( ‪int main‬‬ ‫‪Which is your favourite‬‬
‫{‬ ‫‪book? The Holy Qura’an‬‬
‫;]‪char mybuffer [100‬‬ ‫‪I like The Holy Qura’an too.‬‬
‫;"‪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‬‬
‫‪// my first pointer‬‬ ‫‪a=10 , b=20‬‬
‫>‪#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‬‬
‫}‬

‫شر ‪ٌ ptr‬شٌر إلى ‪ a‬عن‬ ‫‪ ‬الحظ أنه تم تعدٌل قٌم ‪ a‬و ‪ b‬بشكل غٌر مباشر حٌث جعلنا المإ ّ‬
‫شر ‪ ptr‬وكذلك األمر بالنسبة لـ ‪.b‬‬ ‫طرٌق الرمز & ث ّم أسندنا القٌمة ‪ 10‬إلى ماٌشٌر إلٌه المإ ّ‬
‫ّ‬
‫شر خبلل البرنامج عناوٌن مختلفة حٌث استخدمنا المإشر ‪ ptr‬لٌشٌر إلى ‪a‬‬ ‫‪ ‬كما ٌمكن أن ٌؤخذ المإ ّ‬
‫ث ّم إلى ‪.b‬‬
‫مثال ‪2‬‬
‫‪// more pointers‬‬ ‫‪a=10 , b=20‬‬
‫>‪#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‬‬
‫;‪*p1 = 20‬‬ ‫القٌمة التً ٌشٌر إلٌها ‪// 32 = p1‬‬
‫;‪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‬‬

‫‪// more pointers‬‬ ‫‪10, 20, 30, 40, 50,‬‬


‫>‪#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‬‬‫شرات كما ٌلً )إذا كان المإ ّ‬
‫المإ ّ‬
‫‪*p‬‬ ‫]‪a[0‬‬
‫)‪*(p+1‬‬ ‫]‪a[1‬‬
‫)‪*(p+2‬‬ ‫]‪a[2‬‬
‫‪...‬‬ ‫‪...‬‬
‫)‪*(p+i‬‬ ‫]‪a[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‬‬

‫شر ‪ٌ p‬شٌر إلى أول‬ ‫فً هذه الحالة ت ّم حجز حجم ثابت من الذاكرة لتخزٌن السلسة "‪ "hello‬وت ّم جعل المإ ّ‬
‫رمز )‪ (char‬لمجموعة الحجرات الذاكرٌّة التً ت ّم حجزها أي أنّ ‪ٌ p‬شٌر إلى الحجرة التً تحوي الحرف '‪'h‬‬
‫فإذا فرضنا أنّ "‪ُ "hello‬خ ّزنت فً العنوان ‪ 2813‬وما بعده فإنّ الذي ت ّم ٌُلخصه الشكل التالً‪:‬‬

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

‫ٌمكن أن نع ّرف مصفوفة مإ ّ‬


‫شرات كما ٌلً ‪:‬‬
‫;]‪type* name[ELEMENTS‬‬

‫مثال ‪:‬‬
‫;]‪char* cars[3‬‬ ‫مصفوفة ‪ 4‬مإ ّ‬
‫شرات على سبلسل ‪//‬‬

‫;"‪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‬إلى المإشر معنى ذلك أننا نجعله ٌشٌر إلى العنصر التالً لنفس‬
‫شر حسب النوع‪.‬‬‫النوع الذي عرفناه أي ٌضاف الحجم بالباٌت إلى المإ ّ‬

‫شر ‪mychar‬‬ ‫حجم النوع )‪ 2 (char‬باٌت لذلك تم إضافة ‪ 2‬إلى المإ ّ‬


‫حجم النوع )‪ 2 (short‬باٌت لذلك تم إضافة ‪ 2‬إلى المإ ّ‬
‫شر ‪myshort‬‬
‫شر ‪mylong‬‬ ‫حجم النوع )‪ 4 (long‬باٌت لذلك تم إضافة ‪ 4‬إلى المإ ّ‬

‫سٌحدث نفس األمر تماما إذا كتبنا‬


‫;‪mychar = mychar + 1‬‬
‫;‪myshort = myshort + 1‬‬
‫;‪mylong = mylong + 1‬‬

‫‪::‬‬
‫من المهم التنبٌه إلى أنّ معامبل الزٌادة )‪ (++‬والنقصان )‪ (--‬لهما أولوٌّة على معامل المرجع )*( لذلك فإنّ‬
‫التعابٌر التالٌة ربما تسبب التباس فً فهمها‬
‫;‪*p++‬‬
‫;‪*p++ = *q++‬‬

‫شر ‪ p‬ولٌس القٌمة التً ٌشٌر‬ ‫التعبٌر األول مكافا لـ )‪ *(p++‬وهو ٌقوم بزٌادة ‪ 2‬إلى العنوان الذي ٌحوٌه المإ ّ‬
‫إلٌها وبالتالً فإنّ القٌمة الجدٌدة التً ٌشٌر إلٌها ‪ 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‬‬

‫مالحظة‬

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

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

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 8
#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
int main ()
{
int m,n;
m = operation(7, 5, addition);
n = operation(20, m, minus);
cout <<n;
return 0;
}

subtraction ‫ أسندنا التابع‬.int ‫ ٌقبل معاملٌن من النوع‬int ‫شر عام على تابع من النوع‬
ّ ‫ هو مإ‬minus
‫ فً سطر التعرٌف نفسه‬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‬‬ ‫لتحرٌر الذاكرة المحجوزة لعدة عناصر )مصفوفة(‪.‬‬

‫مثال‪:‬‬

‫‪//calculate average using dynamic memory‬‬ ‫‪enter the number of courses: 7‬‬
‫>‪#include <iostream‬‬ ‫‪mark 1= 91‬‬
‫>‪#include<stdlib.h‬‬ ‫‪mark 2= 78‬‬
‫;‪using namespace std‬‬ ‫‪mark 3= 77‬‬
‫‪mark 4= 68‬‬
‫‪mark 5= 83‬‬
‫)( ‪int main‬‬ ‫‪mark 6= 73‬‬
‫{‬ ‫‪mark 7= 81‬‬
‫;‪int n,i,sum=0‬‬ ‫‪average= 78.7143‬‬
‫;" ‪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‬‬ ‫فً حال لم تكن معرّ فة فٌمكن أن تع ّرفها بنفسك كما ٌلً‪:‬‬
‫شرات‪ ,‬ولكن ‪ NULL‬مستخدمة بشكل أكبر وهً أكثر‬ ‫ال ٌوجد فارق أن تضع ‪ 1‬أو ‪ 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 Enter title: java how to program
#include <iostream> Enter year: 1997
using namespace std; Enter title: eat, pray, love
#include <stdlib.h> Enter year: 2006
Enter title: advanced memory
#define N_BOOKS 5 Enter year: 2005
Enter title: being logical
struct book { Enter year: 2004
char title [50]; Enter title: c++ how to program
int year; Enter year: 2005
} books [N_BOOKS];
You have entered these movies:
void printBook (book mybook); java how to program (1997)
eat, pray, love (2006)
int main () advanced memory (2005)
{ being logical (2004)
char buffer [50]; c++ how to program (2005)
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
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 Enter title: c++ how to program
#include <iostream> Enter year: 2005
using namespace std;
#include <stdlib.h> You have entered:
struct book { c++ how to program (2005)
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
‫شرات على‬ ‫شرات على التراكٌب أو المإ ّ‬
‫المعامل )>‪ (-‬هو معامل مرجعً ٌستخدم خصٌصا مع المإ ّ‬ ‫‪‬‬
‫األصناف للوصول إلى الحقول الموجودة فٌها وهو ٌلغً الحاجة الستخدام األقواس فً كل مرة نرٌد‬
‫أن نصل إلى حقل ما فً تركٌب ما‪.‬‬

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

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

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

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

‫ٌلخص الحاالت الممكنة للمإ ّ‬


‫شرات والتراكٌب‬ ‫الجدول التالً ّ‬

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


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

‫‪(*pbook).title‬‬ ‫العنصر ‪ title‬من التركٌب المشار إلٌه بالمإ ّ‬


‫شر‬ ‫‪pbook->title‬‬
‫‪pbook‬‬
‫)‪*(pbook.title‬‬ ‫القٌمة المشار إلٌها بالعنصر ‪ title‬من التركٌب‬ ‫‪*pbook.title‬‬
‫‪pbook‬‬

‫التراكٌب المتداخلة‬
‫تراكٌب أخرى كما فً المثال التالً‪:‬‬
‫َ‬ ‫ٌمكن أن تكون التراكٌب حقوال موجودة داخل‬

‫{‪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‬التً ُتستخدم كما ٌلً ‪:‬‬

‫‪Typedef‬‬ ‫‪existing_type‬‬ ‫;‪new_type_name‬‬

‫‪ :existing_type‬هو النوع األصلً المعرف فً ‪ C++‬أو أي نوع مع ّرف مسبقا‪.‬‬


‫‪ :new_type_name‬هو اسم النوع الجدٌد الذي سنعرفه‪ .‬مثبل ‪:‬‬

‫‪typedef‬‬ ‫;‪char C‬‬


‫‪typedef‬‬ ‫;‪unsigned int WORD‬‬
‫‪typedef‬‬ ‫;‪char * string_t‬‬
‫‪typedef‬‬ ‫;]‪char field [50‬‬

‫هنا عرّ فنا أربعة أنواع جدٌدة هً ‪ 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‬المعرّ ف بالشكل ‪:‬‬

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

‫‪ :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‬وضع افتراضً‬
‫خاص ٌختلف من صف إلى آخر كما فً الجدول ‪:‬‬

‫الوضع االفتراضً للفتح‬ ‫الصف‬


‫‪ios::out | ios::trunc‬‬ ‫‪ofstream‬‬
‫‪ios::in‬‬ ‫‪ifstream‬‬
‫‪ios::in | ios::out‬‬ ‫‪fstream‬‬

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

‫بما أنّ العملٌة األولى التً تنفذ على الكابن من الصفوف السابقة هً عملٌة فتح ملف فإنّ كبل من هذه‬ ‫‪‬‬
‫الصفوف الثبلثة ٌحتوي على مشٌد )بانً( ٌقوم باستدعاء التابع ‪ open‬بنفس البارامترات‪ ,‬لذلك ٌمكننا‬
‫أن نعرّ ف الكابن ونستدعً التابع بسطر واحد كما ٌلً‪:‬‬

‫;)‪ofstream file ("example.bin", ios::out | ios::app | ios::binary‬‬

‫ٌمكنك التحقق من أنّ الملف قد فُتح بشكل صحٌح باستدعاء التابع العضوي )(‪is_open‬‬

‫;)(‪bool is_open‬‬
‫هذا التابع ٌُعٌد ‪ true‬إذا ت ّم ربط الكابن بالملف بشكل صحٌح ّ‬
‫وإال فإ ّنه ٌُعٌد ‪.false‬‬

‫إغالق ملف‬

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

‫بعد استدعاء هذا التابع ٌصبح الكابن ‪ stream‬جاهزا لفتح ملف آخر‬
‫‪ ‬فً حالة هدم الكابن وهو ماٌزال مرتبط بالملف فإنّ الهادم ٌستدعً التابع ‪ close‬تلقابٌا‪.‬‬

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

‫الصفوف ‪ ofstream‬و ‪ ifstream‬و ‪ fstream‬مشتقة من الصفوف ‪ ostream‬و ‪ istream‬و‬


‫‪ iostream‬لذلك فإنّ كابنات الـ ‪ٌ fstream‬مكنها أن تستخدم عناصر الصفوف األصلٌة لتصل إلى‬
‫المعطٌات‪ ,‬أي ٌمكننا أن نستخدم ‪ cin‬و ‪ cout‬مع الكابنات التً نعرّ فها كما فً المثال التالً حٌث نستخدم‬
‫معامل اإلدخال << الذي ت ّم إعادة تحمٌله‬

‫‪// writing on a text file‬‬ ‫‪file example.txt‬‬


‫>‪#include <iostream‬‬
‫>‪#include <fstream‬‬ ‫‪This is a line.‬‬
‫;‪using namespace std‬‬ ‫‪This is another line.‬‬
‫{ )( ‪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‬‬ ‫‪This is a line.‬‬


‫>‪#include <iostream‬‬ ‫‪This is another line.‬‬
‫>‪#include <fstream‬‬
‫>‪#include <stdlib.h‬‬
‫;‪using namespace std‬‬

‫{ )( ‪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‬‬

‫جمٌع كابنات التدفق الخاصة بالدخل والخرج تحوي مإ ّ‬


‫شرا واحدا على األقل‪:‬‬

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

‫‪228‬‬
‫ٌمكن التعامل مع هذه المإ ّ‬
‫شرات من خبلل التوابع التالٌة‪:‬‬

‫)(‪ tellg‬و )(‪tellp‬‬


‫هذان التابعان ال ٌقببلن وسطاء وٌعٌدان قٌمة من النوع ‪ pos_type‬وهً قٌمة من النوع الصحٌح )‪(integer‬‬
‫شر ‪) put‬فً حالة التابع )(‪.(tellp‬‬ ‫شر ‪) get‬فً حالة التابع )(‪ ( tellg‬أو مكان المإ ّ‬
‫تمثل المكان الحالً للمإ ّ‬
‫)(‪ 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‬إلى نهاٌة الملف‬

‫المثال التالً ٌستخدم التوابع المذكورة لحساب حجم ملف ثنابً‪:‬‬

‫‪// obtaining file size‬‬ ‫‪size of example.txt is 40 bytes.‬‬


‫>‪#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‬لن تن ّفذ‪.‬‬
‫مثال ‪:‬‬
‫‪// exceptions‬‬ ‫‪Exception: Out of range‬‬
‫>‪#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 Exception: index 10 is out of range


#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;
}

: ‫فً هذا المثال ٌوجد احتماالن لحدوث استثنابٌن مختلفٌن‬

‫ عندها سٌت ّم‬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‬وهو من نوع الصفّ )أل ّنه اش ُت َّق منه(‪ٌ .‬مكن‬
‫توضٌح هذه المسؤلة من خبلل المثال التالً‪:‬‬

‫; ‪CRectangle rect‬‬ ‫‪CRectangle‬‬ ‫;‪rect‬‬

‫; ‪int a‬‬ ‫‪int‬‬ ‫; ‪a‬‬

‫‪ int‬هو اسم الصفّ )النوع(‪ ,‬بٌنما ‪ a‬هو اسم الكابن ال ُم ّ‬


‫شتق من الصفّ )النوع( ‪.int‬‬
‫أثناء كتابة التعلٌمات داخل البرنامج ٌمكننا أن نشٌر إلى أيّ عضو عام )من المستوى ‪ (public‬للكابن ‪ rect‬كما‬
‫العضو )كما فعلنا مع ‪struct‬‬
‫ِ‬ ‫اسم‬
‫لو كان تابعا أو متغٌّرا عادٌّا‪ ,‬وذلك فقط بوضع اسم الكابن متبوعا بنقطة ث ّم ِ‬
‫فً ‪ .(C‬مثال‪:‬‬

‫; )‪rect.set_value(3,4‬‬
‫;)(‪myarea = rect.area‬‬
‫لكن ال ٌمكننا أن نفعل ذلك مع العضوٌن ‪ x, y‬أل ّنهما من المستوى الخاص )‪ (private‬أي أ ّنه ال ٌمكن الوصول‬
‫إلٌهما ّإال من داخل الصفّ ‪ CRectangle‬الذي ُعرِّ فا داخله‪ .‬إلٌك اآلن المثال كامبل‪:‬‬

‫‪// classes example‬‬ ‫‪area: 12‬‬


‫>‪#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‬أي أ ّنه ال ٌمكن‬
‫الوصول إلٌهما ّإال من داخل الصفّ كما أسلفنا سابقا‪.‬‬
‫مثال ٌوضح كٌف ٌمكننا باستخدام هذا المعامل الوصول إلى المتغٌّرات الشاملة فً برنامجنا‪.‬‬

‫‪// example on Scope Operator ::‬‬ ‫‪150‬‬ ‫‪0‬‬


‫>‪#include <iostream‬‬ ‫‪0‬‬ ‫‪0‬‬
‫;‪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‬‬

‫‪// class example‬‬ ‫‪rect area: 12‬‬


‫>‪#include <iostream‬‬ ‫‪rectb area: 30‬‬
‫;‪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‬‬ ‫‪rect area: 12‬‬
‫>‪#include <iostream‬‬ ‫‪rectb area: 30‬‬
‫;‪using namespace std‬‬

‫{ ‪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‬‬

‫الهادم ٌجب أن ٌؤخذ نفس اسم الصفّ مسبوقا بالرمز ~ كما وٌجب ّأال ٌعٌد الهادم قٌمة‪.‬‬

‫ٌستخدم الهادم عادة لتحرٌر الذاكرة ‪-‬التً ٌحجزها الكابن أثناء تنفٌذه‪ -‬فً اللحظة التً ٌنهً فٌها الكابن عمله‪.‬‬

‫‪// example on constructors and destructors‬‬ ‫‪rect area: 12‬‬


‫>‪#include <iostream‬‬ ‫‪rectb area: 30‬‬
‫;‪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‬‬
‫}‬
‫ٌجب أن تعلم أنّ المشٌّدٌن االفتراضٌن ٌكونان موجودٌن عندما ال تقوم بالتصرٌح عن أيِّ مشٌّد فً الصفّ و‬
‫لذلك عندما تضٌف مشٌّدا ما إلى الصفّ فإنّ هذٌن المشٌّدٌن لن ٌكونا موجودٌن وفً حال رغبت باإلبقاء على‬
‫أحدهما فعلٌك أن تصرّ ح عنه بنفسك‪.‬‬

‫‪// overloading class constructors‬‬ ‫‪rect area: 12‬‬


‫>‪#include <iostream‬‬ ‫‪rectb area: 25‬‬
‫;‪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‬تؤمّل البرنامج التالً‪:‬‬
‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬
‫)(‪int main‬‬
‫{‬
‫;"‪cout<<"Sweat plus sacrifice equals success.‬‬
‫;‪return 0‬‬
‫}‬
‫اجعل البرنامج ٌطبع الشكل التالً‪:10‬‬
‫‪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‬ولكً نشٌر بشكل مباشر إلى عضو ما من‬ ‫شر السابق مإ ّ‬‫ٌمثل المإ ّ‬
‫ضح بعض العبارات الممكنة‪.‬‬ ‫أعضاء هذا الكابن ٌنبغً أن نستخدم المعامل >‪ -‬والمثال التالً ٌو ّ‬

‫‪// pointer to classes example‬‬ ‫‪a area: 2‬‬


‫>‪#include <iostream‬‬ ‫‪*b area: 12‬‬
‫;‪using namespace std‬‬ ‫‪*c area: 2‬‬
‫‪d[0] area: 30‬‬
‫{ ‪class CRectangle‬‬
‫‪d[1] area: 56‬‬
‫;‪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‬‬ ‫‪&x‬‬
‫العضو ‪ y‬من المإ ّشر ‪x‬‬ ‫‪x.y‬‬
‫العضو ‪ y‬من الكابن المشار إلٌه بالمإ ّشر ‪x‬‬ ‫‪(*x).y‬‬
‫العضو ‪ y‬من الكابن المشار إلٌه بالمإ ّشر ‪x‬‬ ‫‪x->y‬‬
‫شر‬ ‫الكابن األول الذي ٌشٌر إلٌه المإ ّ‬ ‫]‪x[0‬‬
‫شر‬ ‫الكابن الثانً الذي ٌشٌر إلٌه المإ ّ‬ ‫]‪x[1‬‬
‫الكابن رقم ‪ n‬الذي ٌشٌر إلٌه المإ ّشر‬ ‫]‪x[n‬‬

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

‫‪243‬‬
‫الكلمة المفتاحٌة ‪this‬‬
‫اٌظف اٌز‪ُٕ٠ ٞ‬فّز ؽبٌ‪١‬بً‪ ٟ٘ٚ .‬رّضًّ ِإ ّششاً‬
‫ّ‬ ‫ّ‬
‫اٌظف رش‪١‬ش ئٌ‪ ٝ‬اٌؼٕ‪ٛ‬اْ ف‪ ٟ‬اٌزاوشح ٌٍىبئٓ ِٓ ٘زا‬ ‫٘زٖ اٌىٍّخ داخً‬
‫ل‪ّ١‬زٗ دائّب ً ػٕ‪ٛ‬اْ ٘زا اٌىبئٓ‪.‬‬

‫عضو ما من الكابن هو الكابن نفسه‪.‬‬


‫ٍ‬ ‫ٌمكن أن تستخدم هذه الكلمة لمعرفة فٌما إذا كان الوسٌط الممرر إلى ٍ‬
‫تابع‬
‫مثال‪:‬‬

‫‪// this‬‬ ‫‪yes, &a is b‬‬


‫>‪#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 -858993460
#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;
}
x ٛ‫ّش اٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ل‬ٟ٘ ً‫طجغ ٘زا اٌجشٔبِظ قٍمتً عشىائٍّت‬١‫مخ األِش ع‬١‫ ؽم‬ٟ‫ما هً وتٍجت هزا انبروامج ؟ ف‬
‫ّش‬١‫ّخ اٌّزغ‬١‫ ؟ ٘زا اٌزبثغ لبَ ثاعٕبد ل‬set_x(int x) ‫نكه كٍف؟ و مانزي فعهه انتابع‬ٚ .‫ّخ‬١‫ّخ ل‬٠‫ٗ أ‬١ٌ‫ ٌُ رُغٕذ ئ‬ٞ‫اٌز‬
ّ ‫ اٌّشىٍخ ٌزٌه‬ٟ٘ ٖ‫ؾ؟ ٘ز‬١‫ع‬ٌٛ‫ّش ا‬١‫ اٌّزغ‬ٛ٘ ‫ّب‬ّٙ٠‫أ‬ٚ ٛ‫ّش اٌؼؼ‬١‫ اٌّزغ‬ٛ٘ ٓ٠‫ّش‬١‫ اٌّزغ‬ٞ
ْ‫فا‬ ّ ‫ ٌىٓ أ‬x ‫ّش‬١‫ اٌّزغ‬ٌٝ‫ ئ‬x
ّ
‫طجغ اٌزبثغ‬١‫ّزٗ عشىائٍّت ٌزٌه ع‬١‫ثّب أْ ل‬ٚ ٗ‫ ٔفغ‬ٌٝ‫ ئ‬x ٛ‫ّشاٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ئعٕبد ل‬ٟ٘ ‫ّخ‬١ٍ‫ؼزجش ٘زٖ اٌزؼ‬٠ ُ‫اٌّزشع‬
:ٌٟ‫ اٌّضبي اٌزب‬ٟ‫ نكه ما هى انحم؟ سالت اٌفشق ف‬.‫ّخ‬١‫ائ‬ٛ‫ اٌؼش‬x ٛ‫ّش اٌؼؼ‬١‫ّخ اٌّزغ‬١‫ ل‬print
// this keyword example 5
#include <iostream>
using namespace std;
class Example
{
int x ;
public:
void set_x(int x) { this->x = x; }
void printX(){cout<< x << endl ;}
};

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 a(3,1) + b(1,2) = c(4,3)


#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;
}

: ّ‫حٍث أن‬

ّ
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‬غزخذِٗ ف‪ ٟ‬ئؽظبء ػذد اٌىبئٕبد اٌز‪ ٟ‬ع‪١‬زُ ئٔشبؤ٘ب‬
‫(٘ذِ‪ٙ‬ب) خالي اٌجشٔبِظ‪:‬‬

‫‪// static members in classes‬‬ ‫‪7‬‬


‫>‪#include <iostream‬‬ ‫‪6‬‬
‫;‪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‬لتقوم بالتواصل مع بٌانات‬
‫الصفّ ‪ .‬لنفترض أن لدٌنا المثال التالً ‪:‬‬

‫>‪#include<iostream‬‬ ‫‪Enter Your age(1 to 110):21‬‬


‫;‪using namespace std‬‬ ‫‪Your age is: 21‬‬
‫‪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> Enter Your age(1 to 110):21


using namespace std; done
class Person Your age is: 21
{
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;
}

‫ أضف المشٌّد التالً إلى البرنامج السابق )ال تنس أنّ المشٌّد العادي لن ٌكون موجودا بعدها‬: ‫ استخدام المش ٌّد ات‬-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 ٟ‬ص ُّ رزوش ٘زٖ اٌىٍّخ أِبِٗ‪ِ .‬ضبي‪:‬‬

‫‪// friend functions‬‬ ‫‪24‬‬


‫>‪#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 16
#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;
}

ّ‫ لذلك فإن‬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‬وسنتعرّ ف‬
‫على فابدته بعد المثال‪:‬‬
‫‪// derived classes‬‬ ‫‪20‬‬
‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪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‬‬

‫الحظ الجدول التالً الذي ٌح ِّدد الفرق بٌن مع ّرفات الوصول‪.‬‬

‫‪private‬‬ ‫‪protected‬‬ ‫‪public‬‬ ‫إمكانٌة الوصول إلى‬


‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫صف‬
‫األعضاء من نفس ال ّ‬
‫‪‬‬ ‫‪‬‬ ‫‪‬‬ ‫األعضاء من الصفوف المشتقة‬

‫فً مثالنا ‪ ,‬األعضاء الموروثة فً ك ّل من الص ّفٌن ‪ 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‬‬

‫‪// constructors and derivated classes‬‬ ‫‪mother:‬‬ ‫‪no‬‬ ‫‪parameters‬‬


‫>‪#include <iostream‬‬ ‫‪daughter: int parameter‬‬
‫;‪using namespace std‬‬
‫{ ‪class mother‬‬ ‫‪mother:‬‬ ‫‪int‬‬ ‫‪parameter‬‬
‫‪public:‬‬ ‫‪son: int parameter‬‬
‫)( ‪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‬‬
‫إلٌك المثال كامبل‪:‬‬

‫‪// multiple inheritance‬‬ ‫‪20‬‬


‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪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 20
#include <iostream> 10
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
‫} ;)‪{ 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‬‬
‫}‬

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

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


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

‫إذن األعضاء من النوع ‪ virtual‬هً األعضاء المشتركة التً نرغب بؤن ترثها كل الصفوف المشتقة من‬
‫الصفّ األساسً والتً سنعٌد كتابة تعلٌماتها )‪ (overriding‬داخل بعض أو كل الصفوف التً ترث الصفّ‬
‫األساسً‪.‬‬

‫و بعد التعدٌل ٌصبح المثال بالشكل‪:‬‬


‫‪// virtual members‬‬ ‫‪20‬‬
‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪using namespace std‬‬ ‫‪0‬‬
‫{ ‪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‬فً ك ّل‬ ‫)(‪ area‬فً الصفّ ‪ CPolygon‬ث ّم استخدمت مإ ّ‬
‫شر سٌشٌر إلى التابع فً الصفّ األساسً والذي ٌعٌد القٌمة ّ كما هو واضح‬ ‫من الكابنٌن ‪ rect , trgl‬فإنّ المإ ّ‬
‫من تعرٌفه أمّا الكابن ‪ poly‬فهو أصبل من النوع ‪ CPolygon‬والتابع المعرّ ف فٌه ٌعٌد ‪ 0‬دابما‪.‬‬

‫إنّ ما تفعله هذه الكلمة هو أ ّنها تسمح باستدعاء العضو من الصفّ المشتق والذي ٌمتلك نفس اسم العضو فً‬
‫الصفّ األساسً عندما ٌستخدم المإ ّ‬
‫شر‪ ,‬كما فً المثال السابق‪.‬‬

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

‫ومثال ذلك لو افترضنا أنّ لدٌنا ص ّفا أساسٌّا للمركبات ث ّم اشت ّقٌنا منه ص ّفا للسٌارة وآخر للدراجة النارٌة‪ ,‬معلو ٌم‬
‫أنّ ك ّل المركبات تستخدم الوقود لكً تسٌر لذلك سنعرّ ف التابع )(‪ fuel‬فً الصفّ األساسً لٌحسب كمٌة الوقود‬
‫البلزمة لقطع مسافة معٌّنة لكن هل تستهلك السٌارة نفس الكمٌة من الوقود التً تستهلكها الدراجة لتقطعا‬
‫نفس المسافة؟ بالطبع ال و هذا االختبلف ٌجعل من األفضل أن نستخدم الكلمة ‪ virtual‬لنعٌد قٌادة التابع‬
‫)(‪ fuel‬ضمن الصفّ المشتق كلّما دَ َعت الحاجة لذلك‪.‬‬

‫‪261‬‬
// virtual members Vehikle need: 2 leters of fuel
#include <iostream > in 10 KM
using namespace std; Car need: 1 leters of fuel in 10
class Vehicle KM
{ MotoCicle need: 0.666667 leters
protected: of fuel in 10 KM
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
‫الصفوف األساس ٌّة المجردة ‪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‬ال تحتوي على تعلٌمات بداخلها وهذا ٌجعل من‬
‫المستحٌل إنشاء ُنسخ من الصفّ المجرّ د إذ أنّ بعض أعضابه ال تمتلك تعرٌفات كاملة لوظابفها‪ّ ,‬إال أ ّنه ٌمكننا‬
‫أن نشٌر إلى الصفّ الذي ٌرث الصفّ األساسً المجرّ د باستخدام مإ ّ‬
‫شر كما فً المثال التالً‪:‬‬
‫‪// virtual members‬‬ ‫‪20‬‬
‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪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 = &rect;
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 20
#include <iostream> 10
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
‫{ )( ‪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‬‬
‫‪// function template‬‬ ‫‪6‬‬
‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪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‬‬

‫‪// function template‬‬ ‫‪6‬‬


‫>‪#include <iostream‬‬ ‫‪10‬‬
‫;‪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 100
#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;
}

:template <class T> ‫ بالتعلٌمة‬getmax() ‫ال حظ كٌف سبقنا سطر تضمٌن )كتابة تعلٌمات( التابع‬

template <class T>


T pair<T>::getmax )( {…}
‫ أمّا‬template<…> ‫ فوجب علٌنا أن نسبقه بالسابقة‬prototype ً‫وهذا أل ّننا استخدمنا التصرٌح المبدب‬
.‫ فبل داعً من ذكر هذه السابقة أمامها‬inline ّ‫األعضاء المصرّ ح عنها كلٌّا داخل الصف‬

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


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

// Template specialization 25
#include <iostream> 0
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
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> // The most usual: one class parameter.


template <class T, class U> // Two class parameters.
template <class T, int N> // A class and an integer.
template <class T = char> // With a default value.
template <int Tfunc (int)> // A function as parameter.

26:
‫الفصل العصرون ‪:‬‬

‫تم ّكننا فضاءات األسماء من تجمٌع ع ّدة صفوف عا ّمة فً مجموعة واحدة‪ ,‬من الكابنات و)أو( التوابع تحت اسم‬
‫واحد لك ّل هذه المجموعة حٌث تصبح كلُّها أعضاء داخل المدى الذي ٌش ّكل فضاء االسم‪ ,‬وٌكون ك ّل عضو منها‬
‫قادرا على الوصول إلى األعضاء األخرى‪.‬‬
‫الشكل الذي ٌمكننا من خبلله التصرٌح عن فضاء اسم جدٌد هو ‪:‬‬
‫‪namespace identifier‬‬
‫{‬
‫‪namespace-body‬‬
‫}‬
‫حٌث أنّ ‪:‬‬
‫‪ :identifier‬هو أي اسم تختاره أنت شرٌطة أن ٌكون صحٌحا )ٌخضع لقواعد تسمٌة المتغٌّرات(‪.‬‬
‫‪ :namespace-body‬مجموعة من الصفوف و)أو( الكابنات و)أو( التوابع‪.‬‬
‫مثال ‪:‬‬
‫‪namespace general‬‬
‫{‬
‫;‪int a, b‬‬
‫;‪class S‬‬
‫;}…{()‪void B‬‬
‫}‬
‫و لكً نصل إلى أحد أعضاء فضاء االسم ‪ general‬من خارج الفضاء علٌنا أن نستخدم معامل المدى ‪::‬‬

‫مثال‪:‬‬
‫;‪general::a‬‬
‫;)(‪general::B‬‬
‫الوظٌفة التً ٌشغلها فضاء االسم مفٌدة خصوصا فً الحاالت التً ٌُح َتمل فٌها وجود أعضاء أو كابنات شاملة‬
‫تمتلك نفس االسم داخل نفس البرنامج ما ٌعنً أنّ علٌنا أن نعٌد تسمٌتها لكً نستطٌع أن نتعامل معها كلّها ّإال أنّ‬
‫فضاءات األسماء تق ّدم ّ‬
‫حبل مناسبا لهذه المشكلة‪ .‬راقب المثال التالً ‪:‬‬

‫‪// namespaces‬‬ ‫‪5‬‬


‫>‪#include <iostream‬‬ ‫‪3.1416‬‬
‫;‪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‬‬


‫مثال ‪:‬‬

‫‪// using namespace example‬‬ ‫‪3.1416‬‬


‫>‪#include <iostream‬‬ ‫‪6.2832‬‬
‫;‪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‬تخضع لقاعدة المدى المعروفة من قبل‪.‬‬


‫ت فً مكان التصرٌح‬‫حٌث أنّ مدى هذه التعلٌمة هو األقواس }{ التً كتبت فٌها‪ .‬أ ّما إن ُك ِت َب ْ‬
‫عن المتغٌّرات الشاملة فإ ّنها ستكون ذات مدى شامل لك ّل البرنامج‪.‬‬

‫مثال ‪:‬‬
‫‪// using namespace example‬‬ ‫‪5‬‬
‫>‪#include <iostream‬‬ ‫‪3.1416‬‬
‫;‪using namespace std‬‬
‫‪namespace first‬‬
‫} ;‪{ int var = 5‬‬
‫‪namespace second‬‬
‫} ;‪{ double var = 3.1416‬‬
‫{ )( ‪int main‬‬
‫{‬
‫;‪using namespace first‬‬ ‫‪// scope of‬‬
‫;‪cout << var << endl‬‬ ‫‪// namespace first‬‬
‫}‬
‫{‬
‫;‪using namespace second‬‬ ‫‪// scope of‬‬
‫;‪cout << var << endl‬‬ ‫‪// namespace second‬‬
‫}‬
‫} ;‪return 0‬‬

‫‪272‬‬
std ‫الفضاء‬

‫ حٌث ت ّم تضمٌن كل صفوف‬.‫ القٌاسٌة نفسها‬C++ ‫ وهو مكتبة‬,‫واح ٌد من أفضل األمثلة حول فضاءات األسماء‬
.std ‫ القٌاسٌة فً الفضاء‬C++ ‫و كابنات وتوابع مكتبة‬

: ‫ِضبي‬

// ANSI-C++ compliant hello world Hello world in ANSI-C++


#include <iostream>
using namespace std;
int main ()
{
std::cout << "Hello world in ANSI-C++\n";
return 0;
}

.‫ رزّىٓ ِٓ اٌزؼبًِ ِغ أػؼبء ٘زا اٌفؼبء‬ٟ‫ ٌى‬ٜ‫غت أْ رغزخذَ اعُ اٌفؼبء ص ُّ ِؼبًِ اٌّذ‬٠ :‫مالحظة‬
ُ‫ ٌٕزّىٓ ِٓ العزغٕبء ػٓ روش اع‬using namespace std ; ‫ّخ‬١ٍ‫ّىٕٕب أْ ٔغزخذَ اٌزؼ‬٠ ّٗٔ‫ّئل أ‬
: ٍٟ٠ ‫ب ِغ أػؼبء ٘زا اٌفؼبء وّب‬ٙ١‫ ِٓ أعً وً ِشّح عٕزؼبًِ ف‬ٜ‫ ِؼبًِ اٌّذ‬ٚ ‫اٌفؼبء‬

// ANSI-C++ compliant hello world (II) Hello world in ANSI-C++


#include <iostream>
using namespace std;

int main ()
{
cout << "Hello world in ANSI-C++\n";
return 0;
}

‫ مارا تجذ؟ ما هى انسبب؟‬.‫ ص ُّ ش ّغً اٌجشٔبِظ‬using namespace std ; ‫ّخ‬١ٍ‫ً اٌزؼ‬٠‫عشّة أْ رض‬

273
274
‫حلول التنارين غري احمللولة‬
‫بنية الربنامج يف لغة الـ ‪C++‬‬

‫‪.2‬‬
‫)(‪main‬‬ ‫‪‬‬
‫بفاصلة منقوطة ) ; (‬ ‫‪‬‬
‫تعلٌق‪.‬‬ ‫‪‬‬
‫التعلٌق هو قطعة من الشٌفرة مهملة من قبل المترجم‪.‬‬ ‫‪‬‬
‫إنهاء البرنامج بطرٌقة سلٌمة‪.‬‬ ‫‪‬‬
‫القوسٌن }{‬ ‫‪‬‬
‫تضمٌن الملف المصدري >‪ <iostream‬الستخدام التعلٌمات الموجودة فٌه‪.‬‬ ‫‪‬‬
‫‪.3‬‬
‫;"!‪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) ; -2
d %= 2 * c / ++b ; 3
a = d - (b += (c * (1-a))); 0
e = !e 0
r = e || t 0
t = e && r 0
e = !( (e && r ) || (e && t ) ) ; 1

.3
‫العبارة‬ ‫الجواب‬
x=7+3*6/2-1; 15
x = 2 % 2 + 2 * 2 -2 / 2 ; 3
x=(3*9*(3+(9*3/(3)))); 324
c = 2*b - 3/d + a++; 1

.4

cout<< ++a ; 1
cout<< a++ ; 0
cout<< a++ / 2 ; 0
cout<< ++a / 2 ; 0

27:
‫بنى التخكه‬

.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 ) while ( c <= 5 )
{ { product *= c;
product *= c; ++c;
++c; }
if ( gender == 1 ) if ( gender == 1 )
cout<< "Woman" ; cout<< "Woman" ;
else; else // ‫ال ٌوجد فاصلة منقوطة هنا‬
cout<<"man"; cout<<"man";
while ( z >= 0 ) while ( z >= 0 )
sum += z; {
sum += z;
z--;
}
// nested loop // nested loop
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int main () int main ()
{ {
int j = 1; int j = 1;
for( int i = 1 ; i<=3 ; for( int i = 1 ; i<=5 ; i++)
i++) {while( j<=i )
while( j<i ) {cout <<"* " ;
{ j++;
cout <<"* " ; }
j++; cout<<endl;
} j = 1;}
return 0; return 0;
} }

281
.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> 3 4 5 6
using namespace std; 4 5 6 7
int main () 5 6 7 8
6 7 8 9
{ for(int i = 3;i<=6;i++)
{ for(int j = i;j<i+4;j++)
cout<<j<<" ";
cout<<"\n";
}
return 0;
}
#include <iostream> 3
using namespace std; 4 5
int main () 5 6 7
6 7 8 9
{ 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
#include <iostream> 3 4 5 6
using namespace std; 5 6 7
int main () 7 8
9
{
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> 6
using namespace std; 6 7
int main () 6 7 8
6 7 8 9
{
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> 3 4 5 6
using namespace std; 4 5 6
int main () 5 6
6
{
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> 3 4 5 6
using namespace std; 4 7
int main () 5 8
6 7 8 9
{
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
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 > #include<iostream >


using namespace std; using namespace std;
void main() void main()
{ { double x,p=1.0,y;
double x,p=1.0,y; cout<<"Enter x, y: ";
cout <<"Enter x, y: "; cin>>x>>y;
cin >> x >> y; if(y>=0){
if(y>=0){ int i = 1;
for(int i = 1; i<=y;i++) while( i<=y )
p *=x; { p *=x;
cout<< p << endl; i++;
} }
} cout<< p << endl;
}
}

285
.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 ‫هذ التابع من النوع‬
{ return statement; ‫ٌحتوي على التعلٌمة‬
int sum = a + b; return sum; // return a+b;
}
int divide(int a , int b) ‫ و هو ٌعٌد قٌمة من النوع‬int ‫هذا التابع من النوع‬
{ .float ‫ فعلٌنا أن نغٌر نوع التابع إلى‬float
return (float)a/b; float divide(int a, int b({…}
}
void subtract(int a , int b) ‫ وٌجب ّأال ٌعٌد قٌمة لكنه‬void ‫هذ التابع من النوع‬
{ ‫ لذلك سنغٌر‬return a-b; ‫ٌحتوي على التعلٌمة‬
return a-b; int ‫نوعه إلى‬
}
int subtract)int a, int b({…}

.3
‫البرنامج‬ ‫الناتج‬
#include<iostream> x b a
using namespace std; 0 0 -1.07374e+008
int x = 0; 0.5
float b; 0 2 1
float d(float a , float& b)
: ‫أ ّما بعد التعدٌل‬
{
a--; x b a
b++; 0 0 -1.07374e+008
x = a/b; 0.5
return (x+1)/2.0; 1 2 1
}
int main() ‫ هً قٌمة‬-1.07374e+008 ‫ القٌمة‬:‫مالحظة‬
{
‫عشوابٌة تختلف دوما وهً عشوابٌة ألن المتغٌّر‬
float a;
cout<<"x\tb\ta\n"; ‫ متغٌّر موضعً ولقد قلنا إنّ المتغٌّرات‬a
cout<<x<<"\t"<<b<<"\t"<<a<<endl; ‫الموضعٌة تؤخذ قٌما عشوابٌة إذا لم تت ّم تبدبتها أ ّما‬
a = b = ++x; ‫المتغٌّرات الشاملة فهً تؤخذ القٌم الصفرٌة للنوع‬
cout<<d(a , b)<<endl;
cout<<x<<"\t"<<b<<"\t"<<a<<endl;
return 0;
}

.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;
.03
cout<<"Enter height: ";
cin>>h;
cout<<"S ="<< Trgl_space(b,h)<<endl;
#include<iostream> break;
using namespace
default: std;
int print(int h); cout<<"program will terminate now!.";
int main() break;
{ int h;//h} is hieght
}cin>>h;
print(h);
return 0; }
int print(int h)
{ int i,j,k;
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;
}

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

-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] (a
.‫تعرٌف‬ (b
.d[2][4] (c
.20 (d

-4
const int arraySize = 10; (a
double fractions[ arraySize ] = { 0.0 }; )b
fractions[ 9 ] = 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);

295
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++)

296
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 is growing.\n";
else if(frq[1]==9)
cout<<"the array is decreasing.\n";
else if(frq[2]==9)
cout<<"the array is constant.\n";
else
cout<<"the array is growing and decreasing.\n";
return 0;
}

-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;
}

297
-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;

298
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;

299
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")
{

29:
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:1
‫الربدلة كائنية التوجه‬

.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:2
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:3
{
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; ‫العبارة‬ .5


.6

#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:4
.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:5
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:6
‫اخلامتة‬

‫كل ما عليك أن تتعلّمو في البرمجة‪ ,‬وليس ىذا ىو آخر الكتب التي ألفت‬
‫أخيراً ال يحوي ىذا الكتاب على ّ‬
‫في ىذا المجال؛ لذلك إن كنت ترى أ ّن البرمجة ىي الشي الذي كنت تبحث عنو فعليك أن تبحث عن كتاب‬
‫آخر لتكمل معو رحلتك‪.‬‬

‫هم اجعلو في ميّان حسناتنا وال تحرمنا أجره‪.‬‬


‫اللّ ّ‬

‫هم من كان سبباً في إنجاز ىذا الكتاب فحرمو على النار وارزقو الجنّة برحمتك يا أرحم الراحمين‪.‬‬
‫اللّ ّ‬

‫هم ما كان من صواب فمنك وحدك ال شريك لك‪ ,‬وما كان من زلل أو نسيان فمن أنفسنا والشيطان‪.‬‬
‫اللّ ّ‬

‫محمد وعلى آلو وصحبو أجمعين‪.‬‬


‫وصلّى اهلل على سي ّدنا ّ‬

‫رب العالمين‪.‬‬
‫وآخر دعوانا أن الحمد هلل ّ‬
‫***‬

‫ٌرجى زٌارة الرابط التالً إلبداء رأٌكم بالكتاب‬

‫‪https://docs.google.com/spreadsheet/viewform?formkey=dDVxYmV5UFgwaHBFZkQ0U3RiO‬‬
‫‪TNNSUE6MQ&ifq‬‬

‫‪2:7‬‬
‫املراجع‬

1- The cplusplus.com tutorial ) http://www.cplusplus.com/doc/ (


Auther: Juan Soulie
2- C++ How to Program
Fifth Edition
3- The C+ + Programming Language
Third Edition, Auther: Bjarne Stroustrup(the creator of c++)
4- Java How to Program
C# And VB.net 8002 ٛ٠‫د‬ٛ‫اي عز‬ٛ‫غ‬١‫ح ِغ ف‬ٛ‫ح ثخط‬ٛ‫ خط‬-5
‫فخ‬١ٍ‫أؽّذ عّبي خ‬

2:8

You might also like