break & continue

1. الأمر break
طبيعة العمل:
  • يوقف تنفيذ الحلقة الحالية فوراً
  • ينقل التحكم إلى أول سطر بعد الحلقة
  • يعمل مع جميع أنواع الحلقات (forwhiledo-while)
  • يستخدم عادة مع شروط if للخروج المبكر من الحلقة
فوائده:
  1. تحسين الأداء بتجنب تكرارات غير ضرورية
  2. الخروج من حلقات لا نهائية عند تحقيق شرط معين
  3. تقليل تعقيد الكود بتجنب شروط متداخلة
أمثلة:
مثال 1: الخروج عند العثور على عنصر
List<int> numbers = [1, 2, 3, 4, 5];
for (int num in numbers) {
  if (num == 3) {
    print('العثور على الرقم 3!');
    break;
  }
  print('فحص: $num');
}
--------------
فحص: 1
فحص: 2
العثور على الرقم 3!
Dart

مثال 2: مع الحلقات المتداخلة

for (int i = 1; i <= 3; i++) {
  for (int j = 1; j <= 3; j++) {
    if (i * j > 4) {
      print('تجاوز الحد المسموح');
      break; // يخرج من الحلقة الداخلية فقط
    }
    print('$i × $j = ${i * j}');
  }
}
Dart

مثال 3: في حلقات while

int count = 0;
while (true) { // حلقة لا نهائية ظاهرياً
  count++;
  if (count >= 5) {
    break;
  }
  print('التكرار $count');
}
Dart

2. الأمر continue

طبيعة العمل:
  • يتخطى باقي كود التكرار الحالي فقط
  • ينتقل إلى التكرار التالي في الحلقة
  • لا يوقف الحلقة كاملة مثل break
  • يستخدم عادة مع شروط if لتخطي حالات معينة
فوائده:
  1. تجنب تنفيذ كود غير ضروري لظروف معينة
  2. تحسين أداء الحلقة بتخطي العمليات غير المطلوبة
  3. زيادة وضوح الكود بتجنب شروط if متداخلة
أمثلة:

مثال 1: تخطي الأعداد الزوجية

for (int i = 1; i <= 5; i++) {
  if (i % 2 == 0) {
    continue; // يتخطى الأعداد الزوجية
  }
  print('العدد الفردي: $i');
}
--------------------
العدد الفردي: 1
العدد الفردي: 3
العدد الفردي: 5
Dart

مثال 2: معالجة بيانات مع استثناءات

List<String> names = ['أحمد', 'محمد', null, 'خالد'];
for (var name in names) {
  if (name == null) {
    continue; // يتخطى القيم null
  }
  print('الاسم: ${name.toUpperCase()}');
}
Dart

مثال 3: في حلقات while

int x = 0;
while (x < 5) {
  x++;
  if (x == 3) {
    continue; // يتخطى التكرار عندما x = 3
  }
  print(x);
}
-----------------
1
2
4
5
Dart
3. الفروق الجوهرية بين break و continue
المعيارbreakcontinue
التأثيرينهي الحلقة كاملةيتخطى التكرار الحالي فقط
الاستخدامللخروج المبكرلتخطي حالات معينة
عدد التكراراتيقلل عدد التكراراتيحافظ على نفس العدد
الأداءيحسن الأداء إذا قلل التكراراتيحسن الأداء بتقليل العمليات
4. حالات خاصة واستخدامات متقدمة
أ. break مع العلامات (Labels)
outerLoop: for (int i = 1; i <= 3; i++) {
  innerLoop: for (int j = 1; j <= 3; j++) {
    if (i == 2 && j == 2) {
      break outerLoop; // يخرج من الحلقتين معاً
    }
    print('$i, $j');
  }
}
------------------
1, 1
1, 2
1, 3
2, 1
Dart

ب. continue مع العلامات

