قوائم المهام في لغة C++: دليل للمبرمجين المبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا نحتاج إلى قوائم المهام في لغة C++؟

\n

تخيل أنك تقف في طابور عند صندوق السوبر ماركت. أول شخص يأتي يتم خدمته أولاً. في البرمجة، يُسمى هذا الهيكل قائمة انتظار (queue). وهو أحد أنواع البيانات الأساسية التي تعمل وفق مبدأ FIFO (First In, First Out) - "من يأتي أولاً يغادر أولاً".

\n

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

\n

في هذه المقالة، سنشرح كيفية إنشاء واستخدام قوائم الانتظار في لغة C++، وسننظر في الحاوية القياسية std::queue، وسنكتب عدة أمثلة عملية، ونناقش الأخطاء الشائعة للمبتدئين.

\n\n

أساسيات قائمة الانتظار: النظرية والمثال الأول

\n

ما هي قائمة الانتظار؟

\n

قائمة الانتظار هي نوع بيانات مجرد يدعم عمليتين أساسيتين:

\n
    \n
  • إضافة عنصر إلى نهاية قائمة الانتظار (enqueue / push);
  • \n
  • استخراج عنصر من بداية قائمة الانتظار (dequeue / pop).
  • \n
\n

في لغة C++، يتم تنفيذ قائمة الانتظار القياسية في ملف الرأس <queue> كفئة std::queue. بشكل افتراضي، تستخدم std::deque كحاوية أساسية، ولكن يمكنك استبدالها بـ std::list.

\n\n

المثال الأول: قائمة انتظار الأرقام

\n

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

\n
#include <iostream>\n#include <queue>\n\nint main() {\n    std::queue<int> my_queue;\n\n    // إضافة عناصر إلى قائمة الانتظار\n    my_queue.push(10);\n    my_queue.push(20);\n    my_queue.push(30);\n\n    std::cout << "العنصر الأول (front): " << my_queue.front() << std::endl;\n    std::cout << "العنصر الأخير (back): " << my_queue.back() << std::endl;\n    std::cout << "حجم قائمة الانتظار: " << my_queue.size() << std::endl;\n\n    // استخراج العناصر\n    while (!my_queue.empty()) {\n        std::cout << "تم الاستخراج: " << my_queue.front() << std::endl;\n        my_queue.pop();\n    }\n\n    return 0;\n}
\n

نتيجة تشغيل البرنامج:

\n
العنصر الأول (front): 10\nالعنصر الأخير (back): 30\nحجم قائمة الانتظار: 3\nتم الاستخراج: 10\nتم الاستخراج: 20\nتم الاستخراج: 30
\n

لاحظ: front() تُرجع العنصر الأول (الذي سيتم استخراجه بعد ذلك)، بينما back() تُرجع آخر عنصر تمت إضافته. الطريقة pop() تحذف العنصر ولكنها لا تُرجعه - من المهم تذكر ذلك!

\n\n

الطرق الأساسية لـ std::queue

\n

للعمل بكفاءة مع قائمة الانتظار، تحتاج إلى معرفة جميع طرقها. فيما يلي القائمة الكاملة:

\n
    \n
  • push(const T& value) - يضيف عنصرًا إلى نهاية قائمة الانتظار;
  • \n
  • pop() - يحذف العنصر الأول (لا يُرجعه);
  • \n
  • front() - يُرجع مرجعًا إلى العنصر الأول;
  • \n
  • back() - يُرجع مرجعًا إلى العنصر الأخير;
  • \n
  • empty() - يتحقق مما إذا كانت قائمة الانتظار فارغة (يُرجع true/false);
  • \n
  • size() - يُرجع عدد العناصر.
  • \n
\n

هام: قبل استدعاء front() أو pop()، تحقق دائمًا مما إذا كانت قائمة الانتظار فارغة باستخدام empty(). محاولة الوصول إلى عناصر قائمة انتظار فارغة ستؤدي إلى سلوك غير محدد (على الأرجح، تعطل البرنامج).

\n\n

مثال عملي: قائمة مهام

\n

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

المدونات

توصيات الكتب