Любая причина заменить, в то время как (условие) для (;состояние;) в C++?

  • Крошечные понятные классы. Многие из них.
  • Крошечные понятные Методы.
  • Неизменный по мере возможности.
  • Минимизируют объем - ничто общедоступное, которое может быть пакетом, ничто пакет, который может быть частным.
  • никогда любое оправдание за общедоступную изменяемую переменную.

кроме того, то, когда Ваши классы являются крошечными и обычно окончательными, будучи защитными, действительно дешево - мог бы также добавить его независимо от того, если Вы верите в него или нет. Протестируйте значения, передаваемые Вашим конструкторам и (если у Вас действительно ДОЛЖНЫ быть они), методы set.

5
задан sharptooth 4 September 2009 в 13:26
поделиться

17 ответов

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

Обновление:

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

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

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

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

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

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

23
ответ дан 18 December 2019 в 05:11
поделиться

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

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

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

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

или:

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

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

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

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

  • Имеется только 1 конструкция цикла, но тогда возражение Кристо остается в силе
  • напишите «for (; EVER;)» , но затем предпочитайте макрос LOOP_FOREVER, если действительно этого хотите.
1
ответ дан 18 December 2019 в 05:11
поделиться

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

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

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

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

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

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

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

2
ответ дан 18 December 2019 в 05:11
поделиться

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

1
ответ дан 18 December 2019 в 05:11
поделиться

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

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

for (; i < 10; i += 2)
2
ответ дан 18 December 2019 в 05:11
поделиться

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

2
ответ дан 18 December 2019 в 05:11
поделиться

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

for(INIT; CONDITION; UPDATE)
{
  BODY
}

в

{
  INIT
  while(CONDITION)
  {
    BODY
    UPDATE
  }
}

ОБНОВЛЕНИЕ: кажущаяся избыточной дополнительная область видимости заключается в том, чтобы поместить любые определения переменных в INIT, то есть из для (int i = 0;. ..) . Спасибо!

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

5
ответ дан 18 December 2019 в 05:11
поделиться

Нет. Нет. Нет.

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

7
ответ дан 18 December 2019 в 05:11
поделиться

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

2
ответ дан 18 December 2019 в 05:11
поделиться

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

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

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

8
ответ дан 18 December 2019 в 05:11
поделиться

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

  1. Неправильная попытка внушить своим коллегам, что вы знаете, что эти две формы эквивалентны.
  2. Глупый маневр для обеспечения «безопасности работы», делая ваш код настолько запутанным, насколько это возможно, чтобы никто не мог
  3. Клавиша "w" на вашей клавиатуре сломана.
  4. Он начал свою жизнь как цикл for с инициализаторами и условием увеличения, и когда логика изменилась, разработчик был слишком занят, чтобы изменить его .
8
ответ дан 18 December 2019 в 05:11
поделиться

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

4
ответ дан 18 December 2019 в 05:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: