Если все, что вам нужно, это простой счетный цикл, тогда
for (i=0; i<100; i++) dostuff();
будет хорошо, и компилятор может оптимизировать его.
Если вы используете функцию в части continue для оператора for, например
for (i=0; i<strlen(s); i++) dostuff();
тогда функция будет оцениваться каждый раз, и это, как правило, не очень хорошая идея, поскольку издержки функции замедляют ваш процесс. Иногда это может замедлить ваш процесс до такой степени непригодности.
Если возвращаемое значение функции не изменится во время итерации, извлеките его из цикла:
slen = strlen(s);
for (i=0; i<slen; i++) dostuff();
Но бывают случаи, когда функция будет возвращать разные значения при каждом вызове, и тогда вы не хотите, чтобы она извлекалась из цикла:
for (isread(fd, &buffer, ISFIRST);
isstat(fd) >= 0;
isread(fd, &buffer, ISNEXT)
{
dostuff(buffer);
}
и вы хотите, чтобы его оценивали каждый раз. (Это немного надуманный пример, основанный на работе, которую я выполняю, но она показывает потенциал).
C дает вам грубую способность катить петлю любым доступным способом. Вы должны знать, как должен работать ваш цикл, и оптимизировать его как можно лучше, в зависимости от ваших потребностей.
Последний пример можно было бы выразить как цикл while:
isread(fd, &buffer, ISFIRST);
while (isstat(fd) >= 0)
{
dostuff(buffer);
isread(fd, &buffer, ISNEXT);
}
но это не так аккуратно, и если я использую продолжение в цикле, то я должен снова вызвать итерацию isread. Помещение всего этого в цикл for делает его более аккуратным и гарантирует, что итерация isread называется каждым циклом.
Я пишу функции более низкого уровня, чтобы их можно было использовать для таких циклов. Он объединяет все элементы цикла while, чтобы вам было легче его понять.