اختبار

مجموعة المسائل 1

ادرس البرنامج التالي ثم أجب عن الأسئلة أدناه. نريد منك الإجابة عن الأسئلة بالنظر فقط إلى رمز المصدر، أي يُرجى عدم نسخه في ملف وتجميعه والإجابة عن الأسئلة استنادًا إلى تشغيله. سيؤدي ذلك إلى إزالة كل المتعة منها.

int main() {
  int counter, first, last, next;
  first = 1; last = 2;

  for (counter = first; counter <= last; counter++) {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
  }

  counter = first;
  while (counter <= last) {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
    counter++;
  }

  counter = first;
  do {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
    counter++;
  } while (counter < last);
}

السؤال 1: ما هي نتائج هذا البرنامج؟

أ) 1 2
2 4
1 2
2 4
1 2
2 4
B) 1 1
2 4
1 1
2 4
1 1
2 4
C) 1 1
2 4
1 1
2 4
1 1
د) 1 1
2 4
1 1
1 1
2 4
هـ) لا ينتج أي شيء - توجد أخطاء في بناء الجملة.

السؤال 2: ماذا سيحدث إذا أزلنا إعداد "counter" قبل حلقة "أثناء تشغيل"؟

أ) التكرار الحلقي لا نهائي - ينتج عن التكرار الحلقي سلسلة من 1
B) لن تتغيّر نتيجة البرنامج.
C) ينتج عن حلقة التكرار 2 و4.
د) لن ينتج عن التكرار الحلقي أي شيء
هـ) ينتج عن حلقة التكرار 3 و9.

السؤال 3: بناءً على البرنامج الأصلي المتوفّر في أعلى هذه الصفحة، لنفترض أنّنا أزلنا السطر الذي يهيئ المتغيّر المقابل قبل حلقة التكرار. ماذا سيحدث إذا أزلنا أيضًا السطر المقابل ++ داخل الحلقة أثناء الاستخدام، كما يلي؟

أ) لا ينتج عن التكرار الحلقي while أي شيء.
B) ناتج التكرار الحلقي while هو 1 و1، ولا ينتج عن تكرار الإجراء "أثناء" أي شيء.
C) ويكون ناتج التكرار الحلقي while هو نفسه عند تضمين كلا السطرين.
د) وسيخرج النظام أرقامًا عشوائية إلى أن يتم إيقاف تشغيل الكمبيوتر.
هـ) التكرار الحلقي while هو تكرار حلقي لا نهائي

السؤال 4: بالنظر إلى البرنامج الأصلي الموجود أعلى هذه الصفحة، ماذا سيحدث إذا بدا التكرار الحلقي while على هذا النحو؟

counter = first;
while (counter <= last) {
  cout << "\n" << counter;
  if (first % 2 == 0)
    next = counter * counter;
  cout << "  " << next;
  counter++;
}
أ) ناتج التكرار الحلقي while هو نفسه الناتج في البرنامج الأصلي.
B) لن يؤدي التكرار الحلقي while إلى إخراج أي شيء
C) ناتج التكرار الحلقي while هو 1 1 و1 4.
د) ناتج التكرار الحلقي while هو 1 2 و2 4.
هـ) ناتج التكرار الحلقي while هو 1 4 و2 4.
و) ناتج التكرار الحلقي while هو 2 4 و2 4.

السؤال 5: ماذا سيحدث إذا كان المتغير الأول أكبر من الأخير؟

أ) ستُخرج الحلقة أثناء التكرار شيئًا ما، لكن لا شيء آخر.
B) ستؤدي التكرارات الحلقية while إلى إخراج شيء ما، لكن لا شيء آخر.
C) لن يتم عرض أي نتيجة على الإطلاق.
د) سيحدّد البرنامج الخطأ أو التعطُّل
هـ) تُنتج التكرارات الحلقية شيئًا ما، لكن لن يحدث شيء آخر.

السؤال 6: ماذا سيخرج البرنامج إذا قمنا بتهيئة المتغير الأول ليكون مماثلاً للمتغير الأخير؟

