Учетно аналитический цикл for

Учетно аналитический цикл for thumbnail

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

Как используют цикл for в Java - 1Примерно так, чтобы много раз не писать один и тот же код, придумали циклы. Представим, что нам нужно вывести в консоль числа от 0 до 99. Код без цикла:

System.out.println(0);
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
// И так далее

Этот код займет 100 строк! Очень много. А вот как это будет выглядеть с циклом:

for(int i = 0; i < 100; i++) {
System.out.println(i);
}

Всего 3 строки!

Что такое циклы for?

Цикл for – это управляющая конструкция программного кода, которая нарушает линейность исполнения алгоритма и позволяет выполнить указанный код множество раз. Например, необходимо принять 30 капель лекарства. Алгоритм будет примерно такой:

  1. Приготовить стакан.
  2. Открыть крышку.
  3. Получить 1 каплю.
  4. Получить 2 каплю.
  5. Получить 30 каплю.
  6. Закрыть лекарство.
  7. Принять полученную порцию.

Этот алгоритм можно объяснить гораздо быстрее:

  1. Приготовить стакан.
  2. Открыть крышку капель.
  3. Получить 30 капель.
  4. Закрыть лекарство.
  5. Принять полученную порцию.

Мы практически каждый день используем цикл for в разговоре с другими людьми: “…20 шагов дальше по улице…”, “…сделай 10 повторений и еще 5 в 2 раза медленнее…”, “…сделай 5 покупок в различных категориях и получи приз…” можно продолжать долго, но смысл ясен.

В Java Цикл for необходим для сокращения кода и его лаконичности.

Принцип работы цикла for

For цикл используется следующим образом:

for(<начальная точка>; <условие выхода>; <операторы счетчика>) {
// Тело цикла
}
Пример перебора цифр от 0 до 5 и вывод каждой в консоль:
for(int i = 0; i < 5; i++) {
System.out.println(i);
}

Вывод:


1
2
3
4

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

Создай переменную i с начальным значением 0, пока она не достигнет 5, прибавляй к ней по 1 и на каждом шаге записывай значение i в консоль.”

В основе работы цикла for в Java лежат три стадии, их можно изобразить следующей схемой:
Как используют цикл for в Java - 2Условие выхода из цикла — это булево выражение. Если оно ложно, цикл будет завершен. В примере выше переменная i увеличивается на 1. Если ее значение менее 5, цикл продолжается. Но как только i станет больше или равно 5, цикл прекратится.

Оператор счетчика — выражение, которое выполняет преобразование переменной счетчика. В примере выше переменная i увеличивалась на 1. То есть цикл будет выполнен ровно 5 раз. Если оператор счетчика будет прибавлять по 2 к переменной i, результат будет иным:

for(int i = 0; i < 5; i = i + 2) {
System.out.println(i);
}

Вывод:


2
4

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

Тело цикла — любой код, который может быть выполнен. В примере выше в теле цикла был вывод значения переменной i в консоль, однако содержимое данного тела ограничено задачей и фантазией.

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

Если задать условие выхода из цикла как true:

for(int i = 0; true; i++) {
if(i % 1000000 == 0) System.out.println(i);
}
System.out.println(“Loop ended”);

То код после цикла будет помечен ошибкой unreachable statement, так как никогда не будет исполнен.

Задача на смекалку: в результате запуска кода ниже будет ли выведено в консоль “Loop ended” или цикл будет выполняться бесконечно?

for(int i = 0; i > -1; i++) {
if(i % 1000000 == 0) System.out.println(i);
}
System.out.println(“Loop ended”);

Ответ: будет. Переменная i рано или поздно достигнет максимального значения, а дальнейшее увеличение превратит ее в максимальное отрицательное, в результате чего условие выхода будет выполнено (i < = -1).

Цикл forEach

При работе с циклами иногда приходится перебирать массивы или коллекции. Обычно массив можно перебрать с помощью цикла for:

public void printAllElements(String[] stringArray) {
for(int i = 0; i < stringArray.length; i++) {
System.out.println(stringArray[i]);
}
}

И это правильно. Однако, для перебора всех элементов массива по очереди придумали конструкцию forEach. Ее сигнатура следующая:

for(<Тип элемента> <Имя переменной, куда будет записан очередной элемент> : <Название массива>) {
// Тело цикла
}

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

