В чем ошибка если на цикле

Неверный тип переменной цикла

var x: real;
begin
  for x := 1 to 10 do // переменная - параметр цикла не может иметь вещественный тип
    write(x);
end.

Изменение переменной цикла в теле цикла

Пример 1.

var i: integer;
begin
  for i := 1 to 10 do
  begin
    write(i);
    i := i + 2; // Нельзя изменять значение переменной цикла внутри цикла
  end;  
end.

Пример 2.

var i: integer;
begin
  for i := 1 to 10 do
  begin
    read(i); // Нельзя изменять значение переменной цикла внутри цикла
    write(i);
  end;  
end.

Использование одинаковой переменной цикла в заголовках вложенных циклов

var i,j: integer;
begin
  for i := 1 to 10 do
  for i := 1 to 10 do // ошибка: во вложенном цикле нельзя использовать параметр цикла с тем же именем
  begin
    write(i);
  end;  
end.

Неинициализированная переменная

var 
  i: integer;
  p: real;
begin
  // Забыли инициализировать p := 1
  for i := 1 to 10 do
    p := p * 2;
  write(p);  
end.

Зацикливание

var x: integer;
begin
  x := 1;
  while x>0 do // ошибка: условие все время остается истинным
  begin
    writeln(x);
    x := x + 1;
  end;
end.

Переполнение

var 
  n: integer;
  x: real;
begin
  n := integer.MaxValue; // максимальное целое
  writeln(n);
  n := n + 1; // следующее за максимальным целым
  writeln(n);  
  writeln;
  
  x := real.MaxValue; // максимальное вещественное
  writeln(x);
  x := x * 2; // бОльшее, чем максимальное вещественное
  writeln(x); // в ряде компиляторов возникает ошибка переполнения. 
              // Здесь x получает значение "бесконечность"
end.

Сравнение вещественных чисел на равенство

begin
  if 0.3*3 = 0.9 then // Значения не равны ввиду ошибки округления при работе с вещественными числами
    writeln('Равны')
  else writeln('Не равны');
end.

Ссылки

  • Программы для начинающих
  • Сайт PascalABC.NET: Программы и алгоритмы для начинающих

Как работает цикл for?

Оператор for определяет инициализатор начальных условий цикла, условие завершения цикла и действие, совершаемое после каждой итерации цикла:

for (инициализатор; условие; действие)
    тело цикла;
  • Инициализатор выполняется один раз перед началом цикла и используется для инициализации счетчика цикла.
  • Логическое условие проверяется перед первой и всеми последующими итерациями. Если условие принимает значение true, цикл выполняется. Как только условие принимает значение false, цикл завершается.
  • После первой и последующих итераций цикла выполняется действие. Как правило этот раздел используетcя для увеличения счетчика цикла.

Почему «программа отказывается считать»?

Допустим, N = 10. Сначала происходит инициализация счетчика цикла n значением N. Получаем n = 10. Перед первой итерацией цикла проверяем, выполняется ли условие n le 1. Думаю, очевидно, что утверждение 10 le 1 ложно. Поэтому тело цикла не выполняется ни разу.

Что делать?

Нам нужно найти сумму ряда. Выражение можно раскрыть следующим образом:

S=sum_{n=1}^N frac{ln n}{sqrt[4]{n^5}}=frac{ln 1}{sqrt[4]{1^5}}+frac{ln 2}{sqrt[4]{2^5}}+...+frac{ln N}{sqrt[4]{N^5}}.

Переменная n изменяется в пределах от 1 до N. Таким образом, следует сделать следующее:

Получаем:

for (int n = 1; n <= N; n++)
    тело цикла;

Теперь все верно?

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

double p = 0;
for (int n = 1; n <= N; n++)
    p += значение_члена_ряда;

А теперь?

И снова нет. Дальше — больше. Из школьного курса математики мы знаем, что

sqrt[4]{n^5}= ({n^5})^frac{1}{4}=n^frac{5}{4},

но никак не

sqrt[4]{n^5}=(sqrt{n^5})^4.

Поэтому:

double p = 0;
for (int n = 1; n <= N; n++)
    p += Math.Log(n) / Math.Pow(n, 5.0 / 4.0);

Очень важно явно указывать принадлежность 5.0 и 4.0 к типу double:

double a = 5.0 / 4.0; // 1.25
double b = 5 / 4; // 1

Жалуется на мой цикл, мол not a statement for.

for (; (line = br.readLine()) != null; i < j)
      {
        String[] commands = decode(line).split(";");
        if ((!line.contains("")) || (!line.contains("Auth_error"))) {
          Log.Write(line);
        }
        String[] arrayOfString1;
        j = (arrayOfString1 = commands).length;i = 0; continue;String com = arrayOfString1[i];
        if (com != null) {
          Bukkit.dispatchCommand(Bukkit.getConsoleSender(), com);
        }
        i++;
      }

В чем собственно ошибка, много времени с ней вожусь.

Помогите понять в чём ошибка , компилятор выдаёт ошибку что «continue» вне цикла , хотя по идее оно внутри , если его убрать по цикл выполняется бесконечно. Спасибо

ошибка : «com/javarush/task/pro/task04/task0408/Solution.java:18: error: continue outside of loop
continue;»

package com.javarush.task.pro.task04.task0408;

import java.util.Scanner;

/*
Максимум из введенных чисел
*/

public class Solution {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
int max = Integer.MIN_VALUE;
while (console.hasNextInt());
{
int num = console.nextInt();
if ((num > max) && (num%2==0))
max=num;
continue;

}
System.out.println(max);
}
}

kriptan

0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

1

Ошибка в цикле

25.09.2018, 11:12. Показов 842. Ответов 26

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте. Подскажите, пожалуйста, в чем тут ошибка и как правильно сделать, что цикл заработал?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        double x, y, z, z1;
        private void button1_Click(object sender, EventArgs e)
        {
            z = 10;
            do
            {
                x = y * z;
                y = 5;
                z1 = 1 / y;
 
                if (z1 != z)
                {
                    z1 = z;
                }
            }
            while (Math.Abs(z - z1) < 0.1);
            textBox1.Text = Convert.ToString(z);
 
        }
    }



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

