C++: تمرين: التفريع والحلقات الشامل
آخر تحديث: 2026-08-26
الدروس السابقة غطت العبارات الشرطية والحلقات بشكل منفصل، لكن في البرامج الحقيقية تُستخدم معًا.
في هذا الدرس، سنتدرب على جعل التفريع والحلقات يعملان معًا من خلال عدة أمثلة شاملة.
1. مثال 1: لعبة تخمين الأرقام (النسخة الكاملة)
(1) 1.1 تحليل المتطلبات
سنبنى لعبة تخمين أرقام كاملة:
- البرنامج يولد عشوائيًا رقمًا من 1-100
- المستخدم يدخل تخمينه
- إذا كان التخمين مرتفعًا جدًا، يُظهر "مرتفع جدًا"
- إذا كان التخمين منخفضًا جدًا، يُظهر "منخفض جدًا"
- إذا كان التخمين صحيحًا، يهنئ المستخدم ويظهر عدد المحاولات
- يمكن للمستخدم اختيار اللعب مرة أخرى
▶ مثال 1: لعبة تخمين الأرقام الكاملة (الصعوبة ⭐⭐)
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
std::srand(static_cast<unsigned int>(std::time(nullptr)));
char playAgain;
do {
int secretNumber = std::rand() % 100 + 1;
int guess;
int attempts = 0;
std::cout << "========== Number Guessing Game ==========\n";
std::cout << "I'm thinking of a number from 1-100, guess it!\n\n";
do {
std::cout << "Enter your guess: ";
std::cin >> guess;
attempts++;
if (guess > secretNumber) {
std::cout << "Too high! Try again.\n";
} else if (guess < secretNumber) {
std::cout << "Too low! Try again.\n";
} else {
std::cout << "\n🎉 Congratulations! You got it!\n";
std::cout << "You guessed " << attempts << " times.\n";
if (attempts <= 5) {
std::cout << "You're amazing!\n";
} else if (attempts <= 10) {
std::cout << "Not bad!\n";
} else {
std::cout << "Keep trying, aim for fewer attempts next time!\n";
}
}
} while (guess != secretNumber);
std::cout << "\nWant to play again? (y/n): ";
std::cin >> playAgain;
std::cout << std::endl;
} while (playAgain == 'y' || playAgain == 'Y');
std::cout << "Thanks for playing, goodbye!" << std::endl;
return 0;
}
الخرج:
========== Number Guessing Game ==========
I'm thinking of a number from 1-100, guess it!
Enter your guess:
Too high! Try again.
Too low! Try again.
🎉 Congratulations! You got it!
You guessed times.
You're amazing!
Not bad!
Keep trying, aim for fewer attempts next time!
Want to play again? (y/n):
Thanks for playing, goodbye!
نموذج تشغيل:
========== Number Guessing Game ==========
I'm thinking of a number from 1-100, guess it!
Enter your guess: 50
Too high! Try again.
Enter your guess: 25
Too low! Try again.
Enter your guess: 37
Too high! Try again.
Enter your guess: 31
🎉 Congratulations! You got it!
You guessed 4 times.
You're amazing!
Want to play again? (y/n): n
Thanks for playing, goodbye!
تحليل الكود:
do-whileالخارجية: تتحكم في "اللعب مرة أخرى"do-whileالداخلية: حلقة التخمين الرئيسيةif-else if-else: تتحقق مما إذا كان التخمين مرتفعًا/منخفضًا/صحيحًاif-elseمتداخلة: تقيم الأداء بناءً على عدد المحاولات
2. مثال 2: دفتر عناوين بسيط
(1) 2.1 تحليل المتطلبات
ابنِ برنامج دفتر عناوين بسيط:
- عرض قائمة (إضافة جهة اتصال، عرض جهات الاتصال، خروج)
- المستخدم يختار عملية
- استخدام حلقة للسماح بالعمليات المستمرة حتى يختار المستخدم الخروج
▶ مثال 2: دفتر عناوين بسيط (الصعوبة ⭐⭐⭐)
#include <iostream>
#include <string>
int main() {
const int MAX_CONTACTS = 100;
std::string names[MAX_CONTACTS];
std::string phones[MAX_CONTACTS];
int count = 0;
int choice;
do {
// عرض القائمة
std::cout << "========== Simple Address Book ==========\n";
std::cout << "1. Add contact\n";
std::cout << "2. Show all contacts\n";
std::cout << "3. Exit\n";
std::cout << "Choose (1-3): ";
std::cin >> choice;
if (choice == 1) {
// إضافة جهة اتصال
if (count >= MAX_CONTACTS) {
std::cout << "Address book is full!" << std::endl;
} else {
std::cout << "Enter name: ";
std::cin.ignore(); // تجاهل سطر جديد
std::getline(std::cin, names[count]);
std::cout << "Enter phone: ";
std::getline(std::cin, phones[count]);
count++;
std::cout << "Added successfully!" << std::endl;
}
} else if (choice == 2) {
// عرض جهات الاتصال
if (count == 0) {
std::cout << "Address book is empty!" << std::endl;
} else {
std::cout << "\n========== Contact List ==========\n";
for (int i = 0; i < count; i++) {
std::cout << i + 1 << ". " << names[i] << " - " << phones[i] << std::endl;
}
std::cout << "================================\n\n";
}
} else if (choice == 3) {
std::cout << "Goodbye!" << std::endl;
} else {
std::cout << "Error: Please enter a number between 1-3!" << std::endl;
}
std::cout << std::endl;
} while (choice != 3);
return 0;
}
الخرج:
========== Simple Address Book ==========
1. Add contact
2. Show all contacts
3. Exit
Choose (1-3):
Address book is full!
Enter name:
Enter phone:
Added successfully!
Address book is empty!
========== Contact List ==========
. -
================================
Goodbye!
Error: Please enter a number between 1-3!
💡 نصيحة: هذا البرنامج يستخدم مصفوفات (سنغطيها بالتفصيل في الدرس 09). يمكنك نسخه حاليًا وفهم النهج العام.
3. مثال 3: حاسبة بسيطة (نسخة موسعة)
(1) 3.1 تحليل المتطلبات
ابنِ حاسبة تدعم عمليات حسابية متعددة:
- عرض قائمة (جمع، طرح، ضرب، قسمة، خروج)
- المستخدم يختار عملية
- إدخال رقمين، إخراج النتيجة
- استخدام حلقة للسماح بالحسابات المستمرة
▶ مثال 3: الحاسبة الموسعة (الصعوبة ⭐⭐)
#include <iostream>
#include <iomanip>
int main() {
int choice;
do {
// عرض القائمة
std::cout << "========== Simple Calculator ==========\n";
std::cout << "1. Addition\n";
std::cout << "2. Subtraction\n";
std::cout << "3. Multiplication\n";
std::cout << "4. Division\n";
std::cout << "5. Exit\n";
std::cout << "Choose (1-5): ";
std::cin >> choice;
if (choice >= 1 && choice <= 4) {
double num1, num2;
std::cout << "Enter the first number: ";
std::cin >> num1;
std::cout << "Enter the second number: ";
std::cin >> num2;
double result;
bool valid = true;
switch (choice) {
case 1:
result = num1 + num2;
break;
case 2:
result = num1 - num2;
break;
case 3:
result = num1 * num2;
break;
case 4:
if (num2 != 0) {
result = num1 / num2;
} else {
std::cout << "Error: Divisor cannot be 0!" << std::endl;
valid = false;
}
break;
}
if (valid) {
std::cout << std::fixed << std::setprecision(2);
std::cout << "Result: " << result << std::endl;
}
} else if (choice == 5) {
std::cout << "Goodbye!" << std::endl;
} else {
std::cout << "Error: Please enter a number between 1-5!" << std::endl;
}
std::cout << std::endl;
} while (choice != 5);
return 0;
}
الخرج:
========== Simple Calculator ==========
1. Addition
2. Subtraction
3. Multiplication
4. Division
5. Exit
Choose (1-5):
Enter the first number:
Enter the second number:
Error: Divisor cannot be 0!
Result:
Goodbye!
Error: Please enter a number between 1-5!
4. الأخطاء الشائعة والتصحيح
(1) 4.1 الحلقات اللانهائية
مثال على خطأ:
int i = 1;
while (i <= 10) {
std::cout << i << " ";
// ❌ نسيت i++، i تبقى 1، الحلقة لا تنتهي أبدًا
}
نصيحة تصحيح: أضف خرج داخل الحلقة للتحقق من قيمة متغير الحلقة:
int i = 1;
while (i <= 10) {
std::cout << "[DEBUG] i = " << i << std::endl;
std::cout << i << " ";
i++; // ✅ تذكر تحديث متغير الحلقة
}
(2) 4.2 شرط حلقة خاطئ
مثال على خطأ:
// ❌ يريد إخراج 1-10، لكن الشرط i < 10، يُخرج فقط 1-9
for (int i = 1; i < 10; i++) {
std::cout << i << " ";
}
نصيحة تصحيح: قبل بدء الحلقة، أخرج القيمة الأولية لمتغير الحلقة والشرط:
int i = 1;
std::cout << "[DEBUG] Initial value i = " << i << ", condition i <= 10" << std::endl;
while (i <= 10) {
std::cout << i << " ";
i++;
}
5. تمرين تطبيقي: محاكي ماكينة صراف آلي
▶ مثال 4: محاكي صراف آلي بسيط (الصعوبة ⭐⭐⭐)
#include <iostream>
#include <iomanip>
int main() {
double balance = 1000.00; // الرصيد الأولي
int choice;
do {
// عرض القائمة
std::cout << "========== ATM Simulator ==========\n";
std::cout << "1. Check balance\n";
std::cout << "2. Deposit\n";
std::cout << "3. Withdraw\n";
std::cout << "4. Exit\n";
std::cout << "Choose (1-4): ";
std::cin >> choice;
if (choice == 1) {
// التحقق من الرصيد
std::cout << std::fixed << std::setprecision(2);
std::cout << "Current balance: " << balance << std::endl;
} else if (choice == 2) {
// إيداع
double amount;
std::cout << "Enter deposit amount: ";
std::cin >> amount;
if (amount > 0) {
balance += amount;
std::cout << "Deposit successful!" << std::endl;
} else {
std::cout << "Error: Deposit amount must be greater than 0!" << std::endl;
}
} else if (choice == 3) {
// سحب
double amount;
std::cout << "Enter withdrawal amount: ";
std::cin >> amount;
if (amount > 0 && amount <= balance) {
balance -= amount;
std::cout << "Withdrawal successful!" << std::endl;
} else if (amount <= 0) {
std::cout << "Error: Withdrawal amount must be greater than 0!" << std::endl;
} else {
std::cout << "Error: Insufficient balance!" << std::endl;
}
} else if (choice == 4) {
std::cout << "Thank you for using, goodbye!" << std::endl;
} else {
std::cout << "Error: Please enter a number between 1-4!" << std::endl;
}
std::cout << std::endl;
} while (choice != 4);
return 0;
}
الخرج:
========== ATM Simulator ==========
1. Check balance
2. Deposit
3. Withdraw
4. Exit
Choose (1-4):
Current balance:
Enter deposit amount:
Deposit successful!
Error: Deposit amount must be greater than 0!
Enter withdrawal amount:
Withdrawal successful!
Error: Withdrawal amount must be greater than 0!
Error: Insufficient balance!
Thank you for using, goodbye!
Error: Please enter a number between 1-4!
نموذج تشغيل:
========== ATM Simulator ==========
1. Check balance
2. Deposit
3. Withdraw
4. Exit
Choose (1-4): 1
Current balance: 1000.00
Choose (1-4): 2
Enter deposit amount: 500
Deposit successful!
Choose (1-4): 1
Current balance: 1500.00
Choose (1-4): 4
Thank you for using, goodbye!
❓ أسئلة شائعة
for عندما تعرف عدد التكرارات (مثلاً: اطبع 100 مرة)؛ استخدم while عندما لا تعرف العدد لكنك تعرف الشرط (مثلاً: خمّن حتى تصيب)؛ استخدم do-while عندما يجب أن يُنفذ الجسم مرة واحدة على الأقل.break يخرج من الحلقة بالكامل، continue يتخطى التكرار الحالي وينتقل للتكرار التالي. يمكن خلطهما، لكن تأكد من وضوح المنطق — break ينهي بالكامل، continue يتخطى التكرار الحالي فقط.cin >> وgetline. الحل: أضف cin.ignore() بعد cin >> لتجاهل حرف السطر الجديد.📖 ملخص
- البرامج الحقيقية غالبًا تخلط التفريع والحلقات
do-whileيناسب سيناريوهات "يجب التنفيذ مرة واحدة على الأقل" (مثلاً: القوائم)switch-caseيناسب سيناريوهات "اختر واحدًا من عدة" (مثلاً: اختيارات القائمة)- عند تصحيح الحلقات، أضف خرجًا داخل الحلقة (مثلاً
[DEBUG] i = ...) - احرص على تجنب الحلقات اللانهائية (تذكر تحديث متغيرات الحلقة)
📝 تمارين
-
أساسي (الصعوبة ⭐): اكتب برنامجًا يتيح للمستخدم إدخال عدد صحيح موجب n، ثم يُخرج جميع الأعداد الزوجية من 1 إلى n.
-
متوسط (الصعوبة ⭐⭐): اكتب برنامجًا ينفذ لعبة "حجر-ورقة-مقص":
- دع المستخدم يدخل 1 (حجر)، 2 (مقص)، 3 (ورقة)
- البرنامج يولد اختيارًا عشوائيًا
- حدد الفائز وأخرج النتيجة
- يمكن للمستخدم اختيار "اللعب مرة أخرى"
-
متقدم (الصعوبة ⭐⭐⭐): اكتب برنامجًا ينفذ "نظام إدارة درجات الطلاب البسيط": 5. الميزات: إضافة طلاب (اسم، درجة)، عرض جميع الطلاب، حساب المتوسط، خروج 6. استخدم قائمة حلقة للعمليات المستمرة 7. (اختياري) أضف ميزة "الترتيب حسب الدرجة"
- البرامج الحقيقية تخلط التفريع والحلقات
- do-while يناسب السيناريوهات التي تُنفذ مرة واحدة على الأقل (مثلاً: القوائم)
- switch-case يناسب سيناريوهات اختر واحدًا من عدة
- في الحلقات المتداخلة، break يخرج فقط من المستوى الحالي
- عند تصحيح الحلقات، استخدم cout لإخراج قيم المتغيرات وتتبع التنفيذ
6. 🚀 الخطوات التالية
تهانينا! لقد أكملت جميع دروس المرحلة 1 (الأساسيات). بعد ذلك، ندخل المرحلة 2 (الدوال)، تعلم كيفية تغليف الكود في وحدات قابلة لإعادة الاستخدام لبرامج أنظف وأسهل في الصيانة!