freeCodeCamp/guide/russian/c/loops/index.md

22 KiB
Raw Blame History

title localeTitle
Loops of all kinds Петли всех видов

Петли всех видов в C

Циклы - это то, что вы используете, когда у вас есть код, который вы хотите использовать в цикле, а это означает, что после его запуска вам может понадобиться цикл для начала и повторного запуска. Есть несколько из них в 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; 
 }