25.09.2018, 11:12

Ответы с готовыми решениями:

Ошибка в цикле
Здравствуйте.
Помогите, пожалуйста, исправить код. Пытаюсь сделать конечный цикл, но видимо…

Ошибка в цикле foreach
всем доброго времени,идея такова есть скажем в одном текстбоксе h(4) и мне нужно что бы в итоге в…

Ошибка в цикле перебора массива символов(((
public static string CheckCarNumber(string number)
{
string num = number;

Ошибка в цикле
Суть программы: создаёт динамический список, каждый новый элемент списка заносится в конец. Ну, там…

26

Рядовой

1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 11:34

2

Цитата
Сообщение от kriptan
Посмотреть сообщение

x = y * z;
* * * * * * * * y = 5;

ну вот тут например вы используете y, а значение ей присваиваете после.

C#
1
2
3
4
if (z1 != z)
                {
                    z1 = z;
                }

каждый шаг цикла присваиваете z1 значение z а потом ждете когда их разница будет больше 0.1

Цитата
Сообщение от kriptan
Посмотреть сообщение

как правильно сделать, что цикл заработал

полностью переписать



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 11:55

 [ТС]

3

Цитата
Сообщение от Рядовой
Посмотреть сообщение

ну вот тут например вы используете y, а значение ей присваиваете после.

Нужно перенести строчку с y выше?

Цитата
Сообщение от Рядовой
Посмотреть сообщение

каждый шаг цикла присваиваете z1 значение z а потом ждете когда их разница будет больше 0.1

Разница вроде меньше 0,1 написано, исправить < yf >?

Цитата
Сообщение от Рядовой
Посмотреть сообщение

полностью переписать

Нужен именно такой цикл. Я хочу решить первое уравнение, но у меня неизвестно z, поэтому я задаю его, но при этом мне нужно правильно решить это уравнение, поэтому я ввожу z1 и решаю данное уравнение итерациями чтоли, как то так. И теперь мне интересно какое же значение примет z. Хочу его посмотреть, поэтому вывожу его в текстбокс. Но при данном цикле ничего не работает, хотя и не выдает ошибок. Посоветуйте, что не так?



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:01

4

Цитата
Сообщение от kriptan
Посмотреть сообщение

Нужно перенести строчку с y выше?

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



0



kriptan

0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:05

 [ТС]

5

Ой извиняюсь y = 5*x. Вот так

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        double x, y, z, z1;
        private void button1_Click(object sender, EventArgs e)
        {
            z = 10;
            do
            {
                x = y * z;
                y = 5 * x;
                z1 = 1 / y;
 
                if (z1 != z)
                {
                    z1 = z;
                }
            }
            while (Math.Abs(z - z1) < 0.1);
            textBox1.Text = Convert.ToString(z);
 
        }
    }
}

Добавлено через 1 минуту

Цитата
Сообщение от Рядовой
Посмотреть сообщение

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

А как сделать чтобы менялись? переменная z должна принимать значение z1 и пересчитывать цикл, пока не выполнится условие Math.Abs(z — z1) < 0.1



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:09

6

Цитата
Сообщение от kriptan
Посмотреть сообщение

x = y * z;
* * * * * * * * y = 5 * x;

для начала разберитесь с этой строкой. у вас неизвестные x и y, известна одна z, как вы хотите чтобы компьютер это решил?



0



kriptan

0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:16

 [ТС]

7

Ага, извиняюсь, вот так должно быть

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        double x, y, z, z1;
        private void button1_Click(object sender, EventArgs e)
        {
            z = 10;
            do
            {
                x = 3 * z;
                y = 5 * x;
                z1 = 1 / y;
 
                if (z1 != z)
                {
                    z1 = z;
                }
            }
            while (Math.Abs(z - z1) < 0.1);
            textBox1.Text = Convert.ToString(z);
 
        }
    }

Добавлено через 3 минуты
Поможете?



0



Рядовой

1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:17

8

Цитата
Сообщение от kriptan
Посмотреть сообщение

C#
1
2
3
4
5
6
7
8
                x = 3 * z;
                y = 5 * x;
                z1 = 1 / y;
 
                if (z1 != z)
                {
                    z1 = z;
                }

Прошел один цикл, вы z1 присвоили z, а затем снова передаете в цикл старую z. И ничего не меняется. Значит должна меняться z а не z1?



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:21

 [ТС]

9

да, конечно z должна принимать значение z1 и с таким значением уже подаваться в цикл пока не выполнится условие

Добавлено через 2 минуты
как это сделать?



0



1406 / 1261 / 20

Регистрация: 09.08.2011

Сообщений: 2,321

Записей в блоге: 1

25.09.2018, 12:25

10

а зачем вам бесконечный цикл? и что за ошибка, если можно ее текст!



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:27

 [ТС]

11

Цитата
Сообщение от V_Monomax
Посмотреть сообщение

а зачем вам бесконечный цикл? и что за ошибка, если можно ее текст!

Ошибки нет, просто зависает. Мне не нужен бесконечный цикл, наоборот нужен конечный.



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:28

12

V_Monomax, ошибки нет, просто бесконечный цикл. Пытаюсь подвести к тому что сам алгоритм не верен.



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:29

 [ТС]

13

Цитата
Сообщение от Рядовой
Посмотреть сообщение

V_Monomax, ошибки нет, просто бесконечный цикл. Пытаюсь подвести к тому что сам алгоритм не верен.

Последний вариант решаемый же?



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:29

14

я запустил, и нет, все равно бесконечный



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:31

 [ТС]

15

Цитата
Сообщение от Рядовой
Посмотреть сообщение

я запустил, и нет, все равно бесконечный

А код правильный для этой цели? Исправлять код не нужно?



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 12:33

16

Цитата
Сообщение от kriptan
Посмотреть сообщение

А код правильный для этой цели?

разумеется я не знаю. Самой задачи так и не увидел.



0



V_Monomax

1406 / 1261 / 20

Регистрация: 09.08.2011

Сообщений: 2,321

Записей в блоге: 1

25.09.2018, 12:35

17

Цитата
Сообщение от kriptan
Посмотреть сообщение

Ошибки нет, просто зависает

это результат вот этого

C#
1
2
3
4
5
6
 if (z1 != z)
                {
                    z1 = z;
                }
            }
            while (Math.Abs(z - z1) < 0.1);

