2010-12-06 3 views
3

Я недавно сталкивался с этим кодом:Является ли конструкция do .. while (false) способствующей лучшему потоку управления?

do { 
    if (! checkSomething()) 
     break; 

    // some code 

    if (! checkSomeOtherThing()) 
     break; 

    // some other code 
} while(false); 

// some final code 

Программиста, который написал, написал комментарий по линиям "cleaner control flow".

На мой взгляд, исходный код может выглядеть лучше, если его реорганизовать во что-то другое. Но есть ли в этом утверждении правда? Является ли эта конструкция хорошей?

+2

В «что-то еще». Как именно мы должны судить об этом, если вы не определили «что-то еще»? – 2010-12-06 00:08:34

+1

Я бы сказал, что это не лучше, чем поставить «goto» перед «некоторым окончательным кодом» и перейти к нему; по крайней мере, с goto ярлык явно. Этот код просто странный. – 2010-12-06 00:11:42

+0

@ sje397 это может выглядеть как петля, но это не так. См. Условие цикла. – robert 2010-12-06 00:12:07

ответ

2

Если вы не возражаете против циклов, содержащих несколько операторов break, тогда единственная проблема заключается в том, что C (по очевидным причинам) не позволяет вам вырваться из голого блока, следовательно, это «не-цикл», который некоторые ничего не подозревающий будущий сопровождающий мог ошибиться для реального цикла.

соображения, я думаю, являются:

  • если есть только две точки break, что так плохо о два if заявления?
  • Если есть более двух точек останова, то отступы с заявлениями if могут стать неприятными, и это экономит это, но опять же функция слишком много? И даже если нет, было бы лучше просто использовать goto и избежать странности петли, которая не петляет?

Поскольку вы отметите этот язык агностик, я имел обыкновение использовать macroised язык ассемблера, с block ... endblock, что вы могли бы вырваться из. Это приводит к достаточно хороший код для проверки необходимых условий, таких как:

block 
    breakif str1 == null 
    breakif str2 == null 
    get some combined property of str1 and str2 
    breakif some other condition that stops us getting on with it 
    get on with it 
endblock 

На самом деле, это было не breakif str1 == null, это было breakifeq.p str1, null, или что-то подобное, но я забыл, что именно.

6

Я нахожу это гораздо легче читать, и он производит одинаковый результат:

if (checkSomething()) 
{ 
    // some code 
    if (checkSomeOtherThing()) 
    { 
     // some other code 
    } 
} 
// some final code 

Я думаю do ... while обычно трудно следовать, но использовать его для чего-то другого, чем цикл вводит в заблуждение в лучшем случае.

3

Это эквивалентно goto.

В таких ситуациях лучше использовать goto, чем использовать уродливый хак.

Изменение его использовать goto делает его гораздо более удобным для чтения:

if (!checkSomething()) 
    goto Done; 

// some code 

if (!checkSomeOtherThing()) 
    goto Done; 

// some other code 
Done: //some final code 
0

Я видел сделай, а форма, принятая в качестве стандарта, к которому соответствовали кодеры. Преимущество состоит в том, что он передает и реализует, что цикл всегда будет выполняться хотя бы один раз. Это помогает изолировать, с последовательностью, ситуации, когда происходит что-то другое, то есть где код в цикле не выполняется.

Этот стандарт был принят, поскольку применялась техника Warnier-Orr.