Книга: Язык Си - руководство для начинающих
Гибкость конструкции for
Гибкость конструкции 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. Параметры, входящие в выражения, находящиеся в спецификации цикла, можно изменить при выполнении операций в теле цикла. Предположим, например, что у вас есть цикл со спецификацией следующего вида:
for(n = 1; n < 1000; n + = delta)
И если после нескольких итераций ваша программа решает, что величина параметра delta слишком мала или велика, оператор if внутри цикла может изменить значение параметра. В диалоговой программе пользователь может изменить этот параметр в процессе выполнения цикла.
Короче говоря, большая свобода выбора вида выражений, управляющих работой цикла for, позволяет с помощью этой конструкции делать гораздо больше, чем просто выполнять фиксированное число итераций. Возможности цикла for могут быть еще более расширены путем использования операций, которые мы вкратце обсудим ниже.
- Forced writes - палка о двух концах
- Forced Writes
- Chapter 15. Graphical User Interfaces for Iptables
- What NAT is used for and basic terms and expressions
- Information request
- SCTP Generic header format
- System tools used for debugging
- FORWARD chain
- How to use this License for your documents
- 1. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- Оператор цикла foreach
- Foreword