Т.е. бесконечного цикла в основном потоке.

Добавлено через 1 минуту
kriptan, напишите словами и по подробнее что вы хотите получить в результате, и какие данные у вас на входе!



0



0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 12:59

 [ТС]

18

Цитата
Сообщение от V_Monomax
Посмотреть сообщение

это результат вот этого
C#Выделить код
1
2
3
4
5
6
*if (z1 != z)
* * * * * * * * {
* * * * * * * * * * z1 = z;
* * * * * * * * }
* * * * * * }
* * * * * * while (Math.Abs(z — z1) < 0.1);
Т.е. бесконечного цикла в основном потоке.

А как это правильно записать, чтобы значение z1 передавалось z и цикл запускался со значением z=z1 пока не выполнится условие while?

Добавлено через 5 минут
При моей записи так и происходит, просто цикл бесконечный? Или код неправильно записан для решения этой задачи?

Добавлено через 51 секунду
Задача: возвращать z=z1 обратно в цикл, пока не выполнится условие while.

Добавлено через 7 минут
Можете помочь с кодом?



0



1499 / 893 / 325

Регистрация: 17.05.2015

Сообщений: 3,386

25.09.2018, 13:01

19

z1 = z заменить на z=z1. Но этим вы ничего не добьетесь, z ,будет принимать только 2 значения 10 и дробное. Цикл останется бесконечным. Поэтому надо менять алгоритм работы.



0



kriptan

0 / 0 / 0

Регистрация: 13.06.2018

Сообщений: 71

25.09.2018, 13:07

 [ТС]

20

Цитата
Сообщение от Рядовой
Посмотреть сообщение

z1 = z заменить на z=z1. Но этим вы ничего не добьетесь, z ,будет принимать только 2 значения 10 и дробное. Цикл останется бесконечным. Поэтому надо менять алгоритм работы

Даже вот так упростил и поидее тут должен выдавать 1 в текстбокс, но все равно виснет. Видимо ошибка в коде( Как исправить?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        double x, y, z, z1;
        private void button1_Click(object sender, EventArgs e)
        {
            z = 1;
            do
            {
                x = z;
                y = x;
                z1 = 1/y;
 
                if (z1 != z)
                {
                    z = z1;
                }
            }
            while (Math.Abs(z - z1) < 0.1);
            textBox1.Text = Convert.ToString(z);
 
        }
    }
}



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

25.09.2018, 13:07

Помогаю со студенческими работами здесь

Ошибка в цикле while
Привет всем! Ниже приведен код программы, в программе две функции одна change() переводит Ф.И.О в…

Ошибка в цикле.
Вот сделал программу в турбо паскале, но со временем отложил ее и переустановил виндовс на 64 бит,…

Ошибка в цикле!
for k=1:1:511
if (M(1,k) == 1) &amp;&amp; (fix(y(1,k)) == 99)
O = A;
O(end+1) =…

Ошибка в цикле
Здравствуйте.

Нужно вычислить факториал неотрицательного числа. К примеру:
n! = n * (n — 1) *…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

20

Здравствуйте, дорогие читатели! Циклы, являются неотъемлемой частью любого языка программирования. Они позволяют нам выполнять огромное количество рутинных операций, которые делать вручную невероятно сложно. В этом и заключается главная «прелесть» циклов.

Существует три вида циклов в C++:

  • for
  • while
  • do while

В данной статье речь пойдет о цикле for.

Как работает цикл for?

Цикл for последовательно выполняет одинаковые действия, определенное количество раз. Например, тысячу раз будет выводить сообщение Hello, world!.

Давайте рассмотрим структуру цикла for:

for (<объявление счетчика>; <условие выполнения цикла>; <шаг цикла>) {

    <тело цикла>

}

Теперь давайте поподробнее рассмотрим синтаксис цикла for:

  • <объявление счетчика> — здесь нужно создать переменную (счетчик цикла) и задать ей первоначальное значение. Эта команда выполняется до запуска цикла;
  • <условие выполнения цикла> — оно похоже на условие оператора if. Нам нужно указать логическое выражение, при истинности которого, цикл будет работать;
  • <шаг цикла> — данная инструкция будет выполняться в конце каждой итерации, переводя счетчик цикла на новое значение;
  • <тело цикла> — здесь мы указываем код, который будет выполнятся на каждой итерации цикла.

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

Пример работы цикла for

Следующая программа находит произведение цифр от 1 до N (факториал):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#include <iostream>

#include <stdlib.h>

using namespace std;

int main() {

    int n; // создаем переменную n

    cout << «N = «; // выводим сообщение cin >> n; // считываем значение

    int res = 1; // создаем переменную res

    // в ней мы будем хранить результат работы цикла

    for (int i = 1; i <= n; i++) // цикл for

        res *= i; // умножаем на i полученное ранее значение

    cout << «RES = « << res << endl; // выводим результат работы программы

    return 0;

}

Вот один из возможных результатов работы данной программы:

N = 7

RES = 5040

Process returned 0 (0x0) execution time : 2.723 s

Press any key to continue.

Теперь давайте приступи к разбору кода:

  • Строка 6: мы создаем переменную n. В будущем ее мы будем использовать в условии выполнения цикла.
  • Строка 10: нам нужна переменная в которой будет хранится результат работы цикла. Поэтому мы создаем переменную res.
  • Строка 11: вот мы и добрались до цикла for. Здесь давайте разберемся поподробнее:
    • в качестве счетчика выступает переменная i. Мы сразу ей задаем значение 1 (собственно можно было начать и с двух, поскольку умножение на 1 не имеет смысла);
    • условием выполнения цикла является нестрогое неравенство. Цикл будет выполнятся до тех пор, пока i меньше или равно n;
    • после каждой итерации мы увеличиваем значение счетчика на единицу (операция инкремента). Это равносильно следующей записи: i = i + 1.
  • Строка 14: выводим результат работы программы на экран пользователя.

Данный пример довольно наглядно демонстрирует возможности циклов. Однако давайте рассмотрим еще одну из вариаций цикла for, которая наглядно демонстрирует его гибкость:

int a, b;

for (a = 140, b = 1742; a != b; ) {

    if (a > b)

        a -= b;

    else

        b -= a;

}

cout << a;

Данная программа — это реализация алгоритма нахождения НОД. Давайте не будем разбирать его работу, а просто рассмотрим особенности данного кода:

  • в качестве счетчика можно указывать сразу несколько переменных. Также они не обязательно должны быть объявлены непосредственно в самом блоке;
  • любой из блоков (их 3) может вовсе отсутствовать. Вот хороший пример работы бесконечного цикла:

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

Довольно часто вам придется пользоваться лишь одной вариацией цикла for. Однако если вам придется выполнять специфические задачи, то вы сможете подстроить цикл for под свои «хотелки».

Возможные ошибки

Цикл — это одновременно очень удобный инструмент для работы, но в тоже время он таит не мало скрытых угроз. Неопытные кодеры могут совершать ошибки, которые не просто выявить, поскольку программа успешно компилируется и начинает работу.

Сегфолт

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

for (int i; i < 10; i++) {

    <ваш код>

}

Вы могли заметь, что здесь переменной i не задали значение. Изначально переменная содержит «мусор» (можете вывести такой мусор на экран для того, чтобы понять о чем я говорю). Естественно к мусору прибавлять ничего нельзя — программа вылетит.

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

Некоторые компиляторы обнуляют переменные при их создании. Например, это делает компилятор gcc.

Бесконечный цикл

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

Давайте посмотрим на простой пример:

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

    r += i;

}

Данный цикл никогда не завершится, поскольку внутри значение i уменьшается на единицу, а после опять увеличивается. Таким образов условие i < 10 всегда будет истинным.

Тест на тему «Цикл for в C++»

Пожалуйста, подождите пока страница загрузится полностью.
Если эта надпись не исчезает долгое время, попробуйте обновить страницу. Этот тест использует javascript. Пожалуйста, влкючите javascript в вашем браузере.

If loading fails, click here to try again

Попробуйте пройти небольшой тест, чтобы проверить свои знания по данной теме.

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

Добавлено 29 мая 2021 в 16:06

Безусловно, наиболее часто используемой инструкцией цикла в C++ является оператор for. Оператор for (также называемый циклом for) предпочтителен, когда у нас есть очевидная переменная цикла, потому что он позволяет нам легко и кратко определять, инициализировать, тестировать и изменять значение переменных цикла.

Начиная с C++11, существует два разных типа циклов for. В этом уроке мы рассмотрим классический оператор for, а новый оператор for на основе диапазона в следующем уроке (10.19 – Циклы for-each), как только рассмотрим некоторые другие необходимые темы, такие как массивы и итераторы.

Оператор for абстрактно выглядит довольно просто:

for (инструкция_инициализации; условие; конечное_выражение)
   инструкция;

Самый простой способ изначально понять, как работает оператор for, – это преобразовать его в эквивалентный оператор while:

{// обратите внимание на блок здесь
    инструкция_инициализации; // используется для определения переменных,
                              // используемых в цикле
    while (условие)
    {
        инструкция;
        конечное_выражение; // используется для изменения переменной цикла перед
                            // повторным вычислением условия
    }
} // переменные, определенные внутри цикла, здесь выходят из области видимости

Вычисление операторов for

Оператор for вычисляется в трех частях:

  1. Сначала выполняется инструкция инициализации. Это происходит только один раз при запуске цикла. Инструкция инициализации обычно используется для определения и инициализации переменных. Эти переменные имеют «область видимости цикла», которая на самом деле является формой области видимости блока, где эти переменные существуют от точки определения до конца инструкции цикла. В нашем эквивалентном цикле while вы можете видеть, что инструкция инициализации находится внутри блока, содержащего цикл, поэтому переменные, определенные в инструкции инициализации, выходят за пределы области видимости, когда блок, содержащий цикл, заканчивается.
  2. Во-вторых, для каждой итерации цикла вычисляется условие. Если оно истинно, инструкция выполняется. Если оно принимает значение false, цикл завершается, и выполнение продолжается со следующей инструкции за пределами цикла.
  3. Наконец, после выполнения инструкции вычисляется конечное выражение. Обычно это выражение используется для увеличения или уменьшения переменных цикла, определенных в инструкции инициализации. После того, как конечное выражение было вычислено, выполнение возвращается ко второму шагу (и условие вычисляется снова).

Давайте посмотрим на пример цикла for и обсудим, как он работает:

#include <iostream>
 
int main()
{
    for (int count{ 1 }; count <= 10; ++count)
        std::cout << count << ' ';
 
    return 0;
}

Сначала мы объявляем переменную цикла с именем count и инициализируем ее значением 1.

Во-вторых, вычисляется count <= 10, и, поскольку count равно 1, условие вычисляется как true. Следовательно, выполняется инструкция, которая выводит 1 и пробел.

Наконец, вычисляется выражение ++count, которое увеличивает значение count до 2. Затем цикл возвращается ко второму шагу.

Теперь снова вычисляется count <= 10. Поскольку count имеет значение 2, условие вычисляет значение true, поэтому цикл повторяется снова. Инструкция печатает 2 и пробел, и count увеличивается до 3. Цикл продолжает повторяться, пока в конечном итоге count не увеличится до 11, после чего count <= 10 вычисляется как false, и цикл завершается.

Следовательно, эта программа выводит следующий результат:

1 2 3 4 5 6 7 8 9 10

В качестве примера давайте преобразуем приведенный выше цикл for в эквивалентный цикл while:

#include <iostream>
 
int main()
{
    { // блок здесь обеспечивает область видимости блока для count
        int count{ 1 };     // наша инструкция инициализации
        while (count <= 10) // наше условие
        {
            std::cout << count << ' '; // наша инструкция
            ++count;                   // наше конечное выражение
        }
    }
}

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

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

Больше примеров циклов

Вот пример функции, которая использует цикл for для вычисления целочисленного возведения в степень:

// возвращает значение base^exponent - берегитесь переполнения!
int pow(int base, int exponent)
{
    int total{ 1 };
 
    for (int count{ 0 }; count < exponent; ++count)
        total *= base;
 
    return total;
}

Эта функция возвращает значение base^exponent (base в степени exponent).

Это цикл for с простым увеличением счетчика на 1, с циклическим увеличением count от 0 до exponent (не включительно).

  • Если exponent равен 0, цикл for будет выполняться 0 раз, и функция вернет 1.
  • Если exponent равен 1, цикл for выполнится 1 раз, и функция вернет 1 * base.
  • Если exponent равен 2, цикл for будет выполнен 2 раза, и функция вернет 1 * base * base.

Хотя большинство циклов for увеличивают переменную цикла на 1, мы также можем уменьшать ее:

#include <iostream>
 
int main()
{
    for (int count{ 9 }; count >= 0; --count)
        std::cout << count << ' ';
 
    return 0;
}

Эта программа напечатает следующий результат:

9 8 7 6 5 4 3 2 1 0

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

#include <iostream>
 
int main()
{
    for (int count{ 9 }; count >= 0; count -= 2)
    std::cout << count << ' ';
 
    return 0;
}

Эта программа напечатает следующий результат:

9 7 5 3 1

Ошибки на единицу

Одна из самых больших проблем, с которыми сталкиваются новички в циклах for (и других циклах, в которых используются счетчики), – это ошибки «на единицу». Ошибки «на единицу» возникают, когда цикл повторяется на один раз больше или на один раз меньше, чем это необходимо.

Например:

#include <iostream>
 
int main()
{
    // упс, мы использовали operator< вместо operator<=
    for (unsigned int count{ 1 }; count < 5; ++count)
    {
        std::cout << count << ' ';
    }
 
    return 0;
}

Эта программа должна печатать «1 2 3 4 5», но она печатает только «1 2 3 4», потому что мы использовали неправильный оператор отношения.

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

Пропущенные выражения

Циклы for можно писать, опуская какие-либо или все инструкции или выражения. Например, в следующем примере мы опустим инструкцию инициализации и конечное выражение, оставив только условие:

#include <iostream>
 
int main()
{
    int count{ 0 };
    for ( ; count < 10; ) // нет инструкции инициализации и конечного выражения
    {
        std::cout << count << ' ';
        ++count;
    }
 
    return 0;
}

Этот цикл for дает следующий результат:

0 1 2 3 4 5 6 7 8 9

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

Хотя вы не часто встретите это, стоит отметить, что следующий пример создает бесконечный цикл:

for (;;)
    инструкция;

Приведенный выше пример эквивалентен следующему коду:

while (true)
    инструкция;

Это может показаться немного неожиданным, поскольку вы, вероятно, ожидаете, что пропущенное условное выражение будет обрабатываться как ложное. Однако стандарт C++ явно (и непоследовательно) определяет, что пропущенное условное выражение в цикле for должно рассматриваться как истинное.

Мы рекомендуем полностью избегать этой формы цикла for и вместо нее использовать while (true).

Циклы for с несколькими счетчиками

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

#include <iostream>
 
int main()
{
    for (int x{ 0 }, y{ 9 }; x < 10; ++x, --y)
        std::cout << x << ' ' << y << 'n';
 
    return 0;
}

Этот цикл определяет и инициализирует две новые переменные: x и y. Он выполняет итерацию по x в диапазоне от 0 до 9, и после каждой итерации x увеличивается, а y уменьшается.

Эта программа дает следующий результат:

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

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

Лучшая практика


Определение нескольких переменных (в инструкции инициализации) и использование оператора запятой (в конечном выражении) внутри оператора for допустимо.

Вложенные циклы for

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

#include <iostream>
 
int main()
{
	for (char c{ 'a' }; c <= 'e'; ++c) // внешний цикл для букв
	{
		std::cout << c; // сначала печатаем нашу букву
		
		for (int i{ 0 }; i < 3; ++i)  // внутренний цикл для всех чисел
			std::cout << i;
 
		std::cout << 'n';
	}
 
	return 0;
}

При каждой итерации внешнего цикла внутренний цикл выполняется полностью. Следовательно, на выходе получается:

a012
b012
c012
d012
e012

Вот еще несколько подробностей о том, что здесь происходит. Сначала выполняется внешний цикл, и char c инициализируется значением 'a'. Затем вычисляется c <= 'e', что верно, поэтому выполняется тело цикла. Поскольку c установлен в 'a', сначала выводится a. Затем полностью выполняется внутренний цикл (который выводит 0, 1 и 2). Затем печатается символ новой строки. Теперь тело внешнего цикла завершено, поэтому внешний цикл возвращается наверх, c увеличивается до 'b', и условие цикла повторно вычисляется. Поскольку условие цикла по-прежнему выполняется, начинается следующая итерация внешнего цикла. Это напечатает «b012n«. И так далее.

Заключение

Операторы for – это наиболее часто используемый цикл в языке C++. Несмотря на то, что его синтаксис обычно немного сбивает с толку начинающих программистов, вы будете видеть циклы for так часто, что поймете их в кратчайшие сроки!

Операторы for идеально подходят, если у вас есть переменная-счетчик. Если у вас нет счетчика, вероятно, лучше выбрать оператор while.

Лучшая практика


Когда есть очевидная переменная цикла, предпочитайте использовать циклы for вместо циклов while.

Когда нет очевидной переменной цикла, предпочитайте использовать циклы while вместо циклов for.

Небольшой тест

Вопрос 1

Напишите цикл for, который печатает каждое четное число от 0 до 20.

Ответ

for (int count{ 0 }; count <= 20; count += 2)
    std::cout << count << 'n';

Вопрос 2

Напишите функцию с именем sumTo(), которая принимает целочисленный параметр с именем value и возвращает сумму всех чисел от 1 до value.

Например, sumTo(5) должна вернуть 15, что равно 1 + 2 + 3 + 4 + 5.

Подсказка: при итерации от 1 до входного значения используйте переменную, объявленную вне цикла, для накопления суммы, подобно тому, как в приведенном выше примере pow() используется переменная total для накопления на каждой итерации возвращаемого значения.

Ответ

int sumTo(int value)
{
    int total{ 0 };
    for (int count{ 1 }; count <= value; ++count)
        total += count;
 
    return total;
}

Вопрос 3

Что не так со следующим циклом for?

// Вывести все числа от 9 до 0
for (unsigned int count{ 9 }; count >= 0; --count)
    std::cout << count << ' ';

Ответ

Этот цикл for выполняется, пока count >= 0. Другими словами, он выполняется до тех пор, пока count не станет отрицательной. Однако, поскольку переменная count не имеет знака, она никогда не может стать отрицательной. Следовательно, этот цикл будет работать вечно (ха)! Как правило, рекомендуется избегать использования в циклах беззнаковых переменных без необходимости.

Теги

C++ / CppforLearnCppwhileДля начинающихОбучениеПрограммированиеЦикл

Часто встречающиеся ошибки программирования:

  1. Точка с запятой после скобок селектора:

switch
($n)
;

