Поиск…


Синтаксис

  • / * все версии * /
  • for ([выражение]; [выражение]; [выражение]) one_statement
  • for ([выражение]; [выражение]; [выражение]) {нуль или несколько операторов}
  • while (выражение) one_statement
  • while (выражение) {нуль или несколько утверждений}
  • делать one_statement while (выражение);
  • делать {одно или несколько утверждений} while (выражение);
  • // с C99 в дополнение к форме выше
  • for (declaration; [expression]; [expression]) one_statement;
  • for (declaration; [expression]; [expression]) {zero или несколько операторов}

замечания

Итерационное заявление / Петли подразделяются на две категории:

  • управляемый итерацией оператор / петли
  • управление итерацией с педалью / петлями

Заглавие итерации с управляемой головой / петли

for ([<expression>]; [<expression>]; [<expression>]) <statement>
while (<expression>) <statement>
C99
for ([declaration expression]; [expression] [; [expression]]) statement

Операция итерации с педальным управлением / петли

do <statement> while (<expression>);

Для цикла

Чтобы снова выполнить блок кода заново, на изображение попадают петли. Цикл for должен использоваться, когда блок кода должен выполняться фиксированное количество раз. Например, чтобы заполнить массив размером n с помощью пользовательских входов, нам нужно выполнить scanf() для n раз.

C99
#include <stddef.h>          // for size_t

int array[10];               // array of 10 int

for (size_t i = 0; i < 10; i++)    // i starts at 0 and finishes with 9
{
   scanf("%d", &array[i]);
}

Таким образом, вызов функции scanf() выполняется n раз (10 раз в нашем примере), но записывается только один раз.

Здесь переменная i является индексом цикла, и ее лучше всего объявить как представленную. Тип size_t ( тип размера ) должен использоваться для всего, что подсчитывает или пересекает объекты данных.

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

C99
#include <stddef.h>        /* for size_t */
size_t i;
int array[10];             /* array of 10 int */

for (i = 0; i < 10; i++)       /* i starts at 0 and finishes at 9 */
{
   scanf("%d", &array[i]);
}

Пока цикл

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

int num = 1;

while (num != 0)
{
    scanf("%d", &num);
}

Цикл Do-While

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

Например, этот цикл do-while while будет получать числа от пользователя, пока сумма этих значений больше или равна 50 :

int num, sum;
num = sum = 0;

do 
{
  scanf("%d", &num);
  sum += num;

} while (sum < 50);

петли do-while относительно редки в большинстве стилей программирования.

Структура и поток управления в цикле for

for ([declaration-or-expression]; [expression2]; [expression3])
{
    /* body of the loop */
}

В for цикла, условие цикла имеет три выражения, все по желанию.

  • Первое выражение, выражение declaration-or-expression , инициализирует цикл. Он выполняется ровно один раз в начале цикла.
C99

Это может быть либо объявление, либо инициализация переменной цикла, либо общее выражение. Если это объявление, область действия объявленной переменной ограничена оператором for .

C99

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

  • Второе выражение, expression2 , является условием проверки . Он выполняется сначала после инициализации. Если условие true , тогда элемент управления входит в тело цикла. Если нет, то он сдвигается за пределы тела цикла в конце цикла. Впоследствии этот conditon проверяется после каждого выполнения тела, а также оператора обновления. Когда true , управление возвращается к началу тела цикла. Условие обычно предназначено для проверки количества циклов, выполняемых телом цикла. Это основной способ выхода из цикла, другой способ использования операторов перехода .
  • Третье выражение, expression3 , является оператором обновления . Он выполняется после каждого выполнения тела цикла. Он часто используется для увеличения переменной, поддерживающей подсчет количества раз, когда тело цикла выполнялось, и эта переменная называется итератором .

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

Пример:

C99
for(int i = 0; i < 10 ; i++)
{
    printf("%d", i);
}

Выход:

0123456789

В приведенном выше примере выполняется первое i = 0 , инициализирующее i . Затем проверяется условие i < 10 , которое считается true . Элемент управления входит в тело цикла и печатается значение i . Затем управление переходит к i++ , обновляя значение i от 0 до 1. Затем условие снова проверяется, и процесс продолжается. Это продолжается до тех пор, пока значение i станет равным 10. Тогда условие i < 10 оценивает значение false , после чего элемент управления выходит из цикла.

Бесконечные петли

Цикл называется бесконечным циклом, если элемент управления входит, но никогда не покидает тело цикла. Это происходит, когда тестовое условие цикла никогда не оценивается как false .

Пример:

C99
for (int i = 0; i >= 0; )
{
    /* body of the loop where i is not changed*/
}

В приведенном выше примере переменная i , итератор инициализируется равным 0. Условие испытания первоначально true . Однако i не изменяется нигде в теле, и выражение update пусто. Следовательно, i останется 0, и условие теста никогда не будет оцениваться как false , что приведет к бесконечному циклу.

Предполагая, что нет инструкций перехода, другой способ, которым может быть сформирован бесконечный цикл, заключается в явном сохранении условия true:

while (true)
{
    /* body of the loop */
}

В цикле for оператор условия необязателен. В этом случае условие всегда true пусто, что приводит к бесконечной петле.

for (;;)
{
    /* body of the loop */
}

Однако в некоторых случаях условие может сохраняться true намеренно, с намерением выйти из цикла с помощью инструкции перехода, например break .

while (true)
{
    /* statements */
    if (condition)
    {
         /* more statements */
         break;
    }
}

Прокрутка Loop и устройство Duff

Иногда прямая петля не может полностью содержаться внутри тела цикла. Это связано с тем, что цикл должен быть загружен некоторыми операторами B. Затем итерация начинается с некоторых операторов A , которые затем следуют за B перед циклом.

do_B();
while (condition) {
    do_A();
    do_B();
}

Для того, чтобы избежать возможных проблем вырезать / вставить с повторяющимися B дважды в коде, устройство Дафф может быть применен , чтобы начать цикл от середины в while тело, с помощью переключателя заявление и провалиться поведения.

switch (true) while (condition) {
case false: do_A(); /* FALL THROUGH */
default:    do_B(); /* FALL THROUGH */
}

Устройство Duff было изобретено для развертывания цикла. Представьте, что вы применяете маску к блоку памяти, где n - тип подписанного интеграла с положительным значением.

do {
    *ptr++ ^= mask;
} while (--n > 0);

Если n всегда делится на 4, вы можете легко развернуть это:

do {
    *ptr++ ^= mask;
    *ptr++ ^= mask;
    *ptr++ ^= mask;
    *ptr++ ^= mask;
} while ((n -= 4) > 0);

Но, с помощью устройства Даффа, код может следовать за этой разворачивающейся идиомой, которая прыгает в нужное место в середине цикла, если n не делится на 4.

switch (n % 4) do {
case 0: *ptr++ ^= mask; /* FALL THROUGH */
case 3: *ptr++ ^= mask; /* FALL THROUGH */
case 2: *ptr++ ^= mask; /* FALL THROUGH */
case 1: *ptr++ ^= mask; /* FALL THROUGH */
} while ((n -= 4) > 0);

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



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow