Files
freeCodeCamp/guide/russian/c/loops/index.md
2019-08-07 15:04:26 -07:00

23 KiB
Raw Blame History

title, localeTitle
title localeTitle
Loops of all kinds Различные циклы

Различные циклы в C

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

Они могут быть подразделены на:

(a) Циклы с предусловием - циклы, в которых условие проверяется перед каждой итерацией, напр. цикл for, цикл while

(b) Циклы с постусловием - циклы, в которых тело выполнятся единожды даже если условие ложно, напр. цикл do-while

Циклы while

Циклы while - cамые простые из перечисленных. Их тело выполняется пока условие в скобках истинно. Их следует использовать в том случае, когда вы хотите, чтобы что-то происходило до наступления определенного условия.

Синтаксис

while(condition) { 
   statement(s); 
 } 

Пример:

#include <stdio.h> 
 
 int main(void) { 
    int my_number = 0; 
 
    while(my_number != 10){ 
        ++my_number; 
    } 
 
    printf("my_number = %i", my_number); 
 
    return 0; 
 } 

Пока условие в цикле while истинно, будет происходить выполнение содержимого фигурных скобок. Когда программа выполняет строку while(my_number) , она проверяет выражение в круглых скобках. Если это выражение ложно, цикл while не будет запущен. Вместо этого программа пропустит код между фигурными скобками и пойдет далее.

Если выражение истинно, код в фигурных скобках будет запущен. Как только его выполнение завершится, выражение в скобках будет проверено снова. Как и раньше, если выражение истинно, код будет запущен, если ложно, код будет пропущен.

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

while(1) { 
    printf("This will get printed forever unless the program is stopped!"); 
 } 

Конечно, это может произойти и случайно. Вот тот же код, что и раньше, но с незаметным отличием, которое превращает его в бесконечный цикл:

#include <stdio.h> 
 
 int main(void) { 
    int my_number = 11; 
 
    while(my_number != 10){ 
        ++my_number; 
    } 
 
    printf("my_number = %i", my_number); 
 
    return 0; 
 } 

Когда будет запущен цикл while, переменная my_number будет проверена на равенство 10. Это не так, поскольку она была инициализирована числом 11, поэтому код тела цикла while будет запущен, а my_number примет значение 12. 12 не равно 10, поэтому код тела цикла while будет запущен, а my_number примет значение 13. Это будет продолжаться вечно, потому что это условие никогда не станет ложным, единственный способ остановить цикл - принудительно завершить программу. Это пример бесконечного цикла, потому что без вмешательства он будет выполняться бесконечно много раз.

Проводящие петли

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

Синтаксис

do { 
   statement(s); 
 } while( condition ); 

Вот посмотрите на это:

#include <stdio.h> 
 
 int main(void){ 
    int a = 0; 
 
    do { 
        a++ 
    } while(a == -123); 
 
    printf("%i\n", a); 
 
    return 0; 
 } 

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

Для петель

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

Синтаксис

for(initialisation; condition; changer) 
 { 
   statement(s); 
 } 

Вот пример этого:

#include <stdio.h> 
 
 int main(void) { 
    int a = 4; 
    int b = 2; 
    int result = 0; 
 
    for(int count = 0; count != b; count++) { 
        result = result + a; 
    } 
 
    printf("a times b is %i\n", result); 
 
    return 0; 
 } 

Умножение - это просто повторное добавление, так что это добавление в a , b раз. Давайте дубль посмотрит на for немного , в частности:

for(int count = 0; count != b; count++) 

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

Следующий раздел - это логическое условие, которое будет проверяться на истинное или ложное, точно так же, как наш цикл while. Он называется «условие», потому что это условие, которое будет проверено перед запуском цикла.

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

Сравнение синтаксиса

main() 
 { 
  int i = 1; 
  while(i<=5) 
  { 
     printf(“While”); 
     i++; 
   } 
  getch(); 
 } 
 
 
 main() 
 { 
  int i = 1; 
  do 
  { 
     printf(“do-while”); 
     i++; 
   } while(i<=5); 
  getch(); 
 
 } 
 
 
 main() 
 { 
  int i 
  for(i=1;i<=5;i++) 
  { 
     printf(“for”); 
   } 
  getch(); 
 } 