public void printAllElements(String[] stringArray) {
for(String s : stringArray) {
System.out.println(s);
}
}

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

Как используются циклы for

А теперь рассмотрим несколько примеров использование цикла for в Java для решения разнообразных задач.

Обратный цикл (от большего к меньшему)

for(int i = 5; i > 0; i–) {
System.out.println(i);
}

Вывод:

5
4
3
2
1

Несколько переменных и увеличение счетчика в теле цикла

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

int a = 0;
for(int i = 5; i > 0; i–, a++) {
System.out.print(“Шаг: ” + a + ” Значение: “);
System.out.println(i);
}

Вывод:

Шаг: 0 Значение: 5
Шаг: 1 Значение: 4
Шаг: 2 Значение: 3
Шаг: 3 Значение: 2
Шаг: 4 Значение: 1

Или объявить две переменные и идти по циклу, пока они не будут равны друг другу:

for(int i = 5, j = 11; i != j; i++, j–) {
System.out.println(“i: ” + i + ” j: ” + j);
}

Вывод:

i: 5 j: 11
i: 6 j: 10
i: 7 j: 9

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

Читайте также:  Итерационный цикл в excel

В цикле for также можно создавать внутренние циклы. В этом случае количество шагов цикла будет умножаться:

for(int i = 0; i < 5; i++) {
System.out.print(i + ” | “);
for(int j = 0; j < 5; j++) {
System.out.print(j + ” “);
}
System.out.print(‘n’);
}

Вывод:

0 | 0 1 2 3 4
1 | 0 1 2 3 4
2 | 0 1 2 3 4
3 | 0 1 2 3 4
4 | 0 1 2 3 4

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

int[][] array = { {0, 1, 2, 3, 4 },
{1, 2, 3, 4, 5},
{2, 3, 4, 5, 6},
{3, 4, 5, 6, 7}};

for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + ” “);
}
System.out.print(‘n’);
}

Вывод:

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

Досрочное завершение цикла

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

public void getFirstPosition(String[] stringArray, String element) {
for (int i = 0; i < stringArray.length; i++) {
if(stringArray[i].equals(element)) {
System.out.println(i);
break;
}
}
}

Метод выведет позицию первого искомого элемента в массиве:

String[] array = {“one”, “two”, “three”, “Jeronimo”};
getFirstPosition(array, “two”);

Вывод:

1

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

Еще один способ создать бесконечный цикл for — оставить пустой область объявления счетчика, условие выхода и оператор счетчика:

for (;;) {
}

Но учти, что в большинстве случаев бесконечный цикл — свидетельство логической ошибки. У такого цикла обязательно должно быть условие выхода.

На курсе JavaRush знакомство с циклами происходит на четвертом уровне обучения в первом квесте (Java Syntax). Отдельные лекции посвящены циклу for, сравнением этого цикла в Java и языке Pascal. Также в курсе есть подборка задач по этой теме.
Как используют цикл for в Java - 3

Источник

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

Я довольно давно пишу код, и так вышло, что практически всегда на C++. Даже и не могу прикинуть, сколько раз я написал подобную конструкцию:

for (int i=0; i<size; i++) {
[…]
}

Хотя почему не могу, очень даже могу:

