الـ Range-Based For Loop
جزء من قسم Logic & Flow في رحلة C++ على Coddy — الدرس 15 من 56.
بينما تعمل حلقات for التقليدية مع الفهارس بشكل جيد للتكرار عبر المتجهات (vectors)، تقدم لغة C++ حلاً أكثر أناقة: حلقة for المبنية على النطاق (range-based for loop). هذا بناء الجملة الحديث يلغي الحاجة إلى إدارة الفهارس يدوياً ويجعل كودك أكثر نظافة وأسهل في القراءة.
تتعامل حلقة for المبنية على النطاق (range-based for loop) تلقائيًا مع تفاصيل التكرار نيابةً عنك. بدلاً من إدارة متغير الفهرس (index variable)، يمكنك ببساطة تحديد ما تريد القيام به مع كل عنصر:
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
for (const std::string& name : names) {
std::cout << name << std::endl;
}تقوم هذه الحلقة بنفس المهمة تماماً مثل النهج التقليدي القائم على الفهرس، ولكن بصيغة برمجية أبسط بكثير. يأخذ المتغير name تلقائياً قيمة كل عنصر في الـ vector، واحداً تلو الآخر.
لاحظ الرمز
& في const std::string& name. هنا، & لا تعني "عنوان" (address of) كما قد تكون رأيت من قبل — ففي تعريف متغير كهذا، تعني مرجعاً (reference) (أو اسماً مستعاراً). بدلاً من نسخ كل عنصر، يصبح name اسماً مستعاراً يشير مباشرة إلى العنصر في الـ vector، بشكل يشبه استخدام المؤشر (pointer) ولكن دون الحاجة إلى فك المرجعية (dereference) داخل جسم الحلقة.تعد الكلمة المفتاحية
const إجراءً وقائياً: فهي تمنعك من تعديل العنصر عن طريق الخطأ عبر الاسم المستعار داخل جسم الحلقة، مما يحافظ على بيانات الـ vector الأصلية دون تغيير.إن حلقة for المبنية على النطاق (range-based for loop) ليست فقط أكثر قابلية للقراءة ولكنها أيضًا أكثر أمانًا - فلا يوجد خطر من حدوث أخطاء في الفهرس (index errors) لأنك لا تدير الفهارس يدويًا. وهي تعمل مع أي حاوية تدعم التكرار، مما يجعلها أداة متعددة الاستخدامات لمعالجة مجموعات البيانات في لغة C++.
التحدي
سهلقم بإنشاء برنامج يوضح حلقة for المبنية على النطاق (range-based for loop) من خلال معالجة مجموعة من أسماء المدن وعرضها مع عدد أحرفها.
سيتم توفير المدخلات التالية:
- عدد صحيح
nيمثل عدد المدن - ثم
nمن السلاسل النصية (strings) التي تمثل أسماء المدن
يجب على برنامجك القيام بما يلي:
- إنشاء
std::vector<std::string>باسمcities - استخدام
push_back()لإضافة كل اسم من أسماء المدن الـnإلى المتجه (vector) - استخدام حلقة for مبنية على النطاق للتكرار عبر المتجه
- لكل مدينة في الحلقة، اطبع اسم المدينة متبوعاً بطولها باستخدام طريقة
.length() - بعد الحلقة، اطبع العدد الإجمالي للمدن التي تمت معالجتها باستخدام طريقة
.size()الخاصة بالمتجه
استخدم تنسيق المخرجات الدقيق التالي:
City: [city name] (Length: [number of characters])\nCity: [city name] (Length: [number of characters])\n...\nTotal cities processed: [total count]يجب أن تستخدم حلقة for المبنية على النطاق الصيغة for (const std::string& city : cities) للتكرار عبر كل عنصر في المتجه. استخدم city.length() للحصول على عدد الأحرف في اسم كل مدينة.
ورقة مرجعية
تكرر حلقة for المبنية على النطاق (range-based for loop) عبر حاوية دون الحاجة إلى إدارة يدوية للفهرس:
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
for (const std::string& name : names) {
std::cout << name << std::endl;
}- تعلن
&عنnameكـ مرجع (اسم مستعار) لكل عنصر — بدون نسخ - تمنع
constالتعديل غير المقصود للعنصر داخل جسم الحلقة - تعمل مع أي حاوية تدعم التكرار
جرّب بنفسك
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
// قراءة عدد المدن
int n;
cin >> n;
// إنشاء متجه (vector) لتخزين أسماء المدن
vector<string> cities;
// قراءة أسماء المدن وإضافتها إلى المتجه
for (int i = 0; i < n; i++) {
string city;
cin >> city;
cities.push_back(city);
}
// TODO: اكتب الكود الخاص بك أدناه
// استخدم حلقة for المبنية على النطاق (range-based) للمرور عبر متجه المدن
// اطبع كل مدينة مع طولها باستخدام التنسيق المحدد
// بعد الحلقة، اطبع إجمالي عدد المدن التي تمت معالجتها
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1المؤشرات والذاكرة
ما هو المؤشر؟معامل العنوان (Address-Of)معامل الوصول للقيمة (Dereference)المؤشرات الفارغة (Null Pointers)المؤشرات والمصفوفاتالذاكرة الديناميكية باستخدام 'new'تحرير الذاكرة باستخدام 'delete'مراجعة - تمارين على المؤشرات2المتجهات (المصفوفات الديناميكية)
مقدمة إلى std::vectorإنشاء Vectorإضافة العناصرالوصول إلى العناصرحجم الـ Vectorالتكرار باستخدام For Loopالـ Range-Based For Loopإزالة العناصرملخص - عمليات الـ Vector