Menu
flag Ar iconالعربيةdown icon

حلقات while في R: شرح while وrepeat وbreak

كيف تعمل حلقات while في R - التكرار بالشرط أولًا، وrepeat مع break بوصفها do-while في R، وnext، والعادات التي تبقيك بعيدًا عن الحلقات اللانهائية.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

حلقة while

تواصل حلقة while في R تنفيذ جسمها ما دام الشرط TRUE. وحيث تُنفَّذ حلقة for مرة لكل عنصر في شيء ما، تُنفَّذ while عددًا مجهولًا من المرات - حتى يتغير الشرط:

ثلاثة أجزاء تجعل كل حلقة while تعمل، وجميعها ظاهر هنا:

  1. التهيئة قبل الحلقة - إذ يمنح count <- 1 الشرط شيئًا يختبره.
  2. الشرط - وهو count <= 5، المبني من معاملات المقارنة المعتادة، ويُفحص قبل كل دورة.
  3. التحديث داخل الجسم - إذ يحرك count <- count + 1 الحلقة نحو التوقف.

احذف الجزء الثالث فيبقى الشرط TRUE إلى الأبد: ولن تنتهي الحلقة أبدًا. وهذا هو الخطر المميز لـ while، وبقية هذه الصفحة تدور في معظمها حول إدارته.

يُفحص الشرط قبل كل دورة

تختبر while شرطها أولًا، ثم تنفّذ الجسم. وينتج عن ذلك أمران. فإذا كان الشرط FALSE أصلًا منذ البداية، لن يُنفَّذ الجسم ولو مرة:

ويقع الفحص بين الدورات الكاملة، لا في منتصف الجسم - فبمجرد أن تبدأ دورة، تمضي حتى نهايتها حتى لو صار الشرط FALSE في منتصفها. وإذا احتجت إلى الانسحاب في منتصف الجسم، فذلك ما وُجدت break لأجله (كما سنرى بعد قليل).

مثال مشروح: التنصيف حتى ما دون العتبة

الموطن الطبيعي لـ while هو "استمر حتى": فلا يمكنك معرفة عدد الدورات مسبقًا، ولذا لا تناسب for. كم مرة يمكنك تنصيف العدد 1000 قبل أن ينخفض دون 1؟

عشر عمليات تنصيف، تنتهي عند نحو 0.977. وهذا النمط - متغير حالة يقلصه الجسم، وعداد ينمّيه - يغطي حصة هائلة من حلقات while الواقعية: الطرق العددية التي تعمل حتى يصغر الخطأ بما يكفي، والمحاكاة التي تعمل حتى ينفد مورد، وإعادات المحاولة التي تستمر حتى ينجح استدعاء.

‏repeat مع break: بديل do-while في R

لا تملك R كلمة مفتاحية do-while - أي لا حلقة تختبر شرطها بعد الجسم. لكنها تملك repeat التي تكرر دون شرط إلى الأبد، وbreak التي تخرج من أي حلقة فورًا. ضع اختبار break في نهاية جسم repeat فتكون قد بنيت do-while بالضبط - حلقة يُضمن تنفيذ جسمها مرة واحدة على الأقل:

يُنفَّذ الجسم دائمًا قبل الاختبار الأول، فيتضاعف n مرة واحدة على الأقل؛ وتخرج الحلقة عند 128، وهو أول تضاعف يتجاوز 100. استخدم هذه الصيغة حين يكون الوصف الصادق هو "افعل الشيء ثم قرر إن كنت ستكرره" - كقراءة مدخلات حتى تصبح صالحة، أو سحب عينات حتى تتأهل إحداها. وحلقة repeat بلا break يمكن بلوغه هي حلقة لانهائية بحكم البناء، فاكتب break أولًا ثم املأ الجسم.

وتعمل break بالطريقة نفسها في حلقات while وfor - فهي مخرج "انتهينا هنا" العام، وتقترن طبيعيًا بـ تعليمات if التي تختبر شرطًا في منتصف الجسم.

الكلمة next داخل حلقة while

تتخطى next بقية الدورة الحالية وتقفز إلى فحص الشرط. وهي تعمل في while كما في for - مع فخ واحد خاص بـ while: فإذا جاءت خطوة التحديث بعد next، فإن تخطيها يعني أن متغير الحلقة لا يتقدم أبدًا، وتكون قد بنيت حلقة لانهائية. ضع التحديث قبل next:

يطبع هذا الأعداد الزوجية من 2 إلى 10. وانقل i <- i + 1 إلى ما بعد سطر next فتتخطى أول قيمة فردية التحديث إلى الأبد. وفي حلقات for لا وجود لهذا الخطر (فمتغير الحلقة يتقدم تلقائيًا)، وهو سبب إضافي لتفضيل for حين تمشي على متتالية ببساطة.

الحماية من الحلقات اللانهائية

