Циклы в языке 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

Объясняется такой результат так:

Еще один пример:

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 заключается в круглые скобки. Если тело цикла включает несколько выражений разделяемых точкой с запятой, то все тело заключается в фигурные скобки.

  1. Присвойте переменной star значение 0. Пока значение star не достигнет 55 выводите на экран в строку по одной звездочке (*).

  2. С помощью цикла while запрограммируйте вывод на экран цифровых кодов и значений таблицы символов ASCII от 31 до 127 включительно. При этом после каждого десятого символа осуществляйте переход на новую строку. (Подсказка: чтобы переходить на новую строку, в цикле while надо использовать инструкцию if, в условии которой остаток1 от деления на 10 сравнивается с нулем.)

  3. Используя внешний и вложенный циклы 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-версия


Основы языка C. Курс




Все разделы сайта