В языке 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
является универсальным циклом, который может использоваться и вместо цикла 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);
.
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; }
Что будет выведено на экран в трех последних примерах?
n
определите количество делителей числа n
.
n
найдите натуральное число, не превосходящее n
,
имеющее наибольшее число натуральных делителей.
n
определите, является ли оно простым.
n
на простые множители.
n
найдите такое представление. Найдите наименьшее натуральное
число, которое нельзя представить в виде суммы трех точных квадратов.
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; }
Что будет выведено на экран в трех последних примерах?
Указание воспользуйтесь представлением числа n в двоичном виде, или свойством: an=(a2)n/2
при четном n, an=a×an-1
при нечетном n.
Указание: НОД(a,b)=2НОД(a/2,b/2),если a и b – четные, НОД(a,b)=НОД(a/2,b),если a – четное, b – нечетное, НОД(a,b)=НОД(a-b,b),если a и b – нечетные.