كيف يمكنني الخروج من فعل/أثناء حلقة؟
سؤال
void GasPump::dispense()
{
bool cont = true;
char stop;
do{
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
cin.get(stop);
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
if(stop == 0)
cont = false;
} while(cont);
}
القيام بمهمة ، هذا هو برنامجي الأول للكتابة مع كائنات حتى تحمل معي. لا يمكنني الحصول على إخراج هذا الرمز ليخرج بشكل صحيح. أحتاج إلى طريقة للخروج من الحلقة ، وما أستخدمه فقط لا يعمل. أي اقتراحات أو تلميحات أو نصائح؟
المحلول
حاول مقارنة توقف إلى الصفر.
stop == '0'
كما يمكنك تبسيط الكود عن طريق القيام بذلك.
void GasPump::dispense()
{
char stop;
do {
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
cin.get(stop);
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
} while (stop != '0');
}
نصائح أخرى
في هذا السيناريو ، يمكنك ضخ الغاز وقتًا إضافيًا بعد أن يضرب المستخدم "0". على افتراض أن هذا ليس مطلوبًا ، لديك ما يعرف باسم "خطأ خارج عن واحد". يمكنك إصلاح هذا (والتخلص من المتغير المؤقت) عن طريق إعادة ترتيب وظيفتك على النحو التالي:
void GasPump::dispense()
{
while (true) {
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
if (cin.get() == '0')
break;
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
}
}
لتجنب استخدام عبارة فاصل ، يمكنك استخدام البناء التالي:
bool GasPump::shouldDispenseGas()
{
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
return (cin.get() != '0');
}
void GasPump::dispense()
{
while (shouldDispenseGas()) {
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
}
}
Edit (2011 سبتمبر 27): tonyk لمجرد أن اللغة توفر ميزة لا يعني أنه ينبغي للمرء استخدامها. ال goto
البيان هو مثال كلاسيكي على هذا.
منحت ، مع مثل هذه الحلقة البسيطة ، لا يوجد فرق بين استخدام وظيفة وكسر. كلاهما واضح. ومع ذلك ، عندما يتم إضافة ميزات إضافية شهر (أو سنوات) في وقت لاحق ، إلى جانب الظروف الإضافية للخروج من الحلقة ، من السهل جدًا العثور if
عبارات ذات منطق معقد داخل حلقة كبيرة جدًا ، فأنت تواجه صعوبة في العثور على بدايتها ، وأقل بكثير من نقاط الخروج. تتمثل إحدى طرق محاربة هذا النوع من الكود في كتابة الوظائف القصيرة والبسيطة والمركزة التي يتم تسميتها جيدًا. إذا قمت بذلك ، فإن الكود يوثق نفسه. يقارن
while (true)
مقابل
while (shouldDispenseGas())
وبالمثل ، قارن هذا بـ STL for_each
خوارزمية. بالتأكيد، std::for_each(v.begin(), v.end(), &foo);
أقصر قليلاً من for (int i = 0; i < v.size(); ++i) { ...body of foo()... }
. لكن الميزة الحقيقية هي أنه من الأسهل رؤية ماهية القصد. في ال for_each
ترى على الفور أنك ستقوم بشيء ما مرة واحدة ، مرة واحدة فقط ، لكل عنصر. في الحلقة ، ليس لديك أي فكرة. عداد الحلقة i
قد يتم تغييرها في الحلقة. أ break
قد تكون مخفية في الداخل كذلك. عن طريق التخلص من هذا break
بيان وتضمين المنطق في shouldDispenseGas
, ، أنت تفهم على الفور الشروط التي ستستمر فيها الحلقة وتنتهي.