الحلقات في C++: for و range-for و while
الألعاب التي تعمل بـ C++ ترسم الشاشة عشرات المرات كل ثانية، وكل رسمة تمر على آلاف العناصر: الشخصيات، والأشجار، والطلقات. كل ذلك يتم بالـحلقات. في هذا الدرس ستتعلم الحلقات في C++، ومعها نوع حديث يجعل المرور على العناصر أسهل وأأمن بكثير.
حلقة for التقليدية
Section titled “حلقة for التقليدية”for (int i = 1; i <= 3; i++) { cout << "الدورة " << i << endl;}الدورة 1الدورة 2الدورة 3ثلاثة أجزاء: البداية int i = 1 مرة واحدة، والشرط i <= 3 قبل كل دورة، والخطوة i++ بعد كل دورة.
تخيّلها مثل جولات حارس الأمن: يبدأ من الجولة 1، ويستمر ما دام لم يكمل 3 جولات، ويسجّل رقم الجولة بعد كل واحدة.
حلقة range-based for
Section titled “حلقة range-based for”منذ C++11، هناك طريقة أبسط للمرور على كل عناصر مجموعة، دون عدّاد:
#include <vector>
vector<string> fruits = {"تفاح", "موز", "برتقال"};for (const string& fruit : fruits) { cout << "- " << fruit << endl;}- تفاح- موز- برتقالاقرأ النقطتين : كأنها كلمة «في»: «لكل fruit في fruits». و vector هو القائمة المرنة في C++، وستتعرف عليه بالتفصيل في درس المصفوفات.
ما معنى const string&؟
&تعني «مرجع» (Reference): نتعامل مع العنصر الأصلي مباشرة دون نسخه. هذا أسرع، خاصة مع النصوص الطويلة.constتعني «للقراءة فقط»: نضمن أننا لن نغيّر العنصر بالخطأ.
وتعمل الحلقة نفسها مع حروف النص:
string word = "code";for (char c : word) { cout << c << " ";}cout << endl;c o d ewhile و do-while
Section titled “while و do-while”int balance = 100;int days = 0;while (balance > 0) { balance -= 30; days++;}cout << "انتهى الرصيد بعد " << days << " أيام" << endl;انتهى الرصيد بعد 4 أيامwhile عندما لا تعرف عدد المرات، بل تعرف شرط الاستمرار. أما do-while فتُنفَّذ مرة واحدة على الأقل قبل فحص الشرط:
int n = 10;do { cout << "يُنفذ مرة واحدة على الأقل: " << n << endl; n++;} while (n < 5);يُنفذ مرة واحدة على الأقل: 10break و continue
Section titled “break و continue”for (int i = 1; i <= 10; i++) { if (i % 2 == 0) continue; // تخطَّ الزوجي if (i > 7) break; // توقف بعد 7 cout << i << " ";}cout << endl;1 3 5 7continue تتخطى باقي الدورة الحالية، و break تُنهي الحلقة كلها.
الحلقات المتداخلة وحيلة string
Section titled “الحلقات المتداخلة وحيلة string”for (int row = 1; row <= 3; row++) { cout << string(row, '*') << endl;}******string(row, '*') تنشئ نصاً فيه الحرف * مكرراً row مرة. حيلة لطيفة توفر حلقة داخلية كاملة! وبالطبع يمكنك كتابتها بحلقتين متداخلتين كما في C، وهذا تمرين جيد لك.
مثال: المجموع
Section titled “مثال: المجموع”int sum = 0;for (int i = 1; i <= 100; i++) sum += i;cout << sum << endl;5050جرّب بنفسك
Section titled “جرّب بنفسك”- اطبع جدول ضرب الرقم 9 من 1 إلى 10.
- أنشئ
vector<int>بدرجات 5 طلاب، واحسب مجموعها بحلقة range-based for. - اطبع عدد حروف العلة (a, e, i, o, u) في كلمة إنجليزية بالمرور على حروفها.
- تحدٍّ: ارسم هرماً من النجوم بارتفاع 4، مستخدماً
string(عدد, ' ')للمسافات وstring(عدد, '*')للنجوم.
أخطاء شائعة
Section titled “أخطاء شائعة”- تعديل عنصر عبر const&: خطأ ترجمة. إذا أردت تعديل العناصر في الحلقة، اكتب
for (string& fruit : fruits)بدونconst. - النسخ غير الضروري:
for (string fruit : fruits)تنسخ كل نص، وهذا أبطأ. استخدمconst string&. - الحلقة اللانهائية: تأكد أن الشرط سيصبح خطأ في لحظة ما.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ماذا تعني & في for (const string& name : names)؟
المرجع يسمح بالتعامل مع العنصر الأصلي مباشرة، فيوفر نسخه، و const يمنع تعديله.
سؤال
ما ناتج cout << string(3, 'a');؟
string(3, 'a') تنشئ نصاً فيه الحرف a مكرراً 3 مرات.
الخلاصة
Section titled “الخلاصة”forالتقليدية بأجزائها الثلاثة عندما تحتاج العدّاد.- range-based for
for (auto x : items)للمرور على كل العناصر أو الحروف. const T&يمنع النسخ والتعديل غير المقصود.whileحسب شرط، وdo-whileمرة على الأقل، وbreakوcontinueللتحكم.string(n, ch)تكرر حرفاً n مرة.