Записи управления контуром

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

C поддерживает следующие управляющие команды:

1. Разговор

Завершает цикл или оператор switch и передает выполнение в оператор сразу после цикла или переключателя.

2. Продолжить заявление

Заставляет цикл пропускать остальную часть своего тела и сразу же повторять его условие до повторного повторения.

3. Операция Goto

Передает контроль над заявлением с надписью.

Некоторые интересные и полезные причуды

Бесконечная петля с петлями

Подумайте, что будет делать этот код:

for(;;){ 
    printf("hello, world! \n"); 
 } 
 
 while("Free Code Camp"){ 
    printf("hello, world! \n"); 
 } 

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

Следующее условие - пустое. Это немного странно. Это означает, что никакое условие не будет проверено, поэтому оно никогда не будет ложным, поэтому оно будет проходить через цикл, выполнить afterthought (что ничего не делать), а затем снова проверить условие, которое запустит его снова. Как вы, наверное, поняли, это бесконечный цикл. Как оказалось, это действительно полезно. При создании бесконечного цикла метод выполнения while(1) является совершенно законным, но каждый раз выполняет сравнение. for(;;) , с другой стороны, нет. По этой причине for(;;) имеет законное применение в том, что это волосы более эффективны, чем другие методы бесконечного цикла. К счастью, многие компиляторы позаботятся об этом для вас.

Цикл во втором коде while («Free Code Camp») также будет выполняться бесконечно. Причина в том, что C считает любое ненулевое значение истинным и, следовательно, будет бесконечно выполнять цикл.

Не использовать скобки

На этой странице вы прочли, что код «в скобках» запускается, и это в основном верно. Однако, что, если скобок нет?

while(true) 
    printf("hello, world! \n"); 

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

Точки с запятой вместо скобок

Если нет скобок, компилятор будет смотреть только на следующую строку, и это будет содержание цикла. Точки с запятой сообщают компилятору, что линия завершена. С этими вещами мы сможем подождать, пока что-то не станет истинным. Скажем, у нас есть метод с именем is_button_pressed который возвращает false, если кнопка не нажата, и true, если нажата кнопка:

while(!is_button_pressed()); 

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

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

Прежде чем продолжить ...

Обзор

  • Циклы позволяют запускать код более одного раза, когда выполняются определенные условия.
  • Есть пара петель, доступных нам в C:
  • Хотя циклы, которые позволяют нам запускать код, пока условие истинно
  • Циклы do-while, которые запускают код, а затем продолжают работать, если условие истинно
  • Для циклов, которые запускают код, пока условие истинно и позволяет нам выполнять операцию в каждом цикле.

Использование циклов для проектирования шаблонов.

Пример 1: программа для печати половины пирамиды с использованием *

* 
 * * 
 * * * 
 * * * * 
 * * * * * 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, j, rows; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=1; i<=rows; ++i) 
    { 
        for(j=1; j<=i; ++j) 
        { 
            printf("* "); 
        } 
        printf("\n"); 
    } 
    return 0; 
 } 

Пример 2: программа для печати половины пирамиды a с использованием чисел

1 
 1 2 
 1 2 3 
 1 2 3 4 
 1 2 3 4 5 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, j, rows; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=1; i<=rows; ++i) 
    { 
        for(j=1; j<=i; ++j) 
        { 
            printf("%d ",j); 
        } 
        printf("\n"); 
    } 
    return 0; 
 } 

Пример 3: Программа для печати половины пирамиды с использованием алфавитов

A 
 BB 
 CCC 
 DDDD 
 EEEEE 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, j; 
    char input, alphabet = 'A'; 
 
    printf("Enter the uppercase character you want to print in last row: "); 
    scanf("%c",&input); 
 
    for(i=1; i <= (input-'A'+1); ++i) 
    { 
        for(j=1;j<=i;++j) 
        { 
            printf("%c", alphabet); 
        } 
        ++alphabet; 
 
        printf("\n"); 
    } 
    return 0; 
 } 

Программы для печати перевернутой половины пирамиды с использованием * и чисел

Пример 4. Перевернутая половина пирамиды с использованием *

* * * * * 
 * * * * 
 * * * 
 * * 
 * 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, j, rows; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=rows; i>=1; --i) 
    { 
        for(j=1; j<=i; ++j) 
        { 
            printf("* "); 
        } 
        printf("\n"); 
    } 
 
    return 0; 
 } 

Пример 5: Перевернутая половина пирамиды с использованием чисел

1 2 3 4 5 
 1 2 3 4 
 1 2 3 
 1 2 
 1 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, j, rows; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=rows; i>=1; --i) 
    { 
        for(j=1; j<=i; ++j) 
        { 
            printf("%d ",j); 
        } 
        printf("\n"); 
    } 
 
    return 0; 
 } 

Пример 6: Программа для печати полной пирамиды с использованием *

        * 
      * * * 
    * * * * * 
  * * * * * * * 
 * * * * * * * * * 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, space, rows, k=0; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=1; i<=rows; ++i, k=0) 
    { 
        for(space=1; space<=rows-i; ++space) 
        { 
            printf("  "); 
        } 
 
        while(k != 2*i-1) 
        { 
            printf("* "); 
            ++k; 
        } 
 
        printf("\n"); 
    } 
 
    return 0; 
 } 

Пример 7: Программа для печати пирамиды с использованием чисел

        1 
      2 3 2 
    3 4 5 4 3 
  4 5 6 7 6 5 4 
 5 6 7 8 9 8 7 6 5 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int i, space, rows, k=0, count = 0, count1 = 0; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=1; i<=rows; ++i) 
    { 
        for(space=1; space <= rows-i; ++space) 
        { 
            printf("  "); 
            ++count; 
        } 
 
        while(k != 2*i-1) 
        { 
            if (count <= rows-1) 
            { 
                printf("%d ", i+k); 
                ++count; 
            } 
            else 
            { 
                ++count1; 
                printf("%d ", (i+k-2*count1)); 
            } 
            ++k; 
        } 
        count1 = count = k = 0; 
 
        printf("\n"); 
    } 
    return 0; 
 } 

Пример 8: Перевернутая полная пирамида с использованием *

* * * * * * * * * 
  * * * * * * * 
    * * * * * 
      * * * 
        * 

Исходный код

#include<stdio.h> 
 
 int main() 
 { 
    int rows, i, j, space; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=rows; i>=1; --i) 
    { 
        for(space=0; space < rows-i; ++space) 
            printf("  "); 
 
        for(j=i; j <= 2*i-1; ++j) 
            printf("* "); 
 
        for(j=0; j < i-1; ++j) 
            printf("* "); 
 
        printf("\n"); 
    } 
 
    return 0; 
 } 

Пример 9: Печатать треугольник Паскаля

           1 
         1   1 
       1   2   1 
     1   3   3    1 
   1  4    6   4   1 
 1  5   10   10  5   1 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int rows, coef = 1, space, i, j; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=0; i<rows; i++) 
    { 
        for(space=1; space <= rows-i; space++) 
            printf("  "); 
 
        for(j=0; j <= i; j++) 
        { 
            if (j==0 || i==0) 
                coef = 1; 
            else 
                coef = coef*(i-j+1)/j; 
 
            printf("%4d", coef); 
        } 
        printf("\n"); 
    } 
 
    return 0; 
 } 

Пример 10: печать треугольника Флойда.

1 
 2 3 
 4 5 6 
 7 8 9 10 

Исходный код

#include <stdio.h> 
 
 int main() 
 { 
    int rows, i, j, number= 1; 
 
    printf("Enter number of rows: "); 
    scanf("%d",&rows); 
 
    for(i=1; i <= rows; i++) 
    { 
        for(j=1; j <= i; ++j) 
        { 
            printf("%d ", number); 
            ++number; 
        } 
 
        printf("\n"); 
    } 
 
    return 0; 
 }