Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Основы программирования на Си.doc
Скачиваний:
361
Добавлен:
02.05.2014
Размер:
1.3 Mб
Скачать

Цикл со счетчиком

Оператор цикла for

for(e1; e2; e3) s

является удобной сокращенной записью для цикла while вида

e1;

while(e2) {

s;

e3;

}

Выражение e1 служит для задания начальных условий выполнения цикла, выражение e2 обеспечивает проверку условия выхода из цикла, а выражение e3 модифицирует условия, заданные выражением e1. Любое из выражений e1, e2, e3 может быть опущено. Если опущено e2, то по умолчанию вместо него подставляется значение TRUE. Например, цикл for

for(;e2;) s;

с опущенными e1,e3 эквивалентен циклу

while(e2) s;

Цикл

for(;;) s;

со всеми опущенными выражениями эквивалентен циклу

while(TRUE) s;

т.е. эквивалентен бесконечному циклу. Такой цикл может быть прерван только явным выходом из него с помощью операторов break, goto, return, содержащихся в теле цикла s.

Несмотря на внешнее сходство с итеративными циклами for языков Паскаль и Ада или итеративными циклами do языков Фортран или ПЛ/1, цикл for языка Си не является их семантической копией. Цикл for языка Си обладает большей общностью, чем циклы for и do других языков. В отличии от этих циклов, в общем случае число итераций в цикле for языка Си не может быть определено до выполнения этого цикла.

Цикл for и его альтернатива цикл while семантически почти эквивалентны, но, как указывается в работе (Ritchie, D.M. 1980. The Programming Language - Reference Manual/. AT&T Bell Laboratories, Murray Hill, N.J. 07974), не идентичны. Например, рассмотрим случай, когда оператор s является оператором continue или составным оператором, содержащим оператор continue. Действие оператора continue состоит в переходе к концу цикла, что имеет различные последствия для цикла for и его эквивалента в форме цикла while. В случае с циклом for выражение e3 выполняется до вычисления значения выражения e2, в то время как в эквивалентном цикле while выражение e3 пропускается.

Гибкость конструкции for - следствие способа использования выражений в спецификации цикла. До сих пор первое выражение применялось для инициализации счетчика, второе - для задания его граничного значения, а третье - для увеличения его текущего значения на 1. Но кроме этой возможности существует еще и много других возможностей его применения, девять из которых мы приведем ниже.

Можно применять операцию уменьшения для счета в порядке убывания вместо счета в порядке возрастания:

for(n=10; n>0; n--)

printf("%d секунд!\n",n);

printf("Пуск! \n");

При желании можно вести счет двойками, десятками и т.д.:

for (n=2; n<60;n=n+13);

printf("%d\n",n);

Можно вести подсчет с помощью символов, а не только чисел:

for(ch = 'a';ch<='z';ch++)

printf("Величина кода ASCII для %с равна %d.\n",ch,ch);

При выполнении этого оператора будут выведены на печать все буквы от а до z вместе с их кодами ASCII. Этот оператор работает, поскольку символы в памяти машины размещаются в виде чисел, и потому в данном фрагменте ведется счет с использованием целых чисел.

Можно проверить выполнение некоторого произвольного условия, отличного от условия, налагаемого на число итераций. Рассмотрим пример в программе печатающей таблицу кубов целых чисел:

/* таблица кубов */

main( )

{

int num;

for(num=1; num<=6; num++)

printf("%5d %5d\n", num,num*num*num);

}

А теперь заменим спецификацию

for(num=1; num<=6; num++)

на

for(num=1; num<6; num++)

Это было бы целесообразно в случае, если бы нас больше занимало ограничение максимального значения диапазона кубов чисел, а не количество итераций.

Можно сделать так, чтобы значение некоторой величины возрастало в геометрической, а не в арифметической прогрессии, т.е. вместо прибавления фиксированного значения на каждом шаге цикла выполнялось бы умножение:

for(x=100.0; x<150.0; x=x*1.1)

printf("Ваш долг теперь %3.2f.\n",x);

В этом фрагменте программы значение переменной x умножается на 1.1 на каждом шаге цикла, что увеличивает ее на 10%. Результат выглядит следующим образом:

Ваш долг теперь 100.00.

Ваш долг теперь 110.00.

Ваш долг теперь 121.00.

Ваш долг теперь 133.10.

Ваш долг теперь 146.41.

В качестве третьего выражения можно использовать любое правильно составленное выражение. Какое бы выражение мы ни указали, его значение будет меняться при каждой итерации:

for (x=y=1; y<=75; y=5*x++)

printf("%10d %10d\n",x,y);

Обратите внимание, что в спецификации цикла проверяется значение y, а не x. В каждом из трех выражений, управляющих работой цикла for, могут использоваться любые переменные.

!

Хотя этот пример и правильный, он не может служить иллюстрацией хорошего стиля программирования. Программа выглядела бы гораздо понятнее, если бы мы не смешали процесс изменения переменной цикла с алгебраическими вычислениями.

Можно даже опустить одно или более выражений, но при этом нельзя опустить символы "точка с запятой". Тело цикла

for(;;) {

...

}

будет выполняться бесконечное число раз, поскольку пустое условие всегда считается истинным.

Первое выражение не обязательно должно инициализировать переменную. Вместо этого, например, там мог бы стоять оператор printf( ). Необходимо помнить только, что первое выражение вычисляется только один раз перед тем, как остальные части цикла начнут выполняться.

for(printf("Запоминайте числа! \n"); num != 6;)

scanf("%d",&num);

printf("Это как раз то, что я хочу!\n");

В этом фрагменте первое сообщение оказывается выведенным на печать один раз, а затем осуществляется прием вводимых чисел до тех пор, пока не поступит число 6.

Параметры, входящие в выражения, находящиеся в спецификации цикла, можно изменить при выполнении операций в теле цикла. Предположим, например, что у вас есть цикл со спецификацией следующего вида:

for(n=1; n<1000; n+t)

И если после нескольких итераций наша программа решает, что величина t слишком мала или велика, то оператор if внутри цикла может изменить значение параметра. В диалоговой программе пользователь может изменить этот параметр в процессе выполнения цикла.

Подведем итоги. В операторе for используются три выражения, управляющие работой цикла. Они разделены символом "точка с запятой". Инициализирующее выражение вычисляется только один раз до начала выполнения какого-нибудь из операторов цикла. Если проверяемое выражение оказывается истинным, или не равным нулю, тело цикла выполняется один раз. Затем вычисляется величина корректируемого выражения, и значение проверяемого выражения определяется вновь. Оператор for - это цикл с предусловием. Решение о том, выполнить ли в очередной раз тело цикла или нет, принимается до начала его прохождения. Поэтому может случиться так, что тело цикла не будет выполнено ни разу. Оператор, образующий тело цикла, может быть как простым, так и составным.

Операция "запятая" увеличивает гибкость использования цикла for, позволяя включить в его спецификацию несколько инициализирующих или корректирующих выражений.