كل حلقة لانهائية هي العلة نفسها: لا شيء في الجسم يغيّر المتغيرات التي يعتمد عليها الشرط - أو أنه يغيّرها في الاتجاه الخاطئ. وفي الجلسات التفاعلية يمكنك المقاطعة بـ Esc أو Ctrl+C، لكن في النص البرمجي تتجمد العملية ببساطة. وعادتان تمنعان ذلك.

أولًا، حين تكتب الشرط، اسأل فورًا: "أي سطر في الجسم يحرّك هذا نحو FALSE؟" وتأكد من أن ذلك السطر يُنفَّذ في كل مسار عبر الجسم (وانتبه إلى فخ next المذكور سابقًا).

وثانيًا، بالنسبة إلى الحلقات التي يصعب إثبات انتهائها، أضف حارسًا لحد أقصى من التكرارات كي تنتج علة المنطق نتيجة قابلة للتشخيص بدل جلسة متجمدة. وهنا يحمي الحارس حلقة بأسلوب كولاتز - تنصيف الأعداد الزوجية مرارًا وتحويل x الفردي إلى 3 * x + 1، حتى بلوغ 1:

انطلاقًا من 10، تبلغ الحلقة القيمة 1 في ست خطوات. ولو أن قيمة ابتدائية ما لم تبلغ 1 أبدًا، لأنهى الشرط steps < 10000 الحلقة رغم ذلك، ولأخبرتك الحالة المطبوعة بأن شيئًا ما اعوجّ - فجواب خاطئ تراه أفضل من برنامج لا يجيب أبدًا. والمعامل && المقصّر للدارة هو المعامل الصحيح هنا: فالطرفان قيمتان مفردتان، ويُقرأ الحارس جملة واحدة.

‏while مقابل for: كيف تختار

القاعدة العملية تدور حول ما تعرفه مسبقًا:

  • تعرف ما الذي تكرر عليه (عناصر متجه، أو الأعداد من 1 إلى n): استخدم حلقة for - فمتغير الحلقة يدير نفسه.
  • لا تعرف سوى شرط التوقف (حتى التقارب، أو حتى الانخفاض دون عتبة، أو حتى الصلاحية): استخدم while.
  • يجب تنفيذ الجسم مرة واحدة على الأقل قبل أن يصبح لأي اختبار معنى: استخدم repeat مع break منهٍ.

وإذا وجدت نفسك تصون عدادًا يدويًا في حلقة while لمجرد المشي على متجه، فتلك حلقة for متنكرة - فبدّل.

ما تخرج به

  • تفحص while (condition) { ... } أولًا ثم تنفّذ - وشرط خاطئ في البداية يعني صفر دورات.
  • يجب أن يحرّك الجسم الشرط نحو FALSE؛ وثلاثي التهيئة والشرط والتحديث هو الانضباط كله.
  • لا تملك R كلمة do-while: فالصيغة المتعارف عليها هي repeat { body; if (done) break }، وتضمن دورة واحدة على الأقل.
  • تخرج break من أي حلقة؛ ومع next داخل while، حدّث متغير الحلقة قبل التخطي وإلا لم يتقدم أبدًا.
  • يحوّل حارس الحد الأقصى للتكرارات (&& steps < 10000) تجمدًا محتملًا إلى جواب خاطئ مرئي وقابل للتصحيح.

التالي: المتجهات - بنية البيانات التي كانت كل حلقة في هذه الصفحة تمشي عليها، والسبب في أن كثيرًا من حلقات R يمكن أن يختفي تمامًا.

الأسئلة الشائعة

كيف تعمل حلقة while في R؟

تفحص while (condition) { ... } الشرط أولًا، وتنفّذ الجسم ما دام الشرط TRUE. ويجب أن يجعل شيء ما في الجسم الشرط FALSE في النهاية - عادة بتحديث عداد أو تقليص قيمة - وإلا لم تنتهِ الحلقة أبدًا. وإذا كان الشرط FALSE منذ البداية، فلن يُنفَّذ الجسم ولو مرة.

هل تملك R حلقة do-while؟

ليس بوصفها كلمة مفتاحية. والصيغة المتعارف عليها هي repeat { ...body...; if (condition) break } - إذ تكرر repeat دون شرط، فيُضمن تنفيذ الجسم مرة واحدة على الأقل، ويؤدي break في النهاية دور اختبار الخروج في do-while.

كيف توقف حلقة لانهائية في R؟

في الجلسات التفاعلية، اضغط Esc ‏(في RStudio) أو Ctrl+C (في الطرفية) للمقاطعة. ولمنع حدوثها أصلًا: تأكد من أن الجسم يحدّث المتغيرات الواردة في الشرط في كل دورة، وأضف حارسًا لحد أقصى من التكرارات - مثل while (working && steps < 10000) - كي تنتج علة المنطق عددًا خاطئًا بدل جلسة متجمدة.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن