Какое условие является предпочтительным в цикле? - PullRequest
7 голосов
/ 25 января 2009
int n = 5;
for(int i = 0;i!=n;i++)//condition !=
{
//executing 5times
}

int n = 5;
for(int i = 0;i<n;i++)//condition <
{
//executing 5times

}

Какой из них предпочтительнее?

Это был пример из "Ускоренного C ++" : практическое программирование на примере / Эндрю Кениг, Барбара Э. Му. "Просто хотел знать, почему автор предпочитает первый

Ответы [ 12 ]

14 голосов
/ 25 января 2009

второй. По двум причинам

  1. Меньше чем (или иногда <=) - это обычный способ, которым большинство кодеров пишут их, и лучше придерживаться соглашения, если это возможно -! =, Вероятно, заставит большинство кодеров дважды взглянуть, чтобы проверить, есть ли что-то нечетное в цикле, тогда как <будет немедленно понято. </p>

  2. ! = Зависит от точного условия. Если внутренняя часть цикла изменяется во время технического обслуживания, и я случайно увеличиваю ее внутри цикла, то получается бесконечный цикл. Как правило, всегда лучше сделать условие завершения максимально широким - оно просто более устойчиво.

2, конечно, причина, почему 1.

3 голосов
/ 25 января 2009

Использование condition < намного лучше, потому что оно уменьшает вероятность перешагнуть через ваше дозорное значение и попасть в бесконечный цикл.

3 голосов
/ 25 января 2009

Я бы сказал <, поскольку он охватывает более широкий набор условий. Предположим, что n не является константой, а возвращается из функции, которая в редких случаях возвращала -1. В этом случае у вас будет гораздо более длинный цикл (пока int не обернется до значения -ve!) С версией цикла!

2 голосов
/ 25 января 2009

Как указано в вопросе, оба цикла эквивалентны. Однако в реальном коде типично, что все немного сложнее, и в этом случае условие «i

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

int n = 5;
int i = 0;
while (i != n) {
    int old_i = i;
    // the real stuff of the loop here
   ++i;
   assert(i == old_i + 1);
}

(Или, что еще лучше, используйте язык, который поддерживает синтаксис, для указания предварительных и постусловий и циклических инвариантов.)

Книга Эндрю Кенига "Ловушки и ловушки" (см. http://en.wikipedia.org/wiki/C_Traps_and_Pitfalls для начала) вам, вероятно, интересно, если вы хотите поразмышлять над этим вопросом.

1 голос
/ 25 января 2009

Я бы предпочел использовать <, поскольку, просто взглянув на код, вы можете сказать, что его цикл увеличивается, это подтверждает тот факт, что вы используете i ++. </p>

Если вы используете i ++ и <и по какой-то причине (другой кодер, опечатка, ошибка человека) ваш код меняет приращение на i - вы сразу узнаете, что цикл не оценивается, как с! = это будет работать в любом случае, делая его менее тривиальным для отладки. </p>

1 голос
/ 25 января 2009

второй. Он всегда завершится в какой-то момент (при условии, что вы не делаете ничего смешного, как игра со значением счетчика внутри цикла).

Я никогда не видел первый использованный, по крайней мере, не таким образом.

1 голос
/ 25 января 2009

Я обычно делаю второй способ, используя <. Но подумайте об использовании! =, Поскольку итераторы stl в c ++ работают таким образом. </p>

1 голос
/ 25 января 2009

<n является наиболее часто используемым (мое мнение)

0 голосов
/ 25 января 2009

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

Loop, , пока я меньше , чем n

Который, я думаю, легче читать большинству программистов, включая меня. Если вы не знаете тип переменной итератора, вам следует сделать как можно меньше предположений о ее возможностях. operator< может быть недоступно для i: если это какой-либо итератор, отличный от итератора с произвольным доступом, operator< не гарантированно будет доступен. В этом случае я бы использовал operator!=.

Я бы не стал выбирать опцию < только потому, что вы могли случайно «перешагнуть» конечное значение. Я думаю, что аргумент неверен. Потому что, если вы случайно перешли, это ошибка, и ее следует заметить как можно скорее ( Fail-fast ).

0 голосов
/ 25 января 2009

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

int n = 5;
for(int i = n;i > 0;i--)
{
//executing 5times
}

Причина в том, что сравнение с 0 выполняется быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...