السلام عليكم
مالفرق بين الحلقات الثلاث في لغة جافا for - while -do while
ومتي يكون استخدام احدها افضل من غيرها
الفارق الجوهري هو أن do while تنفذ الكود اولا ثم تتحقق من الشرط قبل الحلقة التالية
do{
//execute this first
}while(condition) // execute this next
وعلى العكس while و for يتم التحقق من الشرط أولا ثم تنفيذ الكود. وجرت العادة على استخدام for عندما يكون الكود مرتبط بعدد واستخدام while في غير ذلك، أما do while فنادرا ما تستخدم
نعم لكن هذه الميزة يمكن عملها في حلقة الـ for و while عن طريق جعل الشرط صحيح بداية
ولأجل هذا لا فرق جوهري بين الحلقات ويمكن التبديل بينها
كونك تستطيع استخدام for و while بدلا من do-while في بعض الحالات باستخدام خطوات اضافية فهذا لا ينفي وجود اختلاف جوهري بينهم يرجع للحالات المصممة لها وقت تصميم اللغة
ف do-while تمثلها positive kleene وتعني التنفيذ مرة واحدة علي الاقل بينما for و while تمثلها kleene star وتعني عدم التنفيذ أو التنفيذ لعدد غير محدد من المرات
بالطبع يمكن تمثيل positive kleene بال kleene star عن طريق اضافة تنفيذ مبدئي لضمان التنفيذ مرة واحدة على الاقل مثلما ستضطر في استخدامك للwhile بدلا من do-while لتكرار الكود ووضعه مرتين، مرة قبل الحلقة التكرارية ومرة داخلها
ولتوضيح الأمر اكثر جرب عمل برنامج console/terminal بسيط بالثلاث انواع، المطلوب هو أن يطلب من المستخدم ادخال حرف r لاعادة الطلب مرة اخري أو q للخروج من الحلقة وغلق البرنامج
مرحباً أخي الكريم
اسمح لي أن اعترض على مداخلتك القيمة مع احترامي الشديد لما تفضلت بطرحه
أظنك اخطئت عندما قلت
كونك تستطيع استخدام for و while بدلا من do-while في بعض الحالات باستخدام خطوات اضافية فهذا لا ينفي وجود اختلاف جوهري بينهم يرجع للحالات المصممة لها وقت تصميم اللغة
الصواب هو أن جميع الحالات التي يمكن القيام بها بالـ for او while يمكن القيام بها بالـ do-while
وكذلك جميع الحالات التي يمكن القيام بها بالـ do-while يمكن القيام بها بالـ for و الـ while
بكلمات أخرى
لو مثلاً قررت الجافا في الاصدار الجديد لها أن تحذف جميع الحلقات وتكتفي فقط بحلقة واحدة منها
فهذا لا يعني أن اللغة ستصبح اضعف أو انها ستعجز عن تحقيق ما كانت تحققه بالسابق
فكل اللوبات السابقة يمكن الاستغناء عنها تماماً واستبدالها بلوب واحد فقط
حسب معرفتي ووجهة نظري
لا يوجد فرق جوهري بين الثلاث الحلقات
الفروق الموجودة هي فروق شكلية لا غير
ولكي أقتنع بما تفضلت بطرحه
اعطني كود معين يستخدم أي حلقة من الحلقات الثلاث بحيث لا استطيع تحويله إلى كود يستخدم الحلقات الباقيات
واذا فعلت ذلك وقتها فعلا سأكون مخطئ وساعتذر لك
لكني لا أظنك ستجد اي مثال لذلك
محبتي
ستجدني ذكرت في تعليقي
بالطبع يمكن تمثيل positive kleene بال kleene star عن طريق اضافة تنفيذ مبدئي لضمان التنفيذ مرة واحدة على الاقل مثلما ستضطر في استخدامك للwhile بدلا من do-while لتكرار الكود ووضعه مرتين، مرة قبل الحلقة التكرارية ومرة داخلها
تعليقي لا ينفي إمكانية التبديل بينهم لكن في (بعض الحالات) يحتاج ذلك لتكرار الكود، جرب المثال الذي ذكرته لتفهم حتمية وجود التكرار في بعض الحالات
تعليقي لا ينفي إمكانية التبديل بينهم لكن في (بعض الحالات) يحتاج ذلك لتكرار الكود، جرب المثال الذي ذكرته لتفهم حتمية وجود التكرار في بعض الحالات
المعذرة لم انتبه لكلامك هذا
لكن حتى في هذه ليس بالضروة تكرار الكود
فبدلاً من تكرار الكود يمكنك (كما ذكرت سابقا) أن تجعل شرط التكرار صحيح بداية وحينها سيصبح الوايل لوب مثل الدو وايل
مثال ذلك
هذا الكود
int x=1;
do
{
System.out.println("do-while loop");
}while(x==0);
هنا طبعا سيتم تنفيذ ما بداخل الكود مرة واحدة لأن شرط التكرار خاطئ والدو-وايل ينفذ ثم يفحص الشرط
فللحصول على نفس النتيجة بالوايل بدلاً من تكرار ما بداخل اللوب كما اقترحت يمكن ببساطة التلاعب بشرط اللوب فنجعله في البداية سليم ليتحقق تنفيذ ما بداخل اللوب ثم يكون خاطئ لنضمن عدم التكرار بعد ذلك
int x=0;
while(x==0)
{
System.out.println("while loop");
x=1;
}
بكلمات أخرى
الفرق الوحيد في النتيجة بين الوايل والدو وايل يظهر فقط وفقط اذا كان شرط التكرار خاطئ من البداية
حينها بسبب الية ترتيب التنفيذ في الدو وايل سيتم يتنفيذ ما بداخل الحلقة مرة واحدة بينما في الوايل بسبب آلية ترتيب التنفيذ لن يتم تنفيذ ما بداخل الحلقة
لكن ببساطة بمجرد أن نجعل شرط الوايل سليم في البداية ثم يصبح غير سليم بعد ذلك حينها سيصبح الوايل نفس الدو وايل
مثالك يعتمد على التلاعب وكما ذكرت في التعليق الأول
كونك تستطيع استخدام for و while بدلا من do-while في بعض الحالات باستخدام (خطوات اضافية) فهذا لا ينفي وجود اختلاف جوهري بينهم يرجع (للحالات المصممة لها) وقت تصميم اللغة
من حيث الأصل تحويل do ل while يتم بهذا الشكل
do{
loop_body
}while(not_valid_condition)
====>
loop_body
while(not_valid_condition){
loop_body
}
والأفضل في هذه الحالات هو استخدام do بدلا من استخدام خطوات اضافية مثل التلاعب أو تكرار الكود
الفرق الوحيد في النتيجة بين الوايل والدو وايل يظهر فقط وفقط اذا كان شرط التكرار خاطئ من البداية
إذا كنت تقصد ناتج التنفيذ فنعم صحيح، أما إذا كان الناتج المترجم (اسمبلي) فلا ليس صحيح تماما do تحتوي علي conditional jump فقط أما while فتحتوي على conditional jump و unconditional jump وهو بالطبع فارق غير مهم للمطورين الأن فمع قيام الكمبيلر بعملية ال optimization سيقوم بloop unrolling . ولكنه يظل فرق مهم لفهم كيف تحدث الاشياء على أدني مستوي
يبدوا أننا متفقين وإنما الاختلاف بيينا لفظي
أعلم بوجود فروق بين الحلقات الثلاث
لكن هذه الفروق أنا أسميها فروق هامشية لا جوهرية على اعتبار أنه يمكن التبديل بين اللوبات مع الحصول على نفس النتيجة مع مراعاة أن السائل هنا لا يهمه تفاصيل الاسمبلي أو البايت كود الناتجة والظن أيضاً أن السائل يسأل عن الفروق التي تمايز بين نتيجة اختيار اللوبات
فأردت تنبيهه أنه لا تمايز ويمكنه الحصول على نفس النتيجة بأي لوب
بينما أنت تسمي هذه الفروق بالجوهرية لاعتبارات أخرى
ففي حقيقة الأمر نحن متفقين وإن كنا نستخدم الفاظا مختلفة
احترامي لك
وشكراً لاضافاتك المفيدة
محبتي
التعليقات