Теоретический материал (Д.Кириенко, С++)
Сайт: | Информатикс |
Курс: | Операторы цикла |
Книга: | Теоретический материал (Д.Кириенко, С++) |
Напечатано:: | Гость |
Дата: | Пятница, 27 Июнь 2025, 22:25 |
Цикл for
Очень часто возникает необходимость выполнить одну и ту же последовательность
действий несколько раз: например, для вычисления выражения an
необходимо выполнить умножение на величину a n-1 раз. Для этого используются
циклы. В данном листочке речь пойдет о цикле for
.
Рассмотрим задачу вычисления суммы всех натуральных чисел от 1 до n.
Для этого заведем переменную s
, и к ней будем прибавлять значение
переменной
i
, где i
будет принимать все значения от 1 до n.
На языке C++ это можно сделать при помощи цикла for
следующим
образом:
int n, s=0, i;
cin>>n;
for (i=1; i<=n; ++i)
{
s=s+i;
}
cout<<s<<endl;
В этом примере последовательность инструкций в блоке, то есть инструкция
s=s+i
будет выполнена многократно для всех значений переменной i
от 1 до
n
,
то есть в результате переменная s
будет равна сумме всех натуральных
чисел
от 1
до n
.
При использовании цикла for
необходимо задать три параметра (в
круглых скобках
через точку с запятой).
Первый параметр – начальное значение переменной,
задается в виде
присваивания переменной значения, в нашем случае –
i=1
.
Второй параметр – конечное значение переменной,
задается в виде условия на значение
переменной. Цикл будет исполняться, пока условие истинно, в нашем случае условие
i<=n
означает,
что переменная i
будет принимать значения до n
включительно.
Третий параметр – шаг изменения переменной. Запись
++i
означает, что переменная i
будет увеличиваться на 1
с каждым новым исполнением цикла, запись
--i
– уменьшаться.
В нашем примере мы могли бы сделать цикл, в котором переменная
i
принимала бы все значения от n
до 1
, уменьшаясь при этом:
for(i=n; i>0; --i)
.
Если хочется, чтобы значение переменной в цикле менялось не на 1, а на
большую величину, то это можно сделать, например, так:
i=i+2
.
Упражнения
- (A) По данному натуральному n вычислите сумму 12+22+...+n2.
- (B) По данному натуральном n вычислите сумму 13+23+...+n3.
- (C) По данному натуральном n вычислите сумму 1×2+2×3+...+(n-1)×n.
- (D) По данным числам a и b выведите на экран все четные числа от a до b
включительно.
Например, при вводе
1
и10
программа должна вывести2 4 6 8 10
. - (E) По данному числу n вычислите значение n!.
- (F) По данным натуральным n и k вычислите значение Cnk=n!/(k!(n-k)!) (число сочетаний из n элементов по k).
- (G) По данному действительному числу a и натуральному n вычислите величину an. Программа считывает значение a и n и выводит an.
- (H) По данному натуральному n вычислите сумму 1+(1+2)+(1+2+3)+...+(1+2+...+n).
- (I) По данному числу n вычислите сумму 1+1/22+1/32+...+1/n2. Как вы думаете, к чему приближается эта сумма с увеличением n?
- (J) По данному числу n вычислите сумму 4(1-1/3+1/5-1/7+...+(-1)n/(2n+1)). Как вы думаете, к чему будет приближаться эта сумма с увеличением n?
- (K) По данному действительному числу a и натуральному n вычислите сумму 1+a+a2+...+an не используя формулу суммы геометрической прогрессии. Время работы программы должно быть пропорционально n. Затем решите эту задачу по формуле суммы геометрической прогрессии и сдайте ее в тестирующую систему.
- (L)
Дано 10 целых чисел. Вычислите их сумму. Например, при вводе чисел
1 2 3 4 5 6 7 8 9 10
программа должна вывести55
. - (M)
Дано несколько чисел. Вычислите их сумму.
Сначала вводится количество чисел N. Затем вводится N целых чисел, программа должна вывести их сумму.
Например, при вводе
3 1 20 300
программа должна вывести321
. - (без тестирующей системы) Найдите все двузначные числа, которые равны
удвоенному произведению своих цифр. Указание: организуйте цикл, в котором
переменная
i
принимает значения от 10 до 99, проверьте, равна лиi
удвоенному произведению своих цифр. - (без тестирующей системы) Квадрат трехзначного числа оканчивается тремя цифрами, равными этому числу. Найдите все такие числа.
Цикл for в общем виде
Операторы присваивания
В языке C++ помимо стандартного оператора присваивания =
существует еще несколько операторов присваивания: +=
, -=
, *=
, /=
, %=
,
&=
, |=
, ^=
, <<=
, >>=
. Запись x+=a
эквивалентна записи x=x+a
,
то есть значение x
увеличивается на a
. Аналогично работают и остальные операторы:
x=a
- присвоить
x
значениеa
x+=a
- увеличить значение
x
наa
x-=a
- уменьшить значение
x
наa
x*=a
- умножить
x
наa
x/=a
- поделить
x
наa
(не забудьте про то, что бывает деление целочисленное и с плавающей точкой!) x%=a
- заменить
x
на остаток от деленияx
наa
Все эти операции возвращают ссылку на переменную, стоящую слева от оператора присваивания.
При этом если в арифметической инструкции есть несколько операторов присваивания,
то они выполняются справа налево. Операторы присваивания имеют более низкий приоритет,
чем операторы +
, -
, *
, /
, %
, то есть выполняются после этих операторов (если нет скобок).
Пример:
int n=2,m=3;
n+=m*=2;
cout<<n<<" "<<m;
Во второй строке стоит два оператора присваивания. Сначала выполнится оператор m*=2
,
поскольку он стоит правее. Этот оператор присвоит m
значение 6 и вернет это значение.
Следующим выполнится оператор n+=6
, где 6 — это значение, которое вернул предыдущий
оператор присваивания. Таким образом, переменной n
будет присвоено значение 8
и на экран будут напечатаны числа 8 и 6.
Операторы инкремента и декремента
Унарный оператор инкремента ++
увеличивает значение переменной на 1.
Существует две формы оператора инкремента: префиксная форма ++n
и постфиксная форма n++
.
Постфиксный оператор инкремента возвращает старое значение переменной, а префиксный оператор — новое,
то есть увеличенное на 1. Пример:
int a=0,b=0,c=0,d=0;
a=++b;
c=d++;
Переменные a
, b
, d
в этом примере будут иметь значение, равное 1, а переменная c
будет равна 0.
Унарный оператор декремента --
уменьшает значение переменной на 1 и также существует в префиксной и постфиксной формах.
Операторы инкремента и декремента имеют более высокий приоритет, нежели операторы арифметических операций и присваиваний,
то есть выполняются раньше их (в выражении --d%=c
сначала будет выполнен декремент переменной d
,
а затем оператор взятия остатка и присваивания %=
).
Цикл for
Цикл for
является универсальным циклом, который может использоваться и вместо цикла while
.
Однако в большинстве случаев цикл for
используется для того, чтобы некоторая переменная
изменялась в заданном диапазоне с заданным шагом.
Синтаксис оператора for
такой:
for (инициализация ; условие ; итератор )
инструкция
где инициализация
, условие
, итератор
— арифметические выражения, инструкция
— одна инструкция языка C++.
Работает цикл for
следующим образом. Сначала вычисляется выражение "инициализация
".
Затем вычисляется значение "условия
". Если оно истинно, то выполняется
"инструкция
" тела цикла, а затем вычисляется "итератор
".
Если же "условие
" ложно, то цикл не выполняется и управление передается на следующую инструкцию после цикла.
Если цикл был выполнен, то после вычисления "итератора
" снова проверяется "условие
", и если оно истинно, то снова выполняется "инструкция
",
а затем вычисляется "итератор
" и так далее, пока условие не станет ложно.
Таким образом, "инициализация
" выполняется один раз до выполнения цикла и, как правило,
используется для присвоения начальных значений переменным, изменяющимся в цикле.
"Условие
" проверяется всякий раз перед очередным выполнением блока цикла и обычно используется
для задания границы изменения переменной в цикле. "Итератор
" вычисляется после выполнения блока
цикла и в большинстве случаев содержит оператор присваивания, инкремента или декремента, изменяющий
значение переменной.
Рассмотрим следующий пример, в котором на экран выводится 3 числа: 0, 1 и 2:
for(i=0;i<3;++i)
cout<<i<<endl;
Последовательность действий такова:
- Выполняется инициализация
i=0
. - Проверяется условие
i<3
. - Выполняется тело цикла: значение переменной
i
выводится на экран. - Вычисляется итератор
++i
. Теперьi
равно 1. - Проверяется условие
i<3
. - Выполняется тело цикла: значение переменной
i
выводится на экран. - Вычисляется итератор
++i
. Теперьi
равно 2. - Проверяется условие
i<3
. - Выполняется тело цикла: значение переменной
i
выводится на экран. - Вычисляется итератор
++i
. Теперьi
равно 3. - Проверяется условие
i<3
. Поскольку условие ложно, то цикл завершает работу, управление передается на следующую после цикла инструкцию, значениеi
при выходе из цикла равно 3.
Если в теле цикла нужно использовать не одну инструкцию, а несколько, то их надо объединить в блок при помощи фигурных скобок.
Тело цикла может и вообще отсутствовать, тогда в качестве тела цикла следует использовать пустую инструкцию,
которая ничего не делает и имеет синтаксис ";
" (точка с запятой). Пример:
for( cout>>n ; n%2==0 ; n/=2) ;
В этом примере инициализация состоит из считывания значения n
с клавиатуры,
условие состоит в проверке, делится ли число n
на 2, итератор — в делении числа n
на 2,
а тело самого цикла — пустое, так как сразу после закрывающей круглой скобки стоит пустая инструкция ";
".
Данный цикл будет уменьшать значение введенного числа в 2 раза до тех пор, пока число делится на 2.
В цикле for
можно не указывать выражения инициализации, условия и итератора, но обязательно нужно
проставить точки с запятой даже между отсутствующими выражениями. Если в инструкции for
пропущено условие,
то считается, что оно всегда истинно. Таким образом, бесконечный цикл можно задать следующим образом:
for(;;)
Инструкции управления циклом
Внутри циклов while
и for
могут встречаться инструкции управления циклом.
Инструкция break;
прерывает выполнение цикла, управление при этом немедленно
передается на следующую после цикла инструкцию. Инструкция continue;
продолжает
выполнение цикла со следующей итерации: все входящие в блок цикла инструкции не выполняются,
в цикле for
выполняется итератор, после чего проверяется условие (во всех видах циклов)
и в зависимости от его значения выполняется или не выполняется тело цикла.
Как правило, инструкции break;
и continue;
используются вместе с инструкцией if
.
Пример:
for(i=0;i<100;++i)
{
if(i%3==0)
continue;
cout<<i<<endl;
// Выполнить еще какие-нибудь действия
}
В этом примере переменная i
в цикле принимает значения от 0 до 99.
Внутри цикла проверяется условие и если i делится на 3, то оставшаяся часть цикла пропускается,
и на экран будут напечатаны только те значения i
, которые не делятся на 3.
Извлечение квадратного корня
Для извлечения квадратного корня (из величин типа double
, целочисленные величины
необходимо преобразовать к типу double
) используется стандартная функция
sqrt
, определененная в файле cmath
. Для ее использования необходимо в начале файла
с программой добавить строку #include <cmath>
.
Пример использования функции: d=sqrt(e);
.
Упражнения (для 9 класса)
- Не используя компьютер, определите значения переменных после выполнения данных фрагментов программ:
int a=5,b=4,c=17,d=3;
a-=b=c%=d;
int e=2, f=3;
++e+=f--;
int g,h=2;
g=(h++)+(--h);
for(int i=0; i<10; i+=3)
cout<<i<<endl;
for(int j=0; j<100; ++j)
{
j*=2;
cout<<j<<endl;
}
for(int k=0;k<100;)
{
if(k%2==0)
++k;
else
k=3*k+1;
cout<<k<<endl;
}
Что будет выведено на экран в трех последних примерах?
- По данным числам a и n вычислите a^n.
- По данному числу n вычислите сумму ряда 1/0!+1/1!+1/2!+...+1/n! .
- По данному натуральному числу
n
определите количество делителей числаn
. - По данному натуральному числу
n
найдите натуральное число, не превосходящееn
, имеющее наибольшее число натуральных делителей. - По данному числу
n
определите, является ли оно простым. - Найдите разложение данного числа
n
на простые множители. - Число называется совершенным, если оно равно сумме своих делителей, не превосходящих его самого. Например, 6=1+2+3, 28=1+2+4+7+14. Найдите первые 5 совершенных чисел.
- Теорема Лагранжа утверждает, что любое натуральное число можно представить в виде суммы четырех точных
квадратов. По данному числу
n
найдите такое представление. Найдите наименьшее натуральное число, которое нельзя представить в виде суммы трех точных квадратов.
Упражнения (для 10 класса)
- Не используя компьютер, определите значения переменных после выполнения данных фрагментов программ:
int a=5,b=4,c=17,d=3;
a-=b=c%=d;
int e=2, f=3;
++e+=f--;
int g,h=2;
g=(h++)+(--h);
for(int i=0; i<10; i+=3)
cout<<i<<endl;
for(int j=0; j<100; ++j)
{
j*=2;
cout<<j<<endl;
}
for(int k=0;k<100;)
{
if(k%2==0)
++k;
else
k*=2;
cout<<k<<endl;
}
Что будет выведено на экран в трех последних примерах?
- В трехзначном числе зачеркнули первую цифру, полученное число умножили на 7 и получили исходное число. Найдите его.
- По данному натуральному d найдите наименьшее решение в натуральных числах уравнения Пелля x^2-dy^2=1.
- Для данного натурального числа n выведите на экран все его натуральные делители.
- Число называется совершенным, если оно равно сумме своих делителей, не превосходящих его самого. Например, 6=1+2+3, 28=1+2+4+7+14. Найдите первые 5 совершенных чисел.
- Быстрое возведение в степень
По данному действительному a и натуральному n вычислите
an за время порядка log(n).
Указание воспользуйтесь представлением числа n в двоичном виде, или свойством: an=(a2)n/2
при четном n, an=a×an-1
при нечетном n.
- Бинарный алгоритм Евклида
Найдите наибольший общий делитель двух чисел не используя медленного оператора деления.
Можно использовать деление на 2 и взятие остатка от деления на 2, поскольку они
выполняются при помощи битовых операций быстро.
Указание: НОД(a,b)=2НОД(a/2,b/2),если a и b – четные, НОД(a,b)=НОД(a/2,b),если a – четное, b – нечетное, НОД(a,b)=НОД(a-b,b),если a и b – нечетные.
- Найдите число, оканчивающееся на цифру d, при умножении которого на
d получается число, которое также можно получить перестановкой последней цифры d
в начало числа.
- Решите эту задачу для d=4.
- Аналитически (без использования компьютера) решите задачу для d=8.
- Решите эту задачу для всех оставшихся цифр.
- Подумайте над обобщением этой задачи на случай нескольких последних цифр.