Циклы в языке C: while, do-while, for. Инкремент и декремент
Инкремент и декремент
Прежде, чем изучать циклы, следует познакомиться с часто используемым в языке C способом увеличения/уменьшения значений переменных на единицу. Конечно, в Си работают такие формы изменения значений как, например, a += 1
или a -= 1
. Однако чаще используют операции инкрементирования (оператор инкремента ++
) и декрементирования (оператор декремента --
): i++
или ++i
, i--
или --i
. В результате этих операций переменные увеличиваются или уменьшаются на единицу.
Запомните, когда вы видите выражения типа ++i
или i++
, то в результате их выполнения значение i меняется. Не надо делать вот так: i = ++i
. Это совершенно лишнее.
Когда знак инкремента или декремента стоит перед переменной, то перед нами префиксная форма операции (++i
, --i
), а когда после переменной, то постфиксная форма (i++
, i--
). Когда эти выражения не участвуют в построении более сложных выражений, то между префиксной и постфиксной формами никакой разницы нет: что i++
, что ++i
— без разницы, в результате мы получим значение i на единицу больше.
Однако когда эти выражения участвуют в построении более сложных, то разница между префиксной и постфиксной формами появляется и заключается в следующем: переменная над которой производится операция инкрементирования или декрементирования в постфиксной форме сначала используется в сложном выражении как есть, и только потом увеличивается на единицу; если мы имеем дело с префиксной формой, то переменная сначала изменяется, а затем используется. Например, код:
int a, b, c, d; /* выражение означает, что всем переменным присваивается 0 */ a = b = c = d = 0; printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); c = ++a; d = b++; printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
, выведет на экране:
a=0, b=0, c=0, d=0 a=1, b=1, c=1, d=0
Объясняется такой результат так:
-
значение переменной a было увеличено на единицу, после чего это значение было присвоено переменной c;
-
значение переменной b было сначала присвоено переменной d и только потом увеличено на единицу.
Еще один пример:
int x, y; x = y = 0; printf("%d\n", x++ > 0); printf("%d\n", ++y > 0);
На экране будет выведено:
0 1
Это результат логических выражений, где 0 означает ложь, а 1 — истину. В данном случае, когда x сравнивается с нулем, то его значение еще не увеличено, а когда сравнивается у, то его значение уже больше нуля.
Применять операторы инкремента и декремента можно также к переменным вещественного типа.
Цикл while
Цикл while
в языке программирования C работает также как и в других языках программирования. По аналогии с условным выражением в инструкции if
, условное выражение при while
заключается в круглые скобки. Если тело цикла включает несколько выражений разделяемых точкой с запятой, то все тело заключается в фигурные скобки.
-
Присвойте переменной star значение 0. Пока значение star не достигнет 55 выводите на экран в строку по одной звездочке (
*
). -
С помощью цикла
while
запрограммируйте вывод на экран цифровых кодов и значений таблицы символов ASCII от 31 до 127 включительно. При этом после каждого десятого символа осуществляйте переход на новую строку. (Подсказка: чтобы переходить на новую строку, в циклеwhile
надо использовать инструкциюif
, в условии которой остаток1 от деления на 10 сравнивается с нулем.) Используя внешний и вложенный циклы
while
организуйте вывод таблицы умножения на экран.
1 Операция нахождения остатка от деления в языке C обозначается знаком процента %
.
Цикл do-while
Цикл do-while
отличается от while
лишь тем, что его тело будет выполнено хотя бы один раз независимо от условия выполнения цикла. Синтаксис цикла do-while
можно описать так (фигурные скобки необязательны, если выражение только одно):
do { выражение1; …; } while (логич_выражение);
Этот цикл называют циклом с постусловием. Его используют реже обычного while
. В принципе почти всегда можно обойтись без do-while
, но в определенных ситуациях его использование упрощает код. Допустим требуется вывести на экран отдельные цифры числа. Любое число состоит хотя бы из одной цифры, даже число 0. Можно решить эту задачу с использованием цикла while
:
while (a > 0) { printf("%d\n", a % 10); a = a / 10; }
Но в этом случае, если a равно 0, то цикл не выполнится ни разу. Пришлось бы перед циклом использовать инструкцию if
, в которой сравнивать переменную с 0. Использование же цикла do-while
решает эту проблему, т. к. его тело один раз выполнится даже при нулевом значении переменной:
do { printf("%d\n", a % 10); a = a / 10; } while (a > 0);
Цикл for
Представим синтаксис заголовка цикла for
языка программирования C так:
for (часть1; часть2; часть3)
Заголовок цикла for
включает три части, разделенных точкой с запятой; причем каждая часть может быть сложной, т. е. состоять из нескольких выражений, разделенных простой запятой. В первой части обычно указываются переменные и часто их начальные значения; во второй – с помощью логического(их) выражения(й) задаются условия, при которых выполняется тело цикла; в третью часть помещаются выражения, которые выполняются в конце каждой итерации цикла (чаще всего здесь изменяется значение переменной, заданной в первой части заголовка).
Вот так будет выглядеть программный код, выводящий таблицу символов на экран, в котором используется цикл for
:
unsigned char a; for (a = 31; a < 128; a++) { if (a % 10 == 0) printf("\n"); printf("%4d-%c", a, a); } printf("\n");
Напишите программу с использованием цикла for
, выводящую на экран таблицу умножения (Подсказка: как и в случае с while
следует использовать два цикла — внешний и вложенный.)
Операторы break и continue
Оператор break
позволяет прервать выполнение цикла, а continue
— прервать текущую итерацию (проход) цикла. Почти всегда можно обойтись без этих операторов, но иногда их использование позволяет упростить программный код и сделать его более понятным.
Рассмотрим пару примеров. Допустим, требуется проверить массив на наличие в нем хотя бы одного элемента со значением 0. Как только ноль будет обнаружен проверять оставшуюся часть массива уже нет смысла. Поэтому, чтобы не выполнять лишних итераций, используется оператор break
.
#define N 10 int arr[N] = {6, 5, -4, 3, -7, 2, 7, 0, 3, 9}; int new_arr[N], i, j; for (i=0; i<N; i++) { if (arr[i] == 0) { printf("\nIt contains zero"); break; } // не обязательно printf("%d ", arr[i]); } printf("\n");
Второй пример. Требуется из одного массива скопировать в другой только числа, которые больше 0. Можно с помощью continue
прерывать итерацию цикла, если очередной элемент меньше либо равен нулю.
for(i=0, j=0; i<N; i++) { if (arr[i] <= 0) continue; new_arr[j] = arr[i]; printf("%d ", new_arr[j]); j++; } printf("\n");
В данном случае использование continue
совсем не очевидно с точки зрения надобности, т. к. легко можно обойтись без него, если изменить условие при if
на противоположное, удалить continue
, а оставшийся код поместить в тело оператора if
.
Курс с решением задач:
pdf-версия