У меня проблема с переводом этой блок-схемы ниже в код C ++.
Вероятно, это должно выглядеть примерно так (сейчас я знаю, что это неправильно):
do {
I1;
if(!W1) {
I2;
...
}
}
I1
, I2
, I3
это инструкции. Я думаю, что я должен использовать логические переменные, чтобы сделать это правильно, но как?
В блок-схеме есть петля. Условие остановки цикла на самом деле W1.
while (!W1())
{
}
I1 выполняется (изначально) независимо и выполняется до проверки условия завершения цикла, поэтому давайте обновим код:
I1();
while (!W1())
{
}
Опять же, I2 выполняется некодически:
I1();
while (!W1())
{
I2();
}
Теперь W2 влияет на то, выполняем ли мы I1 или I3, давайте обновим код соответствующим образом:
I1(); // for the first, unconditional execution
while (!W1())
{
I2();
if (W2())
I1();
else
I3();
}
Вы находитесь в случае двух скрещенных циклов: ни один не вложен в другой, поэтому обычных инструментов управления потоком недостаточно.
Многие обычно моделируют их с помощью искусственных логических флагов или дублирующих частей кода. Но это на самом деле один из очень немногих (и я имею в виду очень мало — подумайте заранее) используйте случаи goto
,
игнорирование W2
«s true
филиал, это выглядит как простой while
цикл:
I1;
while(!W1) {
I2;
if(W2)
/* ? */;
I3;
}
Теперь просто добавьте недостающую ветку. Конечно, метка должна иметь подходящее имя, чтобы она отражала вашу реальную доменную логику. Добавьте комментарии, чтобы было кристально ясно, и все готово.
// Let's W1 a stuff from our list of stuffs
handleNextStuff:
// Take a stuff
I1;
// Try W1'ing the stuff.
while(!W1) {
I2;
// No way we can W1 this stuff, drop it and try the next one.
if(W2)
goto handleNextStuff;
// A step closer to a W1'd stuff.
I3;
}
Вот моя идея:
for (bool skip_i1 = false; ; skip_i1 = true)
{
for (bool w2 = true; w2; w2 = W2())
{
if (!skip_i1) { I1(); }
skip_i1 = false;
if (W1()) { Finish(); return; }
I2();
}
I3();
}
В блок-схеме есть два цикла, поэтому в коде есть два цикла, но поскольку поток управления «неправильно вложен», нам нужен флаг (skip_i1
) переходить на перекрывающийся бит. Как вариант, вы можете поставить skip_i1 = false;
во внутреннюю for
инкрементор, или в else
филиал if
заявление.
Я предполагаю, что весь код живет в своей собственной функции (как это было лучше!), Так что мы можем выйти из внутреннего цикла напрямую return
,
START:
I1();
while(!W1){
I2();
while(W2) // or if() it's the same...
goto START;
I3();
}
return; // finish
Надеюсь это поможет