أ) ستؤدي التكرارات الحلقية while إلى إخراج شيء ما، لكن لا شيء آخر.
B) ستُخرج الحلقة أثناء التكرار شيئًا ما، لكن لا شيء آخر.
C) وتؤدي كل حلقة تكرارية إلى إخراج سطر واحد.
د) يُخرج التكرار do while-loop خطين، والحلقات الأخرى في سطر واحد.
هـ) لن يؤدي ذلك إلى إخراج أي شيء
و) تُنتج التكرارات الحلقية شيئًا ما، لكن لن يحدث شيء آخر.


مجموعة المسائل 2

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

#include <iostream>
using namespace std;

int main() {
  int Boys = 3, Girls = 5;
  void F1(int males, int females);
  void F2(int &m, int &f);

  F1(Boys, Girls);
  cout << "\nAfter calling F1, within main()";
  cout << "\n\tBoys = " << Boys; // #2
  cout << "\n\tGirls = " << Girls;

  F2(Boys, Girls);
  cout << "\nAfter calling F2, within main()";
  cout << "\n\tBoys = " << Boys; // #4
  cout << "\n\tGirls = " << Girls;
}

void F1(int b, int g) {
  b += 3, g += 4;
  cout << "\nF1";
  cout << "\n\tBoys = " << b; // #1
  cout << "\n\tGirls = " << g;
}

void F2(int &b, int &g) {
  b = b + 8, g = g + 5;
  cout << "\nF2";
  cout << "\n\tBoys = " << b; // #3
  cout << "\n\tGirls = " << g;
}

السؤال 1: ما ناتج متغير الأولاد في الأسطر المميزة؟

أ) رقم 1: 6
رقم 2: 3
رقم 3: 11
رقم 4: 11
B) رقم 1: 6
رقم 2: 3
رقم 3: 11
رقم 4: 3
C) رقم 1: 6
رقم 2: 6
رقم 3: 11
رقم 4: 11
د) لا ينتج عنها أي نتيجة لأنها لا تجمع أو تعمل.

السؤال 2: اختر كل ما ينطبق في ما يتعلق بسطور البرنامج التالية:

void F1(int males, int females);
void F2(int &m, int &f);
أ) تنص قواعد C++ على أنه يمكننا إزالة هذين السطرين طالما تم تحديد الطرق قبل الاستخدام.
B) تنص قواعد C++ على أنّ أسماء الوسيطات يجب أن تكون متطابقة بين التعريف والتعريف.
C) وسينقطع هذا البرنامج إذا أزلنا هذين السطرين.
د) من الأكثر شيوعًا أن يتم ذكر التعريفات على مستوى النطاق العام.
هـ) وتسمى هذه البيانات إعادة التوجيه.

السؤال 3: إذا نقلنا السطر التالي من main() ووضعناه في النطاق العالمي، فماذا سيحدث؟

int Boys = 3, Girls = 5;
أ) ستكون المخرجات هي نفسها.
B) ستكون الأولاد = 3 والفتيات = 5 في جميع الإخراج
C) ستكون الأولاد = 3 والفتيات ستكون = 5 فقط في الإخراج من main()

السؤال 4: ماذا لو غيرنا بداية البرنامج لتبدو على النحو التالي:

// We have moved moved these to global scope
const int Boys = 3;
const int Girls = 5;

void main() {
  //int Boys = 3, Girls = 5;
أ) يتم تجميع البرنامج لكنه يتعطل عند محاولة تشغيله.
B) لن تكون هناك أي تغييرات في الإخراج
C) سيكون الناتج أولاد = 3 فتيات = 5 طوال مدة البرنامج
د) سيكون الناتج Boys = 3 Girls = 5 فقط في الإخراج من main()
هـ) من المحتمل ألا يتم تجميع البرنامج (اعتمادًا على المحول البرمجي).

السؤال 5: يتم تمرير البيانات بالقيمة في F2.

أ) صحيح
B) خطأ


مجموعة المسائل الحسابية رقم 3

كما في مجموعة المشكلات السابقة، إليك برنامج للنظر فيه. يُرجى الإجابة عن الأسئلة التالية من خلال الاطّلاع فقط على رمز المصدر.وهذه المقالة أكثر أهمية من الصفَّين السابقَين، لذا يجب تتبُّع الرمز بعناية.

#include <iostream>
using namespace std;

const int MAX_SIZE = 20;
typedef int ARR2D[MAX_SIZE][MAX_SIZE];

void Print(ARR2D in_array, int rows, int cols);
void Fill(ARR2D in_array, int rows, int cols);

int main() {
  ARR2D matrix;
  int row, col;
  do {
    cout << "Please enter the size of the matrix to generate (rows and cols) :" << endl;
    cin >> row >> col;
  } while (row <= 0 || row > MAX_SIZE || col <= 0 || col > MAX_SIZE);
  Fill(matrix, row, col);
  Print(matrix, row, col);
  return(0);
}

void Print(ARR2D in_array, int rows, int cols) {
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++)
      cout << '\t' << in_array[i][j];
    cout << endl;
  }
}

void Fill(ARR2D in_array, int rows, int cols) {
  for(int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++)
      in_array[i][j] = 0;

  const int limit = rows * cols;
  int cNum = 1;
  int cRow = 0;
  int cCol = 0;
  int cDir = 0;  // 0-north, 1-east, 2-south, 3-west

  while(true) {
    // Place the number.
    in_array[cRow][cCol] = cNum;
    cNum++;
    if (cNum > limit) break;

    int fRow = cRow;
    int fCol = cCol;
    while (true) {
      fRow = cRow;
      fCol = cCol;
      switch(cDir) {
        case 0: fRow--; break;
        case 1: fCol++; break;
        case 2: fRow++; break;
        case 3: fCol--; break;
      }

      if ( fRow >= 0 && fRow < rows && fCol >= 0 && fCol < cols && in_array[fRow][fCol] == 0)
        break;
      cDir = (cDir + 1) % 4;
    }
    cRow = fRow;
    cCol = fCol;
  }
}

السؤال 1: ماذا يخرج هذا البرنامج بمدخلات 3 للصفوف و4 للأعمدة؟

أ) 1 2 3
4 5 6
7 8 9
10 11 12
B) 1 2 3 4
5 6 7 8
9 10 11 12
C) 12 11 10 9
8 7 6 5
4 3 2 1
د) 1 3 2 4
8 6 7 5
9 11 10 12
هـ) 1 2 3 4
10 11 12 5
9 8 7 6
ز) 9 8 7 6
10 11 12 5
1 2 3 4
ح) لا ينتج أي شيء - المنطق خاطئ.
ط) لا ينتج أي شيء - هناك أخطاء في الصيغة.
ي) فليس من المفترض أن يعرض أي شيء، وليس من المفترض أن يعرض أي شيء.
ك) إنها تنتج أول 12 رقمًا تتبادر إلى الذهن أثناء انتظار تشغيل البرنامج.

السؤال 2: ماذا لو أضفنا السطر التالي إلى دالة main()؟

MAX_SIZE = 10;
أ) هذا غير مسموح به في لغة C++.
B) هذا مسموح به؛ سيتم تشغيل البرنامج مع تعيين MAX_SIZE على 20
C) هذا مسموح به؛ سيتم تشغيل البرنامج مع تعيين MAX_SIZE على 10.

السؤال 3: ضع في اعتبارك الأسطر الأربعة التالية من البرنامج أعلاه:

const int MAX_SIZE = 20;
typedef int ARR2D [MAX_SIZE][MAX_SIZE];

void Print  (ARR2D A, int rows, int cols);
void Fill   (ARR2D A, int rows, int cols);

1) هل من الممكن استخدام ثابتة في تعريف طباعي؟
2) هل من الممكن استخدام typedef في التعريف قبل الإعلان عن متغير من هذا النوع؟

أ) 1) نعم 2) نعم
B) 1) لا 2) لا
C) 1) لا 2) نعم
د) 1) نعم 2) لا

السؤال 4: هل يمكننا استخدام ما يلي:

#define MAX_SIZE 20
بدلاً من:
const int MAX_SIZE = 20;
أ) نعم، سيعمل ذلك ولا بأس من استخدام #define للثوابت في C++
B) نعم، سيعمل ذلك ولكننا لا نستخدم عادةً #define للثوابت في C++
C) #define غير متاح في C++
د) لا يمكنك تنفيذ أي من هذين الإجراءين في لغة C

السؤال 5: يتم استخدام typedef لإنشاء اسم مستعار لاسم نوع.

أ) صحيح
B) خطأ

السؤال 6: ماذا سيحدث إذا لم نقم بتهيئة الصفيفة إلى 0 في دالة Fill()؟

أ) سيتم تشغيلها ولكن ستكون المخرجات
B) سيتم تنفيذ هذه الإجراءات بشكلٍ جيد وإنشاء الناتج نفسه كما لو تم إعداد الصفيفة إلى 0.
C) لن يتم تشغيل البرنامج أو سيتعطّل.
د) سيتم تشغيلها ولكن سيكون الناتج 0
هـ) سيتم تشغيلها ولكن قد لا تؤدي إلى إنشاء أي نتائج.

السؤال 7: حدد كل ما ينطبق. لماذا نستخدم الثابت لـ MAX_SIZE في هذا البرنامج؟ أليس من الأسهل كتابة "20" بدلاً من MAX_SIZE عند الحاجة؟

أ) MAX_SIZE هي قيمة C++ مضمنة يمكن لأي شخص استخدامها. ما عليك سوى إعداده واستخدامه.
B) يجب تجنب السلبيات العامة مثل المتغيرات العمومية
C) يؤدي استخدام ثابت إلى تسهيل فهم برنامجنا
د) عادةً ما تعتبر الأرقام السحرية في البرنامج ممارسة جيدة.
هـ) إذا أردنا تغيير MAX_SIZE، فإننا بحاجة إلى تغييرها في مكان واحد فقط

السؤال 8: ينبغي أن تحتوي عبارة التبديل في الدالة fill() على حالة افتراضية، لأنها تعتبر نمطًا جيدًا لتضمين واحدة.

أ) صحيح
B) خطأ

السؤال 9: ملاحظة في الدالة fill()، نُعلن عن المتغيرات بين العبارات. على سبيل المثال، يتم الإعلان عن cNum وcRow وإعدادهما بعد تشغيل التكرار الحلقي. هل سيعمل هذا باستخدام C++ أم يجب الإعلان عن جميع المتغيرات في الجزء العلوي من الدالة؟

أ) لا بأس في القيام بذلك.
B) يجب الإعلان عن جميع المتغيرات في أعلى الدالة.
C) كلتا الطريقتين خاطئتان - لا تسمح لغة C++ بالمتغيّرات في أي مكان في البرنامج.
د) يجب الإعلان عن جميع المتغيرات في النطاق العمومي.

مجموعة المسائل 4

فيما يلي مجموعة من الملفات التي تُحدِّد فئة بسيطة وتختبرها. وكالعادة، أجب عن الأسئلة التالية من خلال الإشارة إلى رمز المصدر فقط.

فيما يلي ملف العنوان (cow.h):

#ifndef COW_H
#define COW_H

using namespace std;

typedef enum Color {black, brown, beige, blackandwhite, nocolor};

class Cow {
 public:
  Cow();
  ~Cow();

  // accessors
  double weight() { return weight_; };
  string name() { return name_; };
  Color color() { return color_; };

  // mutators
  void set_name(string inName) { name_ = inName; };
  void set_color(Color inColor) { color_ = inColor; };
  void set_weight(double inWeight) {weight_ = inWeight; };

  void Moo();
  void Properties();

 private:
  Color color_;
  double weight_;
  string name_;
};

#endif

فيما يلي ملف .cc المرتبط (cow.cc):

#include <iostream>
#include "cow.h"

using namespace std;

Cow::Cow() {}

Cow::~Cow() {}

void Cow::Moo() {
  cout << name() << " says MOO." << endl;
}

void Cow::Properties() {
  cout << name() << " weighs " << weight() << ", is "
       << color() << " and says MOO." << endl;
}

وإليك برنامج عميل لهذه الفئة (cowmain.cc):

#include <iostream>
#include "cow.h"

using namespace std;

int main() {
  Cow cow1;
  cow1.set_name("betsy");
  cow1.set_weight(400.0);
  cow1.set_color(black);

  cow1.Moo();
  cow1.Properties();
}

السؤال 1: ماذا ينتج عن هذا البرنامج؟

أ) "بيتسي" تقول MOO.
يزن "بيتي" 400، يساوي 0 ويقول MOO.
B) "بيتسي" تقول MOO.
يزن "بيتي" 400، وهو أسود ويقول MOO.
C) "بيتسي" تقول MOO.
يزن بيتي 400، وهو

السؤال 2: يجب ألا نضع أبدًا الرمز الخاص بطريقتَي الموصّل وأداة التبديل في ملف العنوان. (لاحظ أن الموصّل هو طريقة تُرجع قيمة، والمحول هو طريقة تقوم بتعديل قيمة).

أ) صحيح
B) خطأ

السؤال 3: هل نحتاج إلى "Cow::" قبل كل من تعريفات الدوال في cow.cc؟

أ) لا - حيث تم تضمين cow.h
B) نعم

السؤال 4: ما الدور الذي تقوم به:

#ifndef COW_H
#define COW_H
...
#endif

في ملف العنوان؟

يُرجى اختيار كل ما ينطبق:

أ) وليس لها أي أغراض لأن اسم الملف هو cow.h وليس COW_H.
B) وإذا لم نتّخذ هذا الإجراء، سيظهر لنا خطأ في وقت التشغيل.
C) إذا لم نفعل ذلك، فقد نضمّن الملف أكثر من مرة
د) ولا تفعل أي شيء بسبب وجود خطأ إملائي في واحدة أو أكثر من الكلمات الرئيسية.
هـ) لا يفعلون أي شيء لأن فئة Cow تحتوي على ملف عنوان واحد فقط.

السؤال 5: ماذا سيحدث إذا أضفنا السطر التالي إلى cowmain.cc؟

cow1.weight_ = 24;
أ) سيتم تشغيل البرنامج، وسيتم تعديل متغير الوزن من خلال هذا السطر.
B) سيتم تجميع البرنامج وتشغيله، ولكنه قد يتعطل على هذا السطر.
C) لا تسمح C++ بذلك.
د) سيتم تجميع البرنامج وتشغيله، ولكن لن يتغيّر متغير الوزن في هذا السطر.

السؤال 6: عند تنفيذ السطر التالي، يتم استدعاء الدالة الإنشائية في فئة Cow:

Cow cow1;

ما هي بعض الخصائص المهمة للبنّاءات؟

يُرجى اختيار كل ما ينطبق.

أ) لا تعرض عادةً أي قيم
B) وإذا لم نوفر دالة إنشائية في فئتنا، فلن تُجمّع الفئة
C) تعتبر الدالة الإنشائية في فئة Cow غير نمطية لأنها لا تُعِدّ المتغيرات الخاصة.
د) يكون لها دائمًا نفس اسم الفئة
هـ) يمكن أن يكون لدينا العديد من دوال الإنشاء في فئة طالما أن الوسيطات مختلفة
و) يتم استدعاء الدالة الإنشائية عند تثبيت فئة.

السؤال 7: ما هي بعض الخصائص المهمة للمدمر؟

أ) يتم استدعاء دالة التدمير عندما يخرج كائن عن النطاق
B) تحمل دالة التدمير الاسم نفسه الخاص بالفئة ولكن مسبوقة بـ "~".
C) ثمة خطأ في دالة التدمير في cow.cc وهو عدم تنفيذ أي إجراء.
د) إذا لم ننشئ دالة تدميرية لفئةنا، لن تجمع الفئة

السؤال 8: بالنظر إلى الطريقة التي يستخدم بها برنامج العميل الفئة، ضع في اعتبارك ما يلي:

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

أ) صحيح
B) خطأ

السؤال 9: ماذا لو أضفنا دالة إنشائية أخرى بالإضافة إلى الدالة التي لدينا إلى cow.cc. تبدو الدالة الإنشائية الجديدة كما يلي

