تخطَّ إلى المحتوى

الحلقات في C++‎: for و range-for و while

الدرس 4 من 11 · C++

الألعاب التي تعمل بـ C++‎ ترسم الشاشة عشرات المرات كل ثانية، وكل رسمة تمر على آلاف العناصر: الشخصيات، والأشجار، والطلقات. كل ذلك يتم بالـحلقات. في هذا الدرس ستتعلم الحلقات في C++‎، ومعها نوع حديث يجعل المرور على العناصر أسهل وأأمن بكثير.

for (int i = 1; i <= 3; i++) {
cout << "الدورة " << i << endl;
}
الناتج
الدورة 1
الدورة 2
الدورة 3

ثلاثة أجزاء: البداية int i = 1 مرة واحدة، والشرط i <= 3 قبل كل دورة، والخطوة i++ بعد كل دورة.

تخيّلها مثل جولات حارس الأمن: يبدأ من الجولة 1، ويستمر ما دام لم يكمل 3 جولات، ويسجّل رقم الجولة بعد كل واحدة.

منذ 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 e
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);
الناتج
يُنفذ مرة واحدة على الأقل: 10
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) continue; // تخطَّ الزوجي
if (i > 7) break; // توقف بعد 7
cout << i << " ";
}
cout << endl;
الناتج
1 3 5 7

continue تتخطى باقي الدورة الحالية، و break تُنهي الحلقة كلها.

الحلقات المتداخلة وحيلة string

Section titled “الحلقات المتداخلة وحيلة string”
for (int row = 1; row <= 3; row++) {
cout << string(row, '*') << endl;
}
الناتج
*
**
***

string(row, '*') تنشئ نصاً فيه الحرف * مكرراً row مرة. حيلة لطيفة توفر حلقة داخلية كاملة! وبالطبع يمكنك كتابتها بحلقتين متداخلتين كما في C، وهذا تمرين جيد لك.

int sum = 0;
for (int i = 1; i <= 100; i++) sum += i;
cout << sum << endl;
الناتج
5050
  1. اطبع جدول ضرب الرقم 9 من 1 إلى 10.
  2. أنشئ vector<int> بدرجات 5 طلاب، واحسب مجموعها بحلقة range-based for.
  3. اطبع عدد حروف العلة (a, e, i, o, u) في كلمة إنجليزية بالمرور على حروفها.
  4. تحدٍّ: ارسم هرماً من النجوم بارتفاع 4، مستخدماً string(عدد, ' ') للمسافات و string(عدد, '*') للنجوم.
  • تعديل عنصر عبر const&: خطأ ترجمة. إذا أردت تعديل العناصر في الحلقة، اكتب for (string& fruit : fruits) بدون const.
  • النسخ غير الضروري: for (string fruit : fruits) تنسخ كل نص، وهذا أبطأ. استخدم const string&.
  • الحلقة اللانهائية: تأكد أن الشرط سيصبح خطأ في لحظة ما.

سؤال

ماذا تعني & في for (const string& name : names)؟

سؤال

ما ناتج cout << string(3, 'a');؟

  • for التقليدية بأجزائها الثلاثة عندما تحتاج العدّاد.
  • range-based for for (auto x : items) للمرور على كل العناصر أو الحروف.
  • const T& يمنع النسخ والتعديل غير المقصود.
  • while حسب شرط، و do-while مرة على الأقل، و break و continue للتحكم.
  • string(n, ch) تكرر حرفاً n مرة.