2017-02-14 10 views
2

У меня возникла проблема с переводом этой блок-схемы ниже на код C++.Перевести блок-схему на код C++

Flowchart

Это должно, вероятно, выглядеть примерно так (я знаю, что это неправильно сейчас):

do { 
    I1; 
    if(!W1) { 
     I2; 
    ... 
    } 
} 

I1, I2, I3 инструкции. Я думаю, что я должен использовать логические переменные, чтобы сделать это правильно, но как?

ответ

5

В блок-схеме есть петля. Условием остановки цикла является фактически W1.

while (!W1()) 
{ 
} 

I1 выполняется (на начальном этапе) независимо, и выполняется до финишной петли проверки состояния, поэтому давайте обновим код:

I1(); 
while (!W1()) 
{ 
} 

Опять же, I2 выполняется uncoditionally:

I1(); 
while (!W1()) 
{    
    I2(); 
} 

Теперь W2 влияет на выполнение I1 или I3, давайте обновим код соответственно:

I1(); // for the first, unconditional execution 
while (!W1()) 
{ 
    I2(); 
    if (W2()) 
     I1(); 
    else 
     I3(); 
} 
+0

Теперь я понимаю. Благодарю. :) –

0

Вот моя идея:

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.

1

Вы находитесь в случае двух пересекающихся петель: ни один из них не вложен в другой, поэтому обычных средств управления потоком недостаточно.
Многие обычно моделируют их с помощью искусственных булевых флагов или дублируют часть кода. Но это на самом деле одно из немногих (и я имею в виду очень мало - думаю, заранее) используются случаи 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; 
    } 
+0

Хотя это выглядит как удобный случай использования 'goto', представляя его для (скорее всего) новичка-программиста, может привести к будущим проблемам ...Представьте себе последствия, если кто-то решит инкапсулировать тело 'while' внутри функции. – hauron

+1

@hauron Добавил еще несколько предостережений в мою формулировку. Если цикл имеет смысл как отдельную функцию, тогда эта функция будет иметь два возможных состояния возврата, которые будут задокументированы и снова включены в «внешний» цикл. Фактически, другой способ, которым люди работают, используя 'goto', порождает посторонние функции, из которых они могут вернуться раньше, - но если у функции есть фактическая причина, чтобы существовать сама по себе, тогда нет никакой проблемы. – Quentin

0
START: 
I1(); 
while(!W1){ 
    I2(); 
    while(W2) // or if() it's the same... 
     goto START; 
    I3(); 
} 
return; // finish 

Я надеюсь, что это поможет