find . ( -name *.h -o -name *.cpp ) -exec grep -H “for (” {} ; | wc -l
43641

Наш текущий проект содержит 43 тысячи циклов. Проект пилю не я один, но команда маленькая и проект у меня не первый (и, надеюсь, не последний), так что в качестве грубой оценки пойдёт. А насколько такая запись цикла for хороша? Ведь на самом деле, важно даже не то количество раз, когда я цикл написал, а то количество раз, когда я цикл прочитал (см. отладка и code review). А тут речь очевидно идёт уже о миллионах.

На КПДВ узел под названием «совершенная петля» (perfection loop).

Так каков он, совершенный цикл?

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

for (int iter=0; iter<nb_iter; iter++) { // some iterative computation
for (int c=0; c<mesh.cells.nb(); c++) // loop through all tetrahedra
for (int lv0=0; lv0<4; lv0++) // for every pair of
for (int lv1 = lv0+1; lv1<4; lv1++) // vertices in the tet
for (int d=0; d<3; d++) { // do stuff for each of 3 dimensions
nlRowScaling(weight);
nlBegin(NL_ROW);
nlCoefficient(mesh.cells.vertex(c, lv0)*3 + d, 1);
nlCoefficient(mesh.cells.vertex(c, lv1)*3 + d, -1);
nlEnd(NL_ROW);
}
[…]
}

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

Мы обязаны иметь дело с кучей вложенных циклов; вышеприведённые пять вложенных далеко не предел. Мы уже довольно давно (лет пятнадцать как) пришли к выводу, что стандартный for (int i=0; i<size; i++) — это очень громоздкая конструкция: те самые пять вложенных заголовков for превращаются в совершенно нечитаемую кашу, и даже подсветка синтаксиса не спасает.

Когда мы читаем стандартный for(;;), мы должны на каждой строчке обратить внимание на три вещи: на инициализацию, на условие выхода и собственно на инкремент. Но ведь это совершеннейший оверкилл для тех случаев, когда нам нужно пройтись от 0 до size-1, а это подавляющее большинство всех циклов. Скажите, как часто вам приходится писать обратный цикл или итерацию с другими границами? Как мне кажется, один раз из десяти — это ещё щедрая оценка.

До появления c++11 мы в итоге пришли к страшной вещи, а именно ввели в самый верхний заголовок вот такой дефайн:

#define FOR(I,UPPERBND) for(int I = 0; I<int(UPPERBND); ++I)

И тогда вышеприведённый кусок кода превращается из тыквы в кабачок:

FOR(iter, nb_iter) {
FOR(c, mesh.cells.nb())
FOR(lv0, 4)
for (int lv1 = lv0+1; lv1<4; lv1++)
FOR(d, 3) {
nlRowScaling(weight);
nlBegin(NL_ROW);
nlCoefficient(mesh.cells.vertex(c, lv0)*3 + d, 1);
nlCoefficient(mesh.cells.vertex(c, lv1)*3 + d, -1);
nlEnd(NL_ROW);
}
[…]
}

Польза такой трансформации в том, что когда я встречаю for (;;), я знаю, что мне нужно насторожиться и внимательно смотреть на все три места (инициализацию, условие, инкремент). В то время как если я вижу FOR(,) то это совершенно стандартный пробег от 0 до n-1 без каких-либо тонкостей. Я совершенно не предлагаю пользоваться вышеприведённым дефайном, но точно знаю, что для нашей команды он сберёг много ресурсов мозга, поскольку мы кода гораздо больше читаем (см. отладка), нежели пишем (как, наверное, и все программисты).

Читайте также:  Считать цикл после эскапела

То есть, вопрос, которым я задаюсь, звучит так: “Как выглядит цикл, имеющий минимальную когнитивную нагрузку при чтении кода?

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

for i in range(n):
print(i)

Что любопытно, до третьего питона range() создавал в памяти массив индексов, и проходился по нему. И со времён c++11 мы вполне можем делать точно так же!

#include <iostream>
int main() {
int range[] = {0,1,2,3,4,5};
for (int i : range) {
std::cerr << i;
}
}

Разумеется, явно создавать в памяти массив индексов это несерьёзно, и с третьей версии в питоне это тоже поняли. Но и в C++ мы можем сделать не хуже!

Давайте посмотрим на следующую функцию range(int n):

#include <iostream>

constexpr auto range(int n) {
struct iterator {
int i;
void operator++() { ++i; }
bool operator!=(const iterator& rhs) const { return i != rhs.i; }
const int &operator*() const { return i; }
};
struct wrapper {
int n;
auto begin() { return iterator{0}; }
auto end() { return iterator{n}; }
};
return wrapper{n};
}

int main() {
for (int i: range(13)) {
std::cerr << i;
}
return 0;
}

Пожалуйста, не начинайте int vs size_t, разговор не об этом. Если скомпилировать этот код при помощи gcc 10.2 с флагами компиляции -std=c++17 -Wall -Wextra -pedantic -O1, то мы получим следующий ассемблерный код (проверьте тут):

[…]
.L2:
mov esi, ebx
mov edi, OFFSET FLAT:_ZSt4cerr
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
add ebx, 1
cmp ebx, 13
jne .L2
[…]

То есть, компилятор начисто убрал все эти обёртки и оставил голый инкремент, ровно как если бы мы написали обычный for (int i=0; i<13; i++).

Лично мне кажется, что for (int i: range(n)) справляется с подчёркиванием обычности цикла чуть хуже, нежели FOR(,), но тоже вполне достойно, и за это не нужно платить дополнительными тактами процессора.

Range for в c++11 нанёс большую пользу. Давайте скажем, что у меня есть массив трёхмерных точек, и мне нужно распечатать икс координаты каждой точки, это можно сделать следующим образом:

#include <vector>
#include <iostream>

struct vec3 { double x,y,z; };

int main() {
std::vector<vec3> points = {{6,5,8},{1,2,3},{7,3,7}};
for (vec3 &p: points) {
std::cerr << p.x;
}
return 0;
}

for (vec3 &p: points) это прекрасная конструкция, никаких костылей, сразу из стандарта языка. Но что если у меня каждая точка из массива имеет цвет, вес или вкус? Это можно представить ещё одним массивом того же размера, что и массив точек. И тогда для доступа к атрибуту мне всё же понадобится индекс, который мы можем сгенерировать, например, вот таким образом:

std::vector<vec3> points = {{6,5,8},{1,2,3},{7,3,7}};
std::vector<double> weights = {4,6,9};
int i = 0;
for (vec3 &p: points) {
std::cerr << p.x << weights[i++];
}

Для этого кода компилятор генерирует следующий ассемблер:

asm

.L2:
movsd xmm0, QWORD PTR [r13+0]
mov edi, OFFSET FLAT:_ZSt4cerr
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
movsd xmm0, QWORD PTR [rbp+0]
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
add rbp, 8
add r13, 24
cmp r14, rbp
jne .L2

В принципе, имеет право на жизнь, но гулять так гулять, давайте снимем с программиста заботу о создании параллельного индекса, ровно как сделали в питоне, благо стандарт c++17 имеет structural binding!

Итак, можно сделать следующим образом:

#include <vector>
#include <iostream>
#include “range.h”

struct vec3 {
double x,y,z;
};

int main() {
std::vector<vec3> points = {{6,5,8},{1,2,3},{7,3,7}};
std::vector<double> weights = {4,6,9};

for (auto [i, p]: enumerate(points)) {
std::cerr << p.x << weights[i];
}

return 0;
}

Функция enumerate() определена в следующем заголовочном файле:

range.h

#ifndef __RANGE_H__
#define __RANGE_H__

#include <tuple>
#include <utility>
#include <iterator>

constexpr auto range(int n) {
struct iterator {
int i;
void operator++() { ++i; }
bool operator!=(const iterator& rhs) const { return i != rhs.i; }
const int &operator*() const { return i; }
};
struct wrapper {
int n;
auto begin() { return iterator{0}; }
auto end() { return iterator{n}; }
};
return wrapper{n};
}

template <typename T> constexpr auto enumerate(T && iterable) {
struct iterator {
int i;
typedef decltype(std::begin(std::declval<T>())) iterator_type;
iterator_type iter;
bool operator!=(const iterator& rhs) const { return iter != rhs.iter; }
void operator++() { ++i; ++iter; }
auto operator*() const { return std::tie(i, *iter); }
};
struct wrapper {
T iterable;
auto begin() { return iterator{0, std::begin(iterable)}; }
auto end() { return iterator{0, std::end (iterable)}; }
};
return wrapper{std::forward<T>(iterable)};
}

#endif // __RANGE_H__

При компиляции с флагами -std=c++17 -Wall -Wextra -pedantic -O2 мы получим следующий ассемблерный код (проверьте тут):

ASM

.L14:
movsd xmm0, QWORD PTR [rbx]
mov edi, OFFSET FLAT:_ZSt4cerr
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
mov rdi, rax
mov rax, QWORD PTR [rsp+32]
movsd xmm0, QWORD PTR [rax+rbp]
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
add rbx, 24
add rbp, 8
cmp r12, rbx
jne .L14

И снова компилятор начисто убрал обёртку (правда, для этого пришлось поднять уровень оптимизации с -O1 на -O2).
Кстати, в c++20 появился std::ranges, что ещё больше упрощает написание такой функции, но я пока не готов переходить на этот стандарт.

На ваш взгляд, каким должен быть совершенный цикл в 2020м году? Научите меня!

Если вы ещё не задавались этим вопросом, то скопируйте к себе в пет-проект заголовочный файл range.h и попробуйте его поиспользовать хотя бы несколько дней.

Читайте также:  С чем связано уменьшение цикла месячных

Источник

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

Существует три вида циклов в 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++»

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

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

Источник