{

case 0:
оператор;

break;

. . . . . . . . . .

  1. Отсутствие фигурных скобок после слова
    switch:

switch ($n)

case 0:
оператор;

break;

. . . . . . . . . .

  1. Перечисление меток вариантов без слов
    case:

switch ($n)

{

case 0, 1, 2: $n++;

break;

. . . .
. . . . . .

  1. Перечисление меток вариантов через
    запятые:

switch ($n)

{

case 0, case 1, case 2:
$n++;

break;

. . . .
. . . . . .

  1. Отсутствие оператора breakпосле ветвей переключателя:

switch ($n)

{

case 0: case 1: case 2:
$n++;

case
3: $
n—;

. . . . . .
. . . .

Циклы

Одним из самых ценных свойств компьютеров
является их способность многократно
повторять последовательность одинаковых
или похожих действий — циклов.

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

  1. бесконечныециклы,

  2. циклы с предусловием(циклы
    типаПОКА),

  3. циклы с постусловием(циклы
    типаДО),

  4. циклы с параметром(циклы типаДЛЯ).

Бесконечные циклы

Бесконечный цикл может быть представлен
следующей схемой:

Как правило, появление в программе
бесконечных циклов вызвано логическими
ошибками, допущенными программистом
при разработке алгоритма и кодировании
(написании операторов программы) с
использованием оператора безусловного
перехода goto.
Поэтому в современных алгоритмических
языках этот оператор практически не
используется, а заменяется циклами.
Бесконечные циклыне выявляютсятранслятором при синтаксическом контроле
и проявляются только после запуска
программы на выполнение следующим
образом:

  1. длительное время (десятки секунд)
    программа не выводит на устройство
    вывода никакой информации – программа
    зависает
    ,

  2. на устройство вывода постоянно выводится
    одна и та же информация.

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

Циклы с предусловием

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

ПОКА (условие)
ВЫПОЛНЯТЬ

цепочка;

Такой
цикл называется циклом спредусловием(цикломПОКА) и изображается
следующей схемой:

Условие– это логическое выражение, зависящее
от переменных, входящих в цепочку. Цикл
повторяется до тех пор, пока условие
истинно
. Значит, данное условие
являетсяусловиемпродолженияцикла. Выполнение цикла заканчивается,
если операторыцепочкиизменяют значения переменных, входящих
вусловие,
и оно становитсяложным.

Цикл не выполняется ни разу,
еслиусловиебылоложнымс самого начала.

Цикл ПОКАпревращается вбесконечный, еслиусловиеподобрано так, что оно всегдаистинно.

В PHP цикл
с предусловием реализуется оператором
циклаwhile:

while
(условие)

оператор;

или

while
(условие)

{

оператор;

оператор;

. . . .

оператор;

}

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

Внимание!Условиевсегда заключаетсяв скобкии
после него точка с запятойне ставится!

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

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

Действия оператора while:

  1. проверяется выполнение условия,

  2. если оно истинно, то выполняетсяоператор(цепочка), стоящий после него,

  3. после его выполнения снова проверяется
    условие,
    и если оно сноваистинно, то
    цикл повторяется,

  4. если условие
    становитсяложным, то цикл
    заканчивает работу.

Примеры:

  1. вычислить сумму ста первых натуральных
    чисел:

s
= 1 + 2 + 3 + … + 98 + 99 + 100

Пусть s– искомая сумма,

i
– очередное число (изменяется от1до100).

Тогда алгоритмрешения задачи
можно описать следующим образом:

  1. обнуляем сумму s
    = 0
    ,

  2. берем первое число: i
    = 1
    ,

  3. добавляем в сумму это число: s
    =
    s
    +
    i,

  4. увеличиваем очередное число на единицу:
    i
    =
    i+
    1
    ,

  5. если оно не больше 100, то снова
    добавляем его в сумму и повторяем цикл.

Представим этот алгоритм так:

s
= 0;

i = 1;

ПОКА
(i ≤ 100)

НАЧАЛО

s = s + i;

i
=
i
+ 1;

КОНЕЦ;

Программа:

$i = 1;

$s = 0;

while ($i <= 100)

{

$s += $i;

$i++;

}

echo “<BR>s = $s
i = $i<BR>”;

Результат решения задачи:

s
= 5050
i
= 101

Таким образом, выходим из этого цикла
со значением
iне100,
а101.

Вместо цепочки:

$s += $i;

$i++;

можно использовать один оператор:

$s
+= $
i++;

Этот цикл можно превратить в бесконечный,
если после условияпоставить точку с запятой:

$i
= 1;

$s = 0;

while ($i <= 100);

{

$s += $i;

$i++;

}

echo “<BR>s = $s
i = $i<BR>”;

Значение переменной
$
iв этом случае меняться не будет – она
останется равнойединице.

  1. вычислить сумму s
    всех цифр заданного натурального
    числа n

Пусть s
– искомая сумма,

i
– очередная цифра числа.

Тогда алгоритмрешения задачи
можно описать следующим образом:

  1. обнуляем сумму s=0,

  2. берем последнююцифру числа,
    для чего определяем остаток от деления
    исходного числа на 10:i
    =
    n
    % 10
    ,

  3. добавляем в сумму найденную цифру: s
    =
    s
    +
    i,

  4. уменьшаем число в 10 раз: n
    =
    n
    / 10
    ,

  5. повторяем цикл до тех пор, пока
    n
    > 0
    – это и будетусловиемпродолжения цикла.

Программа:

$s = 0;

$n = 12345;

while ($n > 0)

{

$i = $n % 10;

$s += $i;

$n /= 10;

}

echo “<BR>s = $s”;

  1. ввести с клавиатуры по одному
    последовательность целых чисел (конец
    последовательности – число 0).
    Определить их сумму, максимальное и
    минимальное число, количество введенных
    чисел и их среднее арифметическое.

Пусть s
искомая сумма,

min,
max– минимальное и максимальное из введенных
чисел,

count– количество введенных чисел,

sred– среднее арифметическое,

n– очередное число.

Тогда алгоритмрешения задачи
можно описать следующим образом:

  1. обнуляем сумму s = 0,

  2. вводим первое число n,

  3. если оно не равно нулю, то

  4. принимаем его значение за minиmax

  5. количество введенных чисел count
    = 1

  6. увеличиваем сумму на введенное число
    s
    =
    s
    +
    n

  7. входим в цикл ввода:

  8. вводим очередное число n,

  9. если оно не равно нулю, то

  10. количество введенных чисел увеличиваем
    на 1:count
    =
    count+1

  11. увеличиваем сумму на введенное число
    s
    =
    s
    +
    n

  12. если оно меньше min,
    тоmin
    =
    n,

  13. если оно больше max,
    тоmax
    =
    n,

  14. повторяем цикл до тех пор, пока
    n
    # 0
    – это и будетусловиемпродолжения цикла.

Создадим интерфейсэтой задачи
– взаимодействие программы с пользователем,
то есть что должно выводиться на экран:

Первое число: 3

Очередное число:
8

Очередное число:
1

Очередное число:
-2

Очередное число:
0

Сумма = 10

Количество чисел
= 4

min
= -2

max
= 8

Среднее
арифметическое = 2.50

Схема
алгоритма:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Содержание:развернуть

  • Немного информатики
  • Синтаксис цикла while
  • Несколько примеров использования цикла while
  • break и continue
  • else
  • while true или бесконечный цикл
  • Best practice
  • Цикл while в одну строку

  • Вложенные циклы

  • Как выйти с помощью break из двух циклов

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

Циклы в языке Python представлены двумя основными конструкциями: while и for. Цикл while считается универсальным, в то время как for нужен для обхода последовательности поэлементно.

Подробнее о циклах for вы можете прочитать здесь:

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

Немного информатики

Как было отмечено выше,

Цикл — это управляющая конструкция, которая раз за разом выполняет серию команд (тело цикла) до тех пор, пока условие для выполнения является истинным.

Напишем на псевдокоде классическую схему:

повторять, пока условие
начало цикла
последовательность инструкций
конец цикла

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

Циклы, как механизм программирования, нужны, главным образом, для упрощения написания кода. Вполне очевидно, что создавать программу, выполняющую определённую операцию для каждой точки 4К дисплея в отсутствии циклов — это вручную повторять описание нужной команды 4096*2160 раз. 🤔 Много? Безусловно.

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

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

Синтаксис цикла while

В самом простом случае, цикл while в python очень похож по своей структуре на условную конструкцию с if:

import time
a = 1

if a == 1:
print("I'm the condition")

while a == 1:
print("I'm the loop")
time.sleep(1)

И в том и в другом случае, блок кода внутри (инструкция print(‘…’)) будет исполнен тогда и только тогда, когда условие (a == 1) будет иметь значение True. Вот только в конструкции с if, при успешной проверке, вывод на экран будет выполнен всего один раз, а в случае с while фраза «I’m the loop» будет печататься бесконечно.

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

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

count = 1 # фиксируем начальное значение
while count <= 10: # и конечное (включительно)
print(count, end=' ')
count += 1

# после 9-й итерации в count будет храниться значение 10
# это удовлетворяет условию count <= 10, поэтому на 10-м витке будет выведено число 10
# (как видно, значение счетчика печатается до его инкрементирования)
# после count станет равным 11, а, значит, следующий прогон цикла не состоится, и он будет прерван
# в итоге получаем:
> 1 2 3 4 5 6 7 8 9 10

В Python есть и более сложные, составные условия. Они могут быть сколь угодно длинными, а в их записи используются логические операторы (not, and, or):

dayoff = False
sunrise = 6
sunset = 18

worktime = 12

# пример составного условия
while not dayoff and sunrise <= worktime <= sunset:
if sunset == worktime:
print("Finally it's over!")
else:
print('You have ', sunset - worktime, ' hours to work')
worktime += 1

>
You have 6 hours to work
You have 5 hours to work
You have 4 hours to work
You have 3 hours to work
You have 2 hours to work
You have 1 hours to work
Finally it's over!

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

num = 0
control = True
while num < 10:
num += 1

# аналогичная запись
num = 0
control = True
while control:
if num == 10:
control = False
num += 1

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

# unknown до этого нигде не была объявлена
while unknown:
print('+')

>
Traceback (most recent call last):
while unknown:
NameError: name 'unknown' is not defined

Несколько примеров использования цикла while

Идея циклов while проста — требуется определенное количество раз сделать что-то? Заведи счётчик и уменьшай/увеличивай его в теле цикла.

x = 20
y = 30
while x < y:
print(x, end=' ')
x = x + 3

> 20 23 26 29

Своеобразным счётчиком может быть даже строка:

word = "pythonchik"
while word:
print(word, end=" ")
# на каждой итерации убираем символ с конца
word = word[:-1]

> pythonchik pythonchi pythonch pythonc python pytho pyth pyt py p

break и continue

Оператор break заставляет интерпретатор прервать выполнение цикла и перейти к следующей за ним инструкции:

counter = 0
while True:
if counter == 10:
break
counter += 1

Цикл прервётся после того, как значение счетчика дойдёт до десяти.

Существует похожий оператор под названием continue, однако он не прекращает выполнение всей конструкции, а прерывает лишь текущую итерацию, переходя затем в начало цикла:

# классический пример вывода одних лишь чётных значений
z = 10
while z:
z -= 1
if z % 2 != 0:
continue
print(z, end=" ")

> 8 6 4 2 0

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

else

В Python-циклах часть else выполняется лишь тогда, когда цикл отработал, не будучи прерван break-ом.

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

👉 Пример из практики: проверка доступности всех выбранных узлов сети

Например, обойти все узлы локальной сети и

def print_prime_list(list_of_numbers: list) -> None:
""" функция выведет список чисел,
если каждое из этих чисел является простым """
number_count = len(list_of_numbers) # количество чисел

i = 0
while i < number_count:
x = list_of_numbers[i] // 2
if x != 0 and list_of_numbers[i] % x == 0:
break
i += 1
else:
print(f'{list_of_numbers} - list is prime!')

print_prime_list([11, 100, 199]) # 100 - не простое число
>

print_prime_list([11, 113, 199])
> [11, 113, 199]

В каком-либо другом языке стоило бы завести булеву переменную, в которой хранится результат проверки, но у Python, как всегда, есть способ получше!

while true или бесконечный цикл

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

Однако вы некоторых случая бесконечный цикл делают намерено:

  1. Если нужно производить какие-то действия с интервалом, и выходить из цикла лишь в том случае, когда внутри тела «зашито» условие выхода.
    Пример: функция, которая возвращает connection базы данных. Если связь с базой данных отсутствует, соединение будет пытаться (в цикле) установиться до тех пор, пока не установится.
  2. Если вы пишете полноценный демон, который продолжительное время висит как процесс в системе и периодически производит какие-то действия. В таком случае остановкой цикла будет прерывание работы программы. Пример: скрипт, который раз в 10 минут «пингует» IP адреса и пишет в лог отчет о доступности этих адресов.

💁‍♂️ Совет: в бесконечных циклах рекомендуется ставить таймаут выполнения после каждой итерации, иначе вы очень сильно нагрузите CPU:

import time

while True:
print("Бесконечный цикл")
time.sleep(1)

>
Бесконечный цикл
Бесконечный цикл
Бесконечный цикл
Traceback (most recent call last):
File "main.py", line 5, in <module>
time.sleep(1)
KeyboardInterrupt

Aborted!

Код был прерван комбинацией клавиш ^Ctrl + C. Иначе цикл продолжался бы бесконечно.

Best practice

Цикл while в одну строку

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

Например, записи:

while x < y:
x +=1

# и

while x < y: x += 1

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

Вложенные циклы

Вложенные while циклы встречаются не так часто, как их братья (или сестры) for, что, однако не мешает им быть полезными. Простой пример — выведем на экран таблицу умножения:

q = 1
while q <= 9:
w = 1
while w <= 9:
print(q * w, end=" ")
w += 1
q += 1
print("")

>
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

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

Как выйти с помощью break из двух циклов

В случае вложенных циклов, оператор break завершает работу только того цикла, внутри которого он был вызван:

i = 100
j = 200
while i < 105:
while j < 205:
if j == 203:
break
print('J', j)
j += 1
print('I', i)
i += 1

>
J 200
J 201
J 202
# здесь видно, что внутренний цикл прерывается, но внешний продолжает работу
I 100
I 101
I 102
I 103
I 104

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

Способ №1
Используем конструкцию for ... else ...:

def same_values_exists(list_1: list, list_2: list) -> None:
""" функция выводит на экран
первые совпавшие числа из списков """
for i in list_1:
for j in list_2:
print("compare: ", i, j)
if i == j:
print(f"found {i}")
break
else:
continue
break

same_values_exists([0, 10, -2, 23], [-2, 2])
>
compare: 0 -2
compare: 0 2
compare: 10 -2
compare: 10 2
compare: -2 -2
found -2

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

Способ №2
Через создание дополнительного флага:

def same_values_exists(list_1: list, list_2: list) -> None:
""" функция выводит на экран
первые совпавшие числа из списков """
break_the_loop = False

for i in list_1:
for j in list_2:
print("compare: ", i, j)
if i == j:
print(f"found {i}")
break_the_loop = True
break
if break_the_loop:
break

same_values_exists([0, 10, -2, 23], [-2, 2])
>
compare: 0 -2
compare: 0 2
compare: 10 -2
compare: 10 2
compare: -2 -2
found -2

Внешний цикл был прерван вслед за внутренним. Дело сделано!

Способ №3
Если циклы находятся в функции (как в нашем примере), достаточно просто сделать
return:

def same_values_exists(list_1: list, list_2: list) -> None:
""" функция выводит на экран
первые совпавшие числа из списков """
for i in list_1:
for j in list_2:
print("compare: ", i, j)
if i == j:
print(f"found {i}")
return

same_values_exists([0, 10, -2, 23], [-2, 2])

>
compare: 0 -2
compare: 0 2
compare: 10 -2
compare: 10 2
compare: -2 -2
found -2

Возможно, вам также будет интересно:

  • В чем ошибка если гель лак не держится
  • В чем ошибка евгения базарова
  • В чем ошибка дорогие друзья позвольте рассказать вам
  • В чем ошибка дориана грея
  • В чем ошибка доктора преображенского

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии