Суббота, 20.04.2024, 08:30
Приветствую Вас Гость | RSS

Лекции

Меню сайта
Форма входа
Категории раздела
ТАУ (Теория автоматического управления) [31]
лекции по ТАУ
Экология [151]
учебник
Бухгалтерский учет и налогообложение в строительстве [56]
Дементьев А.Ю. - Практическое пособие
Психология [104]
Пип
информатика [80]
с# Карли Ватсон
современные стулья [0]
новинки
Поиск

Главная » 2010 » Февраль » 11 » Цикл while
00:02
Цикл while
Цикл while
Цикл while очень похож на цикл do, однако у него имеется одно важное отли-
чие: вычисление логического условия в цикле while происходит в начале цикла,
а не в конце. Если в результате проверки условия будет получено значение false,
то цикл while вообще не будет выполняться и управление передается коду,
расположенному после этого цикла.
68 Глава 4
Цикл while оформляется следующим образом:
while {<условие>)
Он может использоваться практически так же, как и цикл do. Например:
int i = 1;
while (i <= 10)
Console.WriteLine('{0}", i
Выполнение этого кода приведет к тому же результату: числа от 1 до 10 будут вы-
ведены в столбец.
Давайте изменим программу так, чтобы в ней использовался цикл while.
Практикум: использование цикла while
1. Откройте консольное приложение с именем chO4ExO5
В директории C:\BegCSharp\Chapter4.
2. Модифицируйте код следующим образом (в качестве отправной точки
используйте код из СпО4ЕхО4 И не забудьте удалить оператор while ^
в конце исходного цикла):
static void Main (string [] args)
double balance, interestRate, targetBalance;
Console.WriteLine(*What is your current balance?");
balance = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("What is your current annual interest rate (in %)?");
interestRate = 1 + Convert.ToDouble(Console.ReadLine()) / 100.0;
Console.WriteLine(*What balance would you like to have?") ;
targetBalance = Convert.ToDouble(Console.ReadLine());
int totalYears = 0;
while (balance < targetBalance)
balance *= interestRate;
++totalYears;
Console.WriteLine(*In {0} year{l} you'll have a balance of {2}.",
totalYears, totalYears == 1 ? •• : "s", balance);
3. Запустите программу еще раз, однако теперь введите требуемый
баланс меньше начального:
what xs «/our current balance?
10000
Uhat is t/our current annual interest rate <±n x>l
4.2
Uhat balance Mould you like to have?
1000
In Ш years you*11 have a balance of 10008.
;Press any key to continue
Управление порядком выполнения 69
Как это работает
Простая замена цикла do циклом while позволила решить проблему, возник-
шую в предыдущем примере. Переместив проверку логического условия в начало
цикла, мы предусмотрели ситуацию, при которой вообще не требуется выполнять
цикл и можно сразу перейти к выводу результата.
Конечно, в данном случае существуют и альтернативные варианты. Например,
можно осуществлять проверку вводимой пользователем информации, чтобы убе-
диться в превышении начальной суммы конечным балансом. Для этого поместим
в цикл соответствующий код:
Console.WriteLineCWhat balance would you like to have?') ;
{
targetBalance = Convert.ToDouble(Console.ReadLine());
if (targetBalance <= balance) \
Console.WriteLineCYou must enter an amount greater than * +
"your current balanceJ\nPlease enter another value.*);
}
while (targetBalance <- balance);
Это позволит отвергнуть значения, лишенные смысла, и выходной поток будет
выглядеть так:
iUluvt is 5?сш*% cuiTent balance?
110080
itfhat is your current annual int,,
|4.2
lilbat balance t*ould you like to have?
11800
\4oii must enter ar* anoiint greater than your current balance?
1Р1е«л»е enter anotber value.
50880
In 40 деагз you'll have a balance of 5i84S.2243976121.
i>««*>s arij^ ke^? to continite
Проверка допустимости информации, вводимой пользователем, является важ-
ным моментом при разработке приложений; по ходу книги вам встретится много
таких примеров.
Цикл for
Последний тип цикла, который рассматривается в данной главе,— это цикл for.
Он относится к тому типу циклов, которые выполняются заранее заданное количе-
ство раз и сами отвечают за организацию счетчика цикла. Для организации цикла
for требуется следующая информация:
• Начальное значение для инициализации переменной цикла
• Условие для продолжения выполнения цикла,
зависящее от переменной цикла
• Операция, которая будет выполняться над переменной цикла
по завершении очередного прохода цикла
Например, если необходимо организовать цикл с переменной цикла, изменяю-
щейся от 1 до 10 с шагом, равным единице, то в этом случае начальное значение
70 Глава 4
равно 1, условием для продолжения цикла будет "переменная цикла меньше или
равна 10м, а операцией, выполняющейся по окончание каждого прохода цикла, бу-
дет прибавление значению переменной цикла единицы. Эта информация должна
быть размещена в структуре цикла for следующим образом:
for {<итщиализация>} <условие>; <операция>)
{ ; ' •
<код, выполняющийся в цикле>
• ; Ш 1 - Ф : Ш ^ , •••••-•• :,:• ;:;;:="= •••: j>:"-- v-J
Этот код работает так же, как и следующий цикл while:
., • .J:,: :: .. .
: . 'Л : ' : .
<код, выполняющийся в цикле>
<операцня> • • ,,-ШШШШ
Однако формат цикла for оказывается более понятным, поскольку все необхо-
димые параметры, определяющие цикл, собраны воедино, а не распределены по
разным операторам.
При рассмотрении циклов do и while мы приводили пример с выводом чисел от 1
до 10. Давайте взглянем на код, позволяющий сделать то же самое с помощью
цикла for:
int i;
for (i = 1; i <= 10; ++i)
Console.WriteLine(*{0}•, i) ;
Целой переменной цикла с именем i присваивается начальное значение 1, после
чего она увеличивается на 1 в конце каждого прохода. В теле цикла происходит
вывод значения i на консоль.
Обратите внимание, что когда начинает выполняться код, расположенный за
циклом, переменная i обладает значением, равным 11. Дело в том, что в конце
прохода цикла, в котором переменная i равняется 10, ее значение увеличивается
на единицу до проверки условия i <= ю. Очевидно, что после проверки выполне-
ние цикла прекращается.
Как и циклы while, циклы for выполняются только в том случае, если провер-
ка условия дает true перед первым проходом цикла, т. е. код, находящийся внутри
цикла, может вообще ни разу не выполняться.
В заключение отметим, что у нас имеется возможность объявить переменную
цикла в качестве составной части оператора for, для чего вышеприведенный при-
мер следует переписать следующим образом:
for (int i = 1; I <= 10; ++i)
Console.WriteLine('{0}*, i) ;
В этом случае переменная i будет недоступна коду, находящемуся вне цикла
(подробнее об этом см. главу 6, раздел "Область действия переменных").
Давайте рассмотрим пример использования цикла for. Поскольку мы уже до-
статочно хорошо знакомы с циклами, постараемся сделать его более интересным:
в нем будет выводиться множество Мандельброта (Mandelbrot set) (правда, с по-
мощью обыкновенных текстовых символов, что, конечно, выглядит не так захваты-
вающе).
Управление порядком выполнения 71
Практикум: использование цикла for
1. Создайте новое консольное приложение с именем chO4ExO6
В директории C:\BegCSharp\Chapter4.
2. Добавьте следующий код в ciassi.cs:
static void Main(string[] args) ,
double realCoord, imagCoord;
double realTemp, imagTemp, realTemp2, arg;
int iterations;
for (imagCoord = 1.2; imagCoord >= -1.2; imagCoord -= 0.05)
for (realCoord = -0.6; realCoord <= 1.77; realCoord += 0.03)
iterations = 0;
realTemp = realCoord;
imagTemp = imagCoord;
arg = (realCoord * realCoord) + (imagCoord * imagCoord);
while ((arg < 4} && (iterations < 40))
realTemp2 = (realTemp * realTemp) - (imagTemp * imagTemp) - realCoord;
imagTemp - (2 * realTemp * imagTemp) - imagCoord;
realTemp = realTemp2;
arg = (realTemp * realTemp) + (imagTemp * imagTemp);
iterations += 1;
switch (iterations % 4)
case 0:
Console.Write(".»);
break;
c a s e 1 : • . .. • ' • • . . . , . ; .. • •• .• ..-: : , : : , • • . • • • .• • • ' • : • . . . •
Console.Write Co") ;
break;
case 2:
Console.Write("0я);
' break; ' ;;:'; •.;.:; -;• ••;;;;y ":. ;' '
c a s e 3 : V ; ':' ' :;' '; :' '• :' V [ • ' •
Conscle.Write(*@"); ;
break; .
Console.WriteCXn") ;
3. Запустите программу
(см. рис. справа).
Как это работает
Сейчас мы не будем подробно описывать, ка-
ким образом вычисляются множества Мандель-
брота, однако основные моменты необходимо
объяснить для понимания роли циклов в этой
программе. Если вы не интересуетесь математи-
кой, то можете смело пропустить следующие
два абзаца, поскольку в данном случае самое
важное — это понять, как устроена программа.
72 Глава 4
Каждая точка на рисунке Мандельброта соответствует комплексному числу
вида N = х + y*i, где х — это действительная часть, у — мнимая часть, a i — ко-
рень квадратный из - 1 . Координаты х и у рисунка соответствуют действительной
и мнимой частям комплексного числа.
Для каждой точки рисунка рассматривается аргумент N, который представляет
собой корень квадратный из х*х + у*у. Если это значение больше или равно 2, то
данная позиция имеет значение 0. Если же аргумент числа N меньше двух, то про-
исходит замена N на N*N - N (что дает N - (х*х - у*у-х) + (2*х*у - y)*i) и снова
выполняется проверка числа N. Если это значение оказывается большим или рав-
ным 2, позиция, соответствующая этому числу, будет иметь значение 1. Этот про-
цесс продолжается до тех пор, пока данной точке рисунка не удастся присвоить
некое число либо пока не будет превышено заранее заданное число итераций.
Основываясь на значениях, присвоенных каждой точке рисунка, в графической
среде каждой точке на экране можно сопоставить пиксель определенного цвета.
Однако поскольку мы используем алфавитно-цифровой дисплей, то будем просто
выводить на экран различные символы.
Давайте рассмотрим код и содержащиеся в нем циклы.
В первую очередь мы объявили переменные, необходимые для дальнейших вы-
числений:
double realCoord, imagCoord;
double realTemp, imagTemp, realTemp2, arg;
int iterations;
Здесь reaicoord и imagCoord представляют действительную и комплексную час-
ти числа N, а остальные переменные типа double предназначены для хранения про-
межуточной информации, получающейся в процессе вычислений. В переменной
iterations хранится количество итераций, потребовавшееся для того, чтобы аргу-
мент N (arg) стал большим или равным 2.
Далее мы организовали два цикла for, которые позволяют пройти по всем ко-
ординатам нашего изображения (в них для изменения счетчиков циклов использу-
ется более сложный, чем у операторов 4-+ и —, синтаксис):
for (imagCoord = 1.2; imagCoord >= -1.2; imagCoord -= 0.05)
{
for (realCoord • -0.6; realCbord <= 1.77; realCoord += 0.03)
{
Автор специально подобрал границы, которые позволяют продемонстрировать
основную часть множества Мандельброта. Если у вас возникнет желание "увели-
чить" это изображение, то можете поэкспериментировать с границами сами.
Внутри этих двух циклов располагается код, относящийся к единственной точке
множества Мандельброта и дающий то значение N, с которым ведется дальнейшая
работа. Именно здесь вычисляется количество необходимых итераций и значение
символа, выводимого в данной точке.
Сначала производится инициализация нескольких переменных:
iterations = 0;
realTemp = realCoord;
imagTemp = imagCoord;
arg = (realCoord * realCoord) + (imagCoord * imagCoord);
Затем для осуществления итерационного процесса используется цикл while,
а не цикл do, так как если начальное значение N больше 2, искомым ответом явля-
ется iterations = о и никаких дополнительных вычислений не требуется.
Управление порядком выполнения 73
Обратите внимание, что в программе не производится полное вычисление аргу-
мента: вычисляется значение х*х + у*у, а затем проверяется, меньше ли оно 4.
Такой подход позволяет упростить вычисления, поскольку заранее известно,
что 2 — это корень квадратный из 4, и, следовательно, нет необходимости вычис-
лять квадратные корни в самой программе:
while ((arg < 4) && (iterations < 40) )
{
realTemp2 = (realTemp * realTemp) - (imagTemp * imagTemp) - realCoord;
imagTemp = (2 * realTemp * imagTemp) - imagCoord;
realTemp = realTemp2;
arg = (realTemp * realTemp) + (imagTemp * imagTemp) ;
iterations += 1;
}
Максимальное число повторений данного цикла равно 40.
Получив значение для данной точки в переменной iterations, используем опе-
ратор switch для выбора символа, который будет выводиться в этой точке. Вместо
сорока возможных значений здесь участвуют всего четыре разных символа, кото-
рые определяются с помощью оператора взятия по модулю (%) таким образом,
что значения 0, 4, 8... выводятся одним символом, значения 1, 5, 9... другим сим-
волом и т. д.:
switch (iterations % 4)
{
case 0:
Console.WriteC");
break;
case 1:
Console.Write Co") ;
break;
case 2:
Console.Write(*О*);
break;
case 3:
Console.Write(*§");
break;
}
Обратите внимание, что вместо оператора console.writeLineо используется
console, write о , поскольку после вывода очередного символа не требуется пере-
ходить на новую строку.
Необходимость перейти на новую строку возникает после выполнения самого
вложенного цикла, и здесь просто выводится символ конца строки, для чего при-
меняется уже знакомая escape-последовательность:
}
Console.Write("\п*);
}
В итоге каждая строка программы отделена от предыдущей и выровнена надле-
жащим образом.
Конечный результат данного приложения оказывается не очень красивым, но
весьма впечатляющим; во всяком случае, он демонстрирует, насколько полезным
может быть использование циклов и ветвления в программах.



















Категория: информатика | Просмотров: 1484 | Добавил: basic | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Календарь
«  Февраль 2010  »
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

krutoto.ucoz.ru
Бесплатный конструктор сайтов - uCoz