2009-09-04 4 views
5

ПохожиЛюбые причины для замены while (condition) with for (; condition;) в C++?

while(condition) { 
    //do stuff 
} 

полностью эквивалентен

for(; condition;) { 
    //do stuff 
} 

Есть ли какая-либо причина, чтобы использовать последнюю вместо прежнего?

+3

Оба образца кода являются правильными и делают то же самое. Но нет смысла использовать второй оператор. Когда есть правильный синтаксис avaialbe, почему вы хотите использовать второй. Тогда только причина использовать второй оператор - это знать код разного типа, и я думаю, что его следует использовать только в образовательных целях. –

+1

Я видел последнее в одном проекте и хотел бы знать причины, по которым он мог появиться. – sharptooth

+0

Народные идеи стиля отличаются, часто резко и часто способами, которых я не ожидал. Кто-то, возможно, хотел стандартизировать инструкцию for для всех циклов, по какой-то причине это, казалось, имело смысл в то время. Нет никакой функциональной разницы. –

ответ

23

Нет good Причина, насколько мне известно. Вы намеренно вводите людей в заблуждение, используя for-loop, который ничего не увеличивает.

Update:

Основываясь на замечании ФПА к вопросу, я могу рассуждать о том, как вы могли бы видеть такую ​​конструкцию в реальном коде. Я видел (и используется) это раньше:

lots::of::namespaces::container::iterator iter = foo.begin(); 
for (; iter != foo.end(); ++iter) 
{ 
    // do stuff 
} 

Но это, насколько я пойду с оставлением вещи из-за петли. Возможно, в вашем проекте была петля, которая выглядела так же, как в одно время. Если вы добавите код, который удаляет элементы контейнера в середине цикла, вам, вероятно, придется тщательно контролировать, как увеличивается iter. Это может привести к коду, который выглядит следующим образом:

for (; iter != foo.end();) 
{ 
    // do stuff 

    if (condition) 
    { 
     iter = foo.erase(iter); 
    } 
    else 
    { 
     ++iter; 
    } 
} 

Однако, это не повод не принимать пять секунд, необходимых для изменения его в то время как петли.

1

Если вы хотите сделать что-то ограниченное количество раз, то «для» давайте укажем ограничение, не смешивая его с логикой внутри вашего цикла.

4

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

2

В этом случае я лично предпочитаю первый цикл, так как его легче писать и читать.

Но если у меня есть цикл, который нуждается в какой-то пост заявления, я хотел бы использовать цикл, как это:

for (; i < 10; i += 2) 
2

Там могут быть небольшие компилятором в зависимости от различий на уровне сборки, но в идеале и должны ведут себя точно так же, и первое более читаемо. Так что нет, нет резона использовать последнюю версию, отличную от нонконформизма.

2

Скомпилируйте и проверьте полученную разборку, если они такие же (что они, вероятно, есть). Выберите тот, который вы найдете наиболее читаемым.

1

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

Для настольных приложений вы можете выбрать на основе критериев читаемости. См. Другие сообщения - например, глядя на цикл, кто-то думает, что инкрементер объявлен в цикле.

Кажется, что для веб-приложений, например, скрипты на стороне клиента могут быть разными.

Проверить этот сайт: http://www.websiteoptimization.com/speed/10/10-2.html

Выполнить свои собственные эксперименты и идти по результатам еще палкой по правилам читаемости.

+0

Вопрос явно спросил о C++ ... – DevSolar

+0

@sharptooth: И могу ли я держать ваш кошелек, пока вы выполняете эти эксперименты? –

3

Это можно компилировать

for(INIT; CONDITION; UPDATE) 
{ 
    BODY 
} 

в

{ 
    INIT 
    while(CONDITION) 
    { 
    BODY 
    UPDATE 
    } 
} 

UPDATE: Казалось бы, излишними дополнительные сфера является сепаратором любые определения переменных в INIT, то есть от for(int i = 0; ...). Благодаря!

Это в основном просто переупорядочение выражений. Поэтому нет причин предпочитать одну из них по соображениям производительности. Я бы порекомендовал while(), если это возможно, так как это проще. Если более простая конструкция выражает то, что вы хотите сделать, я думаю, что это единственное, что нужно использовать.

+3

Помните, что в последнем случае выражение 'continue' имеет другую семантику. – Juliano

+3

Сфера применения INIT отличается. –

+0

