Первый - идиоматический путь; это то, что ожидает большинство C-кодеров. Тем не менее, я должен отметить, что большинство людей также ожидают увидеть
for(i = 0; i < a; i++)
Обратите внимание, что цикл начинается с нуля. Это будет делать что-то a
раза. Если вы собираетесь написать цикл while
, который эквивалентен циклу for
, как указано выше, я настоятельно рекомендую вам написать его как цикл for
. Опять же, именно это ожидают увидеть C-кодеры. Кроме того, как цикл for
легче читать, поскольку все (инициализация, условие цикла, выражение, которое будет выполнено после каждой итерации) находятся в одной строке. Для цикла while
они разложены, что затрудняет чтение.
Обратите внимание, однако, есть обстоятельства, при которых кажущиеся эквивалентными циклы for
и while
фактически не являются. Например:
for(i = 0; i < 10; i++) {
if(i == 5) continue;
printf("%d\n", i);
}
и
i = 0;
while(i < 10) {
if(i == 5) continue;
printf("%d\n", i);
i++;
}
на первый взгляд кажутся эквивалентными, но это не так. Цикл for
напечатает 0--9
пропуск 5
на консоли, тогда как цикл while
выведет 0--4
на консоли и затем введет бесконечный цикл.
Теперь, это обрабатывает простой случай, о котором вы спрашивали. А как насчет более сложных случаев, о которых вы не спрашивали? Ну, это действительно зависит, но хорошее эмпирическое правило таково: если вы собираетесь повторять что-то фиксированное заранее определенное количество раз, цикл for
обычно лучше. В противном случае используйте петлю while
. Это не жесткое правило, но хорошее практическое правило. Например, вы можете написать
unsigned int v;
unsigned int c;
for(c = 0; v; v >>= 1) c += v & 1;
но я думаю, что большинство программистов на С написали бы это как
unsigned int v;
unsigned int c;
c = 0;
while(v) { c += v & 1; v >>= 1; }
Или, в качестве другого примера, если вы собираетесь читать до конца файла, вам следует использовать цикл while
. Таким образом
FILE *fp;
fp = fopen(path, "r");
while(fgets(buf, max, fp) != NULL) { /* something */ }
вместо
FILE *fp;
for(fp = fopen(path, "r"); fgets(buf, max, fp) != NULL; ) { /* something */ }
Теперь, достигнув религиозной территории, именно поэтому я предпочитаю while(1)
как правильный способ сделать бесконечный цикл над for(;;)
.
Надеюсь, это поможет.