outer: for (int i = 1; i <= 3; i++) {
  inner: for (int j = 1; j <= 3; j++) {
    if (i == j) {
      continue outer; // يتخطى التكرارات الداخلية عندما i == j
    }
    print('$i, $j');
  }
}
-------------------
1, 2
1, 3
2, 1
3, 1
3, 2
Dart

ج. مع Switch-Case

String command = 'pause';
switch (command) {
  case 'start':
    print('بدء التشغيل');
    break; // ضروري في switch
  case 'pause':
    print('إيقاف مؤقت');
    break;
  default:
    print('أمر غير معروف');
}
Dart
5. نصائح وأفضل الممارسات
  1. استخدم break بحكمة: تجنب الإفراط في استخدامه لأنه قد يجعل الكود صعب التتبع
  2. تجنب continue في أماكن غير واضحة: قد يجعل تدفق البرنامج معقداً
  3. استخدم التعليقات: خاصة عند استخدام break أو continue بشروط معقدة
  4. اختبار جميع السيناريوهات: تأكد من أن break و continue لا يسببان سلوكاً غير متوقع
  5. تفضيل القابلية للقراءة: أحياناً if-else تكون أوضح من continue
6. أمثلة تطبيقية عملية
المثال 1: البحث في مجموعة بيانات
List<Map<String, dynamic>> products = [
  {'id': 1, 'name': 'هاتف', 'inStock': false},
  {'id': 2, 'name': 'حاسوب', 'inStock': true},
  {'id': 3, 'name': 'تابلت', 'inStock': true}
];

bool found = false;
for (var product in products) {
  if (product['inStock']) {
    print('المنتج المتاح: ${product['name']}');
    found = true;
    break; // وجدنا منتجاً متاحاً، لا داعي للاستمرار
  }
}

if (!found) {
  print('لا يوجد منتجات متاحة حالياً');
}
Dart

المثال 2: معالجة بيانات مع استثناءات

List<int?> grades = [85, 92, null, 78, null, 90];
int sum = 0;
int count = 0;

for (var grade in grades) {
  if (grade == null) {
    continue; // يتخطى الدرجات الفارغة
  }
  sum += grade;
  count++;
}

if (count > 0) {
  print('المعدل: ${sum / count}');
} else {
  print('لا توجد درجات صالحة');
}
Dart

المثال 3: محاكاة نظام تسجيل الدخول

import 'dart:io';

void main() {
  int attempts = 0;
  const String correctPassword = "123456";
  bool loggedIn = false;

  while (attempts < 3) {
    print("أدخل كلمة المرور:");
    String? input = stdin.readLineSync();

    if (input != correctPassword) {
      attempts++;
      print("كلمة مرور خاطئة. المحاولات المتبقية: ${3 - attempts}");
      continue; // يتخطى باقي الكود ويطلب كلمة المرور مجدداً
    }

    loggedIn = true;
    break; // كلمة المرور صحيحة، نخرج من الحلقة
  }

  print(loggedIn ? "تم تسجيل الدخول بنجاح" : "تم تجاوز عدد المحاولات");
}
Dart

7. الأخطاء الشائعة

أ. استخدام break خارج الحلقة

if (true) {
  break; // خطأ: break يجب أن يكون داخل حلقة
}
Dart

ب. continue في switch

switch (value) {
  case 1:
    continue; // خطأ: continue لا يعمل مع switch
}
Dart

ج. حلقات لا نهائية بدون break

while (true) {
  // نسيان وضع break قد يتسبب في حلقة لا نهائية
}
Dart
الخلاصة
  • break: للأيقاف الفوري للحلقة عند تحقيق شرط معين
  • continue: لتخطي التكرار الحالي والانتقال للتالي
  • كلاهما أدوات قوية لتحسين أداء ووضوح الكود عند استخدامها بشكل صحيح
  • يجب استخدامهما بحذر للحفاظ على قابلية قراءة الكود
  • تعمل مع جميع أنواع الحلقات (forwhiledo-while)
  • يمكن استخدامها مع العلامات (labels) للحلقات المتداخلة