Не только это возможно, оно также определено в стандарте таким образом, см. Мой ответ на дубликат этого вопроса здесь: http://stackoverflow.com/questions/885908/while-1-vs-for-is-there -a выдержки разница/887298 # 887298. –

1

Я вижу 2 причины, ни один из которых я бы рассмотреть:

  • имеют только 1 конструкцию петли, но возражение Kristo в стенды
  • записи "для (; EVER;)", но потом предпочитайте макрос LOOP_FOREVER, если хотите.
+2

Макросы злы. ;-) – DevSolar

+0

'for (; EVER;)' == 'while (true)' :) – suszterpatt

+0

@suszterpatt Это чтение «навсегда». @DevSolar: как насчет BOOST_FOREACH? – stefaanv

6

Нет Нет Нет

Даже если бы разница микроскопическая производительности, вы должны были бы быть в конечной стадии тюнер Jedi производительности, чтобы это достаточно важно, чтобы заботиться.

+1

И даже если бы была какая-либо разница в производительности, использование последнего все равно просто работало бы вокруг ошибки компилятора (не удалось оптимизировать цикл while). –

+0

+1 для «полнофункционального тюнера Jedi Performance» – DVK

+2

Должен быть тюнер производительности Sith. Поскольку все оптимизации уровня кода, подобные этому, являются злыми. –

1

На самом деле нет разницы в языках C-ish между циклами for (; cond;) и циклом while. Как правило, то, что я делаю на языках C-ish, начинается с написания цикла как «for» и меняет его на «while», если я получаю эту форму. Это редкость, хотя, поскольку вы всегда повторяете через что-то, а C позволяет помещать любой код, который вы хотите в этой последней области.

Было бы иначе, если бы у C было real (предварительно вычисленная итерация) для петель.

2

Я думаю, что петли «в то время» и «для» предназначены для разных идиом. Идиома использования «while» - это «что-то делать, а определенные условия верны». Идиома для «for» - это «итерация по определенному диапазону элементов» ...

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

Во всяком случае, это очень субъективно ...

8

Некоторые компиляторы предупреждают о постоянных условиях цикла:

while (true) { /* ... */ } /* Warning! */ 
for (;;) { /* ... */ } /* No warning */ 

В конкретном случае бесконечного цикла, я мог бы выбрать для перебрать некоторое время петля по этой причине. Но если условие не пустое, я не вижу никакой пользы. Мое предположение о том, почему в упомянутом проекте появилось, заключается в том, что код каким-то образом эволюционировал благодаря обслуживанию, но был написан более традиционным способом изначально.

1

Возможно, вы захотите использовать цикл do-while вместо цикла for, чтобы код обрабатывался как минимум один раз, прежде чем условия будут проверены и выполнены (или нет).

6

Есть ли причина использовать последние вместо прежних?

  1. ошибочная попытка произвести впечатление на своих коллег, что вы знаете, что эти две формы эквивалентны.
  2. Глупый маневр, обеспечивающий «безопасность работы», делая ваш код настолько запутанным, насколько это возможно, чтобы никто не захотел его изменить.
  3. Клавиша «w» на клавиатуре сломана.
  4. Он начал жизнь как цикл цикла с инициализаторами и приращением состояния, и когда логика изменилась, разработчик был слишком занят, чтобы изменить его.
+2

+1 для # 3! (добавьте больше символов, чтобы прошло 15) –

1

Я использовал для написания довольно загадочного кода C/C++. Оглядываясь назад, я бы, вероятно, сделать это в цикле в то время:

ifstream f("file.txt"); 
char c; 
for(f.get(c); !f.eof(); f.get(c)) { 
    // ... 
} 

Я думаю, моя точка является то, что для петель, как правило, короче, но менее читаемым, если они не используются в традиционном смысле этого цикла в диапазоне ,

1

Этот вопрос был дан ответ - язык имеет более естественную конструкцию для выражения того, что вы хотите - вы должны использовать его. Например, я могу, конечно, написать это:

for (bool b = condition(); b; b = !b) { 
    /* more code */ 
} 

или:

while (condition()) { 
    /* more code */ 
    break; 
} 

вместо более обычного:

if (condition()) { 
    /* more code */ 
} 

Но почему? C (и все языки) имеют идиомы, и большинство из них делают рациональный смысл с точки зрения выразительности и ожидания смысла. Когда вы стучите с идиомой, ваш беспорядок с чувствами человека, который должен прочитать ваш код.