Язык Си - руководство для начинающих - M. УЭИТ
Шрифт:
Интервал:
Закладка:
ЦИКЛ for
В цикле for все три вышеуказанных действия собраны вместе. Используя цикл for, фрагмент, приведенный выше, можно записать в виде одного оператора:
for(count = 1; count <= NUMBER; count++)
printf(" Будь моим Валентином! n ");
В круглых скобках содержатся три выражения, разделенные символом "точка с запятой". Первое из них служит для инициализации счетчика. Она осуществляется только один раз - когда цикл for начинает выполняться. Второе выражение - для проверки условия; она производится перед каждым возможным выполнением тела цикла. Когда выражение становится ложным (или в общем случае равным нулю), цикл завершается. Третье выражение вычисляется в конце каждого выполнения тела цикла. Ранее мы использовали его для увеличения значения счетчика count, но, вообще говоря, его использование этим не ограничивается. За заголовком цикла for следует простой или составной оператор. Рис. 8.3 служит иллюстрацией структуры цикла for.
РИС. 8.3. Структура цикла for.
Cейчас мы продемонстрируем, как цикл for используется в программе, печатающей таблицу кубов целых чисел:
/* таблица кубов*/
main( )
{
int num;
for(num=1;num<=6;num++)
printf(" %5d %5d n", num, num*num*num);
}
программа выводит на печать числа от 1 до 6 и их кубы:
1
8
27
64
125
216
Из первой строки цикла for мы сразу можем узнать всю информацию о параметрах цикла: начальное значание переменной num, конечное значение, а также насколько увеличивается значение переменной num при каждом выполнении тела цикла. Цикл for часто используется для реализации в программе временной задержки с целью согласования скорости реагирования (в даном случае замедления) машины с возможностями восприятия человека.
for(n=1; n<= 10000; n++);
Этот цикл заставляет машину считать до 10000. Единственный символ "точка с запятой", расположенный во второй строке, интересует нас о том, что никаких других действий в этом цикле не производится. Такой уединенный символ "точка с запятой" можно представлять себе как "пустой" оператор, т. е. оператор, который не выполняет никаких действий.
Гибкость конструкции for
Хотя цикл for на первый взгляд очень похож на цикл DO в Фортране, цикл FOR в Паскале и цикл FOR ... NEXT в Бейсике, for в Си является гораздо более гибким средством, чем любой из упомянутых. Эта гибкость - следствие способа использования упомянутых выше трех выражений в спецификации цикла for. До сих пор первое выражение применялось для инициализации счетчика, второе - для задания его граничного значения, а третье - для увеличения его текущего значения на 1. Использованный таким образом оператор for в языке Си совершенно аналогичен упомянутым выше соответствующим операторам в других языках. Но, кроме описанной, существует еще и много других возможностей его применения, девять из которых мы приводим ниже.
1. Можно применять операцию уменьшения для счета в порядке убывания вместо счета в порядке возрастания:
for(n = 10; n > 0; n--)
printf(" %d секунд!n", n);
printf(" Пуск!n");
2. При желании вы можете вести счет двойками, десятками и т. д.
for (n = 2; n & 60; n = n + 13)
printf(" %dn", n);
В этом операторе значение переменной n будет увеличиваться на 13 при каждом выполнении тела цикла; будут напечатаны числа 2, 15, 28, 41 и 54.
Заметим, между прочим, что в языке Си имеется и другая сокращенная форма записи для увеличения переменной на фиксированную величину. Вместо выражения n = n + 13 можно воспользоваться записью n + = 13.
Знак += определяет "аддитивную операцию присваивания", в результате выполнения которой величина, стоящая справа, прибавляется к значению переменной, расположенной слева. Дополнительные детали, относящиеся к этой операции, приведены ниже.
3. Можно вести подсчет с помощью символов, а не только чисел.
for(ch = 'а' ; ch <= 'z'; ch++)
printf(" Величина кода ASCII для %с равна %d.n" , ch, ch);
При выполнении этого оператора будут выведены на печать все буквы от а до z вместе с их кодами ASCII. Этот оператор "работает", поскольку символы в памяти машины размещаются в виде чисел и поэтому в данном фрагменте счет ведется на самом деле с использованием целых чисел.
4.Можно проверить выполнение некоторого произвольного условия, отличного от условия, налагаемого на число итераций. В нашей программе таблица кубов вы могли бы заменить спецификацию
for(num = 1; num <= 6; num ++)
на
for(num = 1; num *num *num <= 216; num++)
Это было бы целесообразно в случае, если бы нас больше занимало ограничение максимального значения диапазона кубов чисел, а не количества итераций.
5. Можно сделать так, чтобы значение некоторой величины возрастало в геометрической, а не в арифметической прогрессии, т. е. вместо прибавления фиксированного значения на каждом шаге цикла, выполнялось бы умножение:
for(debt = 100.0; debt < 150.0; debt = debt*l.l)
printf(" Baшдолгтеперь$%.2f.n", debt);
В этом фрагменте программы значение переменной debt умножается на 1.1 на каждом шаге цикла, что увеличивает ее на 10%. Результат выглядит следующим образом:
Ваш долг теперь $100.00
Ваш долг теперь $110.00
Ваш долг теперь $121.00
Ваш долг теперь $133.10
Ваш долг теперь $146.41
Как вы уже смогли догадаться, для умножения debt на 1.1 также существует сокращенная запись. Мы могли бы использовать выражение
debt * = 1.1
для получения того же результата. Знак *= определяет "мультипликативную операцию присваивания", при выполнении которой значение переменной, расположенной слева, умножается на величину, стоящую справа. (См. пояснения ниже, на с. 226.)
6. В качестве третьего выражения можно использовать любое правильно составленное выражение. Какое бы выражение вы ни указали, его значение будет меняться при каждой итерации.
for(x = 1; у <= 75; у = 5*х++ + 10);
printf("%10d %10dn", x, у);
В этом фрагменте выводятся на печать значения переменной x и алгебраического выражения 5*х + 10. Результат будет выглядеть так:
1 55
2 60
3 65
4 70
5 75
Обратите внимание, что в спецификации цикла проверяется значение у, а не x. В каждом из трех выражений, управляющих работой цикла for, могут использоваться любые переменные.
Хотя этот пример и правилен, он не может служить иллюстрацией хорошего стиля программирования. Программа выглядела бы гораздо понятнее, если бы мы не смешали процесс изменения переменной цикла с алгебраическими вычислениями.
7. Можно даже опустить одно или более выражений (но при этом нельзя опустить символы "точка с запятой"). Необходимо только включить в тело цикла несколько операторов, которые в конце концов приведут к завершению его работы.
ans = 2;
for (n = 3; ans <= 25;) ans = ans*n;
При выполнении этого цикла величина n останется равной 3. Значение переменной ans вначале будет равно 2, потом увеличится до 6, 18, а затем будет получена окончательная величина 54. (18 меньше 25, поэтому в цикле for выполняется еще одна итерация, и 18 умножается на 3, давая результат 54). Тело цикла
for(; ;)
printf(" Я хочу сделать что-нибудьn");
будет выполняться бесконечное число раз, поскольку пустое условие всегда считается истинным.
8. Первое выражение не обязательно должно инициализировать переменную. Вместо этого, например, там мог бы стоять оператор printf( ) некоторого специального вида. Необходимо помнить только, что первое выражение вычисляется только один раз перед тем, как остальные части цикла начнут выполняться.
for(printf("Запоминайте введенные числа!n"); num == 6;)
scanf(" %d", &num);
printf("Это как раз то, что я хочу!n");
В этом фрагменте первое сообщение оказывается выведенным на печать один раз, а затем осуществляется прием вводимых чисел до тех пор, пока не помтупит число 6.
9. Параметры, входящие в выражения, находящиеся в спецификации цикла, можно изменить при выполнении операций в теле цикла. Предположим, например, что у вас есть цикл со спецификацией следующего вида: