Для vs. while в программировании на C?

В C есть три петли: for, while и do-while. Какая разница между ними?

Например, кажется, что почти все операторы while могут быть заменены операторами for, правильно? Тогда какое преимущество имеет использование while?

Ответ 1

A while цикл всегда будет сначала оценивать условие.

while (condition) {
  //gets executed after condition is checked
}

A do/while цикл всегда будет выполняться  сначала код в блоке do{} а затем оцените условие.

do {
  //gets executed at least once
} while (condition); 

A для цикла позволяет вам инициировать переменную счетчика, условие проверки и способ увеличить ваш счетчик в одной строке.

for (int x = 0; x < 100; x++) {
   //executed until x >= 100
}

В конце концов, все они все еще петли, но они предлагают некоторую гибкость в отношении того, как они выполняются.

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

Основное различие между for 's и while - вопрос прагматика: мы обычно используем for, когда существует известное количество итераций, и используйте конструкции while, когда количество итераций, неизвестных в авансовый. while vs do ... whileпроблема также связана с прагматикой, второй выполняет инструкции один раз в начале, а затем ведет себя как и просто.


Для петель особенно приятно, потому что они кратки. Для этого для цикла

for (int x = 0; x < 100; x++) {
   //executed until x >= 100
}

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

int count = 0;
while (count < 100) {
  //do stuff
  count++;
}

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


Для полноты, вероятно, имеет смысл говорить о инструкциях break и continue, которые пригождаются при обработке цикла.

break мгновенно завершает текущий цикл и больше не будет выполняться итераций.

//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
  if (x == 2) {
    break;
  }
  //do stuff
}

continue завершает текущую итерацию и переходит к следующей.

//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
  if (x == 2) {
    continue;
  }
  //do stuff
}

Обратите внимание, что в цикле for 'continue' оценивает выражение 'part3' 'for (part1; part2; part3)'; напротив, в цикле while он просто перескакивает, чтобы переоценить условие цикла.

Ответ 2

Если есть серьезная обеспокоенность в отношении скорости и производительности, наилучшим подходом является проверка кода, созданного компилятором на уровне сборки.

Например, следующий код показывает, что "делать-пока" немного быстрее. Это потому, что команда "jmp" не используется циклом "do-while".

Кстати, в этом конкретном примере наихудший случай задается циклом "для".:))

int main(int argc, char* argv[])
{
    int i;
    char x[100];

    // "FOR" LOOP:
    for (i=0; i<100; i++ )
    {
        x[i] = 0;
    }

    // "WHILE" LOOP:
    i = 0;
    while (i<100 )
    {
        x[i++] = 0;
    }

    // "DO-WHILE" LOOP:
    i = 0;
    do
    {
        x[i++] = 0;
    }
    while (i<100);

    return 0;
}

// "FOR" LOOP:

    010013C8  mov         dword ptr [ebp-0Ch],0
    010013CF  jmp         wmain+3Ah (10013DAh)

  for (i=0; i<100; i++ )
  {
      x[i] = 0;
    010013D1  mov         eax,dword ptr [ebp-0Ch]  <<< UPDATE i
    010013D4  add         eax,1
    010013D7  mov         dword ptr [ebp-0Ch],eax
    010013DA  cmp         dword ptr [ebp-0Ch],64h  <<< TEST
    010013DE  jge         wmain+4Ah (10013EAh)     <<< COND JUMP
    010013E0  mov         eax,dword ptr [ebp-0Ch]  <<< DO THE JOB..
    010013E3  mov         byte ptr [ebp+eax-78h],0
    010013E8  jmp         wmain+31h (10013D1h)     <<< UNCOND JUMP
  }

// "WHILE" LOOP:

  i = 0;
  010013EA  mov         dword ptr [ebp-0Ch],0
  while (i<100 )
  {
      x[i++] = 0;
    010013F1  cmp         dword ptr [ebp-0Ch],64h   <<< TEST
    010013F5  jge         wmain+6Ah (100140Ah)      <<< COND JUMP
    010013F7  mov         eax,dword ptr [ebp-0Ch]   <<< DO THE JOB..
    010013FA  mov         byte ptr [ebp+eax-78h],0
    010013FF  mov         ecx,dword ptr [ebp-0Ch]   <<< UPDATE i
    01001402  add         ecx,1
    01001405  mov         dword ptr [ebp-0Ch],ecx
    01001408  jmp         wmain+51h (10013F1h)      <<< UNCOND JUMP
  }

// "DO-WHILE" LOOP:

i = 0;
.  0100140A  mov         dword ptr [ebp-0Ch],0
  do
  {
      x[i++] = 0;
    01001411  mov         eax,dword ptr [ebp-0Ch]   <<< DO THE JOB..
    01001414  mov         byte ptr [ebp+eax-78h],0
    01001419  mov         ecx,dword ptr [ebp-0Ch]   <<< UPDATE i
    0100141C  add         ecx,1
    0100141F  mov         dword ptr [ebp-0Ch],ecx
    01001422  cmp         dword ptr [ebp-0Ch],64h   <<< TEST
    01001426  jl          wmain+71h (1001411h)      <<< COND JUMP
  }
  while (i<100);

Ответ 3

Для удобства чтения

Ответ 4

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

Ответ 5

Если вы хотите, чтобы цикл выполнялся, когда условие истинно, а не для определенного количества итераций, намного легче понять кому-то другому:

while (cond_true)

чем-то вроде этого:

for (; cond_true ; )

Ответ 6

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

while <some condition is true> {
   // do some stuff
   // possibly do something to change the condition
}


for ( some var, <some condition is true>; increment var ) {

}

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

Цикл

A while более понятен, если вы не выполняете стандартный инкрементный шаблон. Например:

int x = 1;
while( x != 10 ) {
  if ( some condition )
     x = 10;
  else 
     x += 5;
}

Ответ 7

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

for(int i = 0; i < 10; i++)
{
    print(i);
}

//or

int i = 0;
while(i < 10)
{
    print(i);
    i++;
}

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

Извините за мой плохой английский).

Ответ 8

A for предлагают фиксированную итерацию с использованием индекса или вариантов на этой схеме.

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

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

Ответ 9

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

Циклы

for - это просто синтаксически sugared while петли и сделать код итерации быстрее для записи.

Когда компилятор принимает ваш код и компилирует его, он преобразует его в форму, которая легче понять и выполнить компьютер на более низком уровне (сборка). Во время этого перевода тонкие различия между синтаксисами while и for теряются, и они становятся точно такими же.

Ответ 10

Я заметил некоторое время назад, что цикл For обычно генерирует еще несколько машинных команд, чем цикл while. Однако, если вы внимательно посмотрите на примеры, которые отражают мои наблюдения, разница в двух или трех машинных инструкциях вряд ли стоит особо рассмотреть.

Заметьте также, что инициализатор цикла WHILE можно исключить, выпекая его в код, e. г:.

static int intStartWith = 100;

Статический модификатор выпекает начальное значение в коде, сохраняя (барабанную ручку) одну инструкцию MOV. Большее значение, отмечая переменную как статическую, перемещает ее за рамки стека. При разрешении выравнивания по переменной он может также создавать немного меньший код, так как команда MOV и ее операнды занимают больше места, чем, например, целочисленное, логическое или символьное значение (ANSI или Unicode).

Однако, если переменные выровнены по 8-байтным границам, общий параметр по умолчанию, int, bool или TCHAR, испеченный в код, стоит столько же байтов, сколько инструкция MOV.

Ответ 11

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

Ответ 12

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

Конечно, вы можете написать цикл while как do-while и vv, но для этого обычно требуется дублирование кода.

Ответ 13

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

Одно объяснение среди других

Ответ 14

Для циклов (по крайней мере, учитывая C99) лучше, чем в цикле while, потому что они ограничивают область увеличиваемой переменной (ов).

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

Ответ 15

Между тем и временем: while не требуется инициализация или инструкция обновления, поэтому она может выглядеть лучше, более элегантно; for может иметь отсутствующие утверждения, два или все, поэтому он является наиболее гибким и очевидным, если вам нужно инициализировать, зацикливать условие и "обновить" перед циклом. Если вам нужно только условие цикла (проверено в начале цикла), то while является более элегантным.

Между параметрами for/while и do-while: in do-while условие оценивается в конце цикла. Более комфортно, если цикл должен выполняться хотя бы один раз.

Ответ 16

Они почти одинаковы, за исключением цикла do-while. Цикл for хорош, если у вас есть переменная типа counter. Это делает его очевидным. Цикл while имеет смысл в случаях, когда флаг проверяется как показано ниже:

while (!done) {
   if (some condtion) 
      done = true;
}

Ответ 17

WHILE более гибкий. FOR более кратким в тех случаях, когда он применяется.

FOR отлично подходит для циклов, у которых есть счетчик какого-то типа, например

for (int n=0; n<max; ++n)

Вы можете сделать то же самое с WHILE, конечно, как указывали другие, но теперь инициализация, тест и приращение разбиваются на три строки. Возможно, три широко разделенные линии, если тело петли велико. Это затрудняет для читателя, что вы делаете. В конце концов, хотя "++ n" является очень распространенной третьей частью FOR, это, конечно, не единственная возможность. Я написал много циклов, где пишу "n + = increment" или более сложное выражение.

FOR также может отлично работать с вещами, отличными от счетчика, конечно. Как

for (int n=getFirstElementFromList(); listHasMoreElements(); n=getNextElementFromList())

Etc.

Но FOR ломается, когда логика "в следующий раз через цикл" усложняется. Рассмотрим:

initializeList();
while (listHasMoreElements())
{
  n=getCurrentElement();
  int status=processElement(n);
  if (status>0)
  {
    skipElements(status);
    advanceElementPointer();
  }
  else
  {
    n=-status;
    findElement(n);
  }
}

То есть, если процесс продвижения может отличаться в зависимости от условий, возникающих при обработке, выражение FOR непрактично. Да, иногда вы можете заставить его работать с достаточно сложными выражениями, использовать тернарный?: Оператор и т.д., Но это обычно делает код менее читаемым, а не читаемым.

На практике большинство моих циклов либо проходят через массив или структуру какого-либо типа, и в этом случае я использую цикл FOR; или читают файл или результирующий набор из базы данных, и в этом случае я использую цикл WHILE ( "while (! eof())" или что-то в этом роде).

Ответ 18

/* while loop

5 долларов

1 шоколад = 1 бакс

while my money is greater than 1 bucks 
  select chocolate
  pay 1 bucks to the shopkeeper
  money = money - 1
end

приходите домой и не можете пойти во время магазина, потому что мои деньги = 0 баксов */

#include<stdio.h>
int main(){
  int money = 5;

  while( money >= 1){   
    printf("inside the shopk and selecting chocolate\n");
    printf("after selecting chocolate paying 1 bucks\n");
    money = money - 1 ;  
    printf("my remaining moeny = %d\n", money);
    printf("\n\n");
  }

  printf("dont have money cant go inside the shop, money = %d",  money);

  return 0;
} 

бесконечные деньги

while( codition ){ // condition will always true ....infinite loop
  statement(s)
}

пожалуйста, посетите это видео для лучшего понимания https://www.youtube.com/watch?v=eqDv2wxDMJ8&t=25s

/* для цикла

5 долларов

for my money is greater than equal to 1 bucks   0      money >= 1
  select chocolate
  pay 1 bucks to the shopkeeper
  money = money - 1  1-1 => 0
end

*/

#include<stdio.h>
int main(){

  int money = 5;
  for( ; money >= 1; ){     0>=1  false 
    printf("select chocolate \n");
    printf("paying 1 bucks to the shopkeeper\n");
    money = money - 1;    1-1 = 0
    printf(" remaining money =%d\n", money);
    printf("\n\n");
  }

  return 0;
}

Для лучшего понимания посетите https://www.youtube.com/watch?v=_vdvyzzp-R4&t=25s

Ответ 19

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

Ответ 20

Операторы

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

Используйте любой цикл, который вам нравится. Тем не менее, цикл do...while может быть несколько сложным в программировании на C.