Cow::Cow(string inName, double inWeight, Color inColor) {
  set_name(inName);
  set_weight(inWeight);
  set_color(inColor);
}

ونضيف الأسطر التالية إلى main():

Cow cow2("milly", 350.2, brown);
cow2.Moo();
cow2.Properties();

هل هذا ممكن؟

يُرجى اختيار كل ما ينطبق.

أ) سيتعطل السطر في main() حيث نقوم بتهيئة cow2.
B) يمكننا الحصول على دالة إنشاء واحدة فقط.
C) هذا أمر شائع في C++
د) نعم ولكن هذا ليس استخدامًا نموذجيًا لـ C++
هـ) سيتم تنفيذ ذلك على ما يرام، ولكن لن يؤدي إلى عرض أي بيانات بسبب عدم إعداد الخصائص الخاصة.
و) لا يمكننا استدعاء setName() وsetColor() وsetWeight() من داخل طريقة من الفئة نفسها.


أسئلة إضافية

السؤال 1) ما ناتج ما يلي؟

#include <iostream>
using namespace std;

void HelpMe(int *p, int *num, int *q);
void WhereAmI(int *p, int *q, int a);

void HelpMe(int *p, int *num, int *q) {
  int a;

  a = 2;
  q = &a;
  *p = *q + *num;
  num = p;
}


void WhereAmI(int *p, int *q, int a) {
  a = 6;
  *p = a + *p;
  *q = a + 3;
  HelpMe(q, &a, p);
}


int main() {
  int *p;
  int q;
  int *num;
  int a;

  a = 3;
  q = 5;
  p = &a;
  num = &q;

  HelpMe(&a, p, num);
  WhereAmI(&q, p, *num);

  cout << "*p = " << *p << " q = " << q << " *num = " << *num << endl;
}
 

السؤال 2) ضع في اعتبارك العبارة التالية، بافتراض وجود فئة Apple وإعدادها. تحتوي فئة Apple على متغير مثيل color_:

Apple* granny_smith = new Apple; 

اختر كل العبارات التالية الصحيحة:

أ) Apple* granny_smith = NULL; if (granny_smith == NULL)... هذا ليس مقبولاً - فارغة (NULL) ليست قيمة يمكن التحقق منها بهذه الطريقة.
B) Apple* granny_smith, fuji; يشير إلى مؤشرين لكائنات Apple.
C) يحتوي المتغير granny_smith على قيم متغير المثيل المرتبطة بكائن Apple.
د) تفاح* granny_smith = NULL; لا بأس،
هـ) يحتوي المتغير granny_smith على عنوان كائن Apple
و) سلسلة gs_color = *(granny_smith.get_color( شركاء) تُرجع هذه العبارة لون الكائن granny_smith، بافتراض أنّه تم تهيئته.
ز) يتم تخصيص مساحة التخزين لكائن Apple الجديد في كومة الذاكرة المؤقتة
ح) تخصيص مساحة التخزين لكائن Apple الجديد في حزمة وقت التشغيل
ط) int* a = &b; هذا يضع عنوان b في a.


السؤال 3) ما ناتج البرنامج التالي؟

#include <iostream>
using namespace std;

const int kNumVeggies = 4;

void Grill(int squash, int *mushroom);
int Saute(int onions[], int celery);


void Grill(int squash, int *mushroom) {
  *mushroom = squash/4;
  cout << *mushroom + squash << endl;
}

int Saute(int onions[], int celery) {
  celery *= 2;
  onions[celery]++;
  Grill(onions[0], &onions[3]);
  cout << celery << " " << onions[3] << endl;
  return celery;
}

int main() {
  int broccoli, peppers[kNumVeggies], *zucchini;

  for (broccoli = 0; broccoli < kNumVeggies; broccoli++)
    peppers[broccoli] = kNumVeggies - broccoli;
  zucchini = &peppers[Saute(peppers,1)];
  Grill(*zucchini, zucchini);
  zucchini--;
  cout << peppers[3] + *zucchini + *(zucchini + 1) << endl;
}


إجابات الاختبار

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

يمكنك الاطّلاع على إجابات عن المسائل أعلاه هنا.