МегаПредмет

ПОЗНАВАТЕЛЬНОЕ

Сила воли ведет к действию, а позитивные действия формируют позитивное отношение


Как определить диапазон голоса - ваш вокал


Игровые автоматы с быстрым выводом


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


Целительная привычка


Как самому избавиться от обидчивости


Противоречивые взгляды на качества, присущие мужчинам


Тренинг уверенности в себе


Вкуснейший "Салат из свеклы с чесноком"


Натюрморт и его изобразительные возможности


Применение, как принимать мумие? Мумие для волос, лица, при переломах, при кровотечении и т.д.


Как научиться брать на себя ответственность


Зачем нужны границы в отношениях с детьми?


Световозвращающие элементы на детской одежде


Как победить свой возраст? Восемь уникальных способов, которые помогут достичь долголетия


Как слышать голос Бога


Классификация ожирения по ИМТ (ВОЗ)


Глава 3. Завет мужчины с женщиной


Оси и плоскости тела человека


Оси и плоскости тела человека - Тело человека состоит из определенных топографических частей и участков, в которых расположены органы, мышцы, сосуды, нервы и т.д.


Отёска стен и прирубка косяков Отёска стен и прирубка косяков - Когда на доме не достаёт окон и дверей, красивое высокое крыльцо ещё только в воображении, приходится подниматься с улицы в дом по трапу.


Дифференциальные уравнения второго порядка (модель рынка с прогнозируемыми ценами) Дифференциальные уравнения второго порядка (модель рынка с прогнозируемыми ценами) - В простых моделях рынка спрос и предложение обычно полагают зависящими только от текущей цены на товар.

Операторы передачи управления





ОРГАНИЗАЦИЯ ЦИКЛОВ

 

Цель работы: научиться написанию программ на языке C# с использованием циклических структур и приемов обработки исключительных ситуаций.

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

В С# имеется четыре вида циклов: цикл с предусловием whi1е (do), цикл с постусловием do (while) или repeat, цикл с параметром for и цикл перебора foreach. Каждый из них состоит из определенной последовательности операторов.

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

Остальные операторы служат для управления процессом повторения вичислений – это начальные установки, проверка условия продолжения цикла и модификация параметра цикла (рис. 1). Один проход цикла называется итерацией.

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

Проверка условия продолжения цикла выполняется на каждой итерации либо до тела цикла (тогда говорят о цикле с предусловием, схема которого показана на рисунке 1, а),либо после тела цикла (цикл с постусловием,рис. 1, б). Разница между ними состоит в том, что тело цикла с постусловием всегда выполняется хотя бы один раз, после чего проверяется, надо ли его выполнять еще раз. Проверка необходимости выполнения цикла с предусловием делается до тела цикла, поэтому возможно, что он не выполнится ни разу.

Рисунок 1 – Структурные схемы операторов цикла

 

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

Цикл завершается, если условие его продолжения не выполняется. Возможно принудительное завершение как текущей итерации, так и цикла в целом. Для этого служат операторы break, continue, return и goto. Передавать управление извне внутрь цикла запрещается (при этом возникает ошибка компиляции).

Цикл с предусловием while

Формат оператора:

while (выражение) оператор

Выражение должно быть логического типа. Например, это может быть операция отношения или просто логическая переменная. Если результат вычисления выражения равен true, выполняется простой или составной оператор (блок). Эти действия повторяются до того момента, пока результатом выражения не станет значение false.

После окончания цикла управление передается на следующий за ним оператор.

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

Выражение вычисляется перед каждой итерацией цикла. Если при первой проверне выражение равно false, цикл не выполнится ни разу.

ВНИМАНИЕ

Если в теле цикла необходимо выполнить более одного оператора, необходимо заключить их в блок с помощью фигурных скобок.

В качестве примера рассмотрим программу, выводящую для аргумента X,изменяющегося в заданных пределах с заданным шагом, таблицу значений следующей функции:

Назовем начальное значение аргумента Хn, конечное значение аргумента – Хk, шаг изменения аргумента – dX и параметр t. Все величины вещественные. Программа должна выводить таблицу, состоящую из двух столбцов: значений аргумента и соответствующих им значений функции.

Опишем алгоритм в словесной форме:

1. Взять первое значение аргумента.

2. Определить, какому из интервалов оно принадлежит, и вычислить значение функции по соответствующей формуле.

3. Вывести строку таблицы.

4. Перейти к следующему значению аргумента.

5. Если оно не превышает конечное значение, повторить шаги 2-4, иначе закончить.

Шаги 2-4 повторяются многократно, поэтому для их выполнения надо организовать цикл. Текст программы приведен в листинге 1. Строки программы помечены соответствующими номерами шагов алгоритма. Обратите внимание на то, что условие продолжения цикла записано в его заголовке и проверяется до входа в цикл. Таким образом, если задать конечное значение аргумента, меньшее начального, даже при отрицательном шаге цикл не будет выполнен ни разу.

Листинг 1. Таблица значений функции, полученных с использованием цикла while

Результат работы программы:

ПРИМЕЧАНИЕ

При выводе использованы дополнительные поля спецификаций формата, определяющие желаемую ширину поля вывода под переменную (в данном случае – 6 позиций). В результате колонки при выводе таблицы получаются ровными.

Параметром этого цикла, то есть переменной, управляющей его выполнением является Х. Блок модификации параметра цикла представлен оператором, выполняющемся на шаге 4. Для перехода к следующему значению аргумента предыдущее значение наращивается на величину шага и заносится в ту же переменную. Начинающие часто забывают про модификацию параметра, в результате программа ≪зацикливается≫. Если с вами произошла такая неприятность, попробуйте для завершения программы нажать клавиши Ctrl+Break, а впредь перед запуском программы проверяйте:

• присвоено ли параметру цикла верное начальное значение;

• изменяется ли параметр цикла на каждой итерации цикла;

• верно ли записано условие продолжения цикла.

Распространенным приемом программирования является организация бесконечного цикла с заголовком while (true) и принудительным выходом из тела цикла по выполнению какого-либо условия с помощью операторов передачи управления. В листинге 2 приведен пример использования бесконечного цикла для организации меню программы.

Листинг 2. Организация меню

Результат работы программы:

 

Цикл с постусловием do

Цикл с постусловием реализует структурную схему, приведенную на рисунке 4, б, и имеет вид

do оператор while выражение;

Сначала выполняется простой или составной оператор, образующий тело цикла, а затем вычисляется выражение (оно должно иметь тип bool). Если выражение истинно, тело цикла выполняется еще раз и проверка повторяется. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления.

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

Пример программы, выполняющей проверку ввода, приведен в листинге 3.

Листинг 3. Проверка ввода

Результат работы программы:

Рассмотрим еще один пример применения цикла с постусловием – программу, определяющую корень уравнения cos(x) = х методом деления пополам с точностью 0,0001.

Исходные данные для этой задачи – точность, результат – число, представляющее собой корень уравнения. Оба значения имеют вещественный тип.

Суть метода деления пополам очень проста. Задается интервал, в котором есть ровно один корень (следовательно, на концах этого интервала функция имеет значения разных знаков). Вычисляется значение функции в середине этого интервала.

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

В приведенной далее программе (листинг 4) исходный интервал задан с помощью констант, значения которых взяты из графика функции. Для уравнений, имеющих несколько корней, можно написать дополнительную программу, определяющую (путем вычисления и анализа таблицы значений функции) интервалы, содержащие ровно один корень (программа печати таблицы значений функции приведена в листинге 1).

Листинг 4. Вычисление корня нелинейного уравнения

Результат работы программы:

 

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

Цикл с параметром for

Цикл с параметром имеет следующий формат:

for (инициализация; выражение; модификации) оператор;

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

for (int l = 0, j = 2; ...

int k, m;

for (k = 1, m = 0; ...

Областью действия переменных, объявленных в части инициализации цикла, является цикл. Инициализация выполняется один раз в начале исполнения цикла.

Выражение типа bool определяет условие выполнения цикла: если его результат равен true, цикл выполняется. Цикл с параметром реализован как цикл с предусловием.

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

Простой или составной оператор представляет собой тело цикла. Любая из частей оператора for может быть опущена (но точки с запятой надо оставить на своїх местах!).

Для примера вычислим сумму чисел от 1 до 100:

for (int l = 1, s = 0; l<=100; l++) s += l;

В листинге 5 приведена программа, выводящая таблицу значений функции из листинга 1.

Листинг 5. Таблица значений функции, полученных с использованием цикла for

Результат работы программы:

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

СОВЕТ

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

Любой цикл while может быть приведен к эквивалентному ему циклу for и оборот. Например, два следующих цикла эквивалентны:

Цикл for:

for (bl; b2; b3) оператор;

Цикл whilе:

b1;

while (b2)

{

оператор;

b3

}

Цикл перебора foreach

Цикл foreach используется для просмотра всех объектов из некоторой группы данных, например массива, списка или другого контейнера.

Операторы передачи управления

В С# есть пять операторов, изменяющих естественный порядок выполнения вычислений:

• оператор безусловного перехода goto;

• оператор выхода из цикла break;

• оператор перехода к следующей итерации цикла continue;

• оператор возврата из функции return;

• оператор генерации исключения throw.

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

Оператор goto

Оператор безусловного перехода goto используется в одной из трех форм:

goto метка;

goto case константное_выражение;

goto default;

В теле той же функции должна присутствовать ровно одна конструкция вида

метка: оператор;

Оператор goto метка передает управление на помеченный оператор. Метка – это обычный идентификатор, областью видимости которого является функция, в теле которой он задан. Метка должна находиться в той же области видимости, что и оператор перехода. Использование этой формы оператора безусловного перехода оправдано в двух случаях:

• принудительный выход вниз по тексту программы из нескольких вложенных циклов или переключателей;

• переход из нескольких точек функции вниз по тексту в одну точку (например, если перед выходом из функции необходимо всегда выполнять какие-либо действия).

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

Вторая и третья формы оператора goto используются в теле оператора выбора switch. Оператор goto case константное_выражение передает управление на соответствующую константному выражению ветвь, а оператор goto default – на ветвь default. Надо отметить, что реализация оператора выбора в С# на редкость неудачна, и наличие в нем оператора безусловного перехода затрудняет понимание программы, поэтому лучше обходиться без него.

Оператор break

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

Для примера рассмотрим программу вычисления значения функции ch(х) (гиперболический косинус) с точностью в = 10-6 с помощью бесконечного ряда Тейлора по формуле

Этот ряд сходится при любих значениях аргумента. Для достижения заданной точности требуется суммировать члены ряда, абсолютная величина которых больше е. Для сходящегося ряда модуль члена ряда Сп при увеличении п стремится к нулю. При некотором п неравенство | Сп | > е перестает выполняться и вычисления прекращаются.

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

До выполнения программы предсказать, сколько членов ряда потребуется просуммировать, невозможно. В цикле такого рода есть опасность, что он никогда не завершится – как из-за возможных ошибок в вычислениях, так и из-за ограниченной области сходимости ряда (данный ряд сходится на всей числовой оси, но существуют ряды Тейлора, которые сходятся только для определенного интервала значений аргумента). Поэтому для надежности программы необходимо предусмотреть аварийный выход из цикла с печатью предупреждающего сообщения по достижении некоторого максимально допустимого количества итераций. Для выхода из цикла применяется оператор break.

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

Для уменьшения количества выполняемых действий следует воспользоваться рекуррентной формулой получения последующего члена ряда через предыдущий:

где – некоторый множитель. Подставив в эту формулу и , получим выражение для вычисления :

В листинге 6 приведен текст программы с комментариями.

Листинг 6. Вычисление суммы бесконечного ряда

Результат работы программы:

Получение суммы бесконечного ряда – пример вычислений, которые принципиально невозможно выполнить точно. В данном случае мы задавали желаемую погрешность вычислений с помощью значения е. Это значение не может быть меньше, чем самое малое число, представляемое с помощью переменной типа double, но при задании такого значения точность результата фактически будет гораздо ниже из-за погрешностей, возникающих при вычислениях. Они связаны с конечностью разрядной сетки.

В общем случае погрешность результата складывается из нескольких частей:

• погрешность постановки задачи (возникает при упрощении задачи);

• начальная погрешность (точность представления исходных данных);

• погрешность метода (при использовании приближенных методов решения задачи);

• погрешности округления и вычисления (поскольку величины хранятся в ограниченном количестве разрядов).

Специфика машинных вычислений состоит в том, что алгоритм, безупречный с точки зрения математики, при реализации без учета возможных погрішностей может привести к получению результатов, не содержащих ни одной верной значащей цифры! Это происходит, например, при вычитании двух близких значений или при работе с очень большими или очень малыми числами.

Оператор continue

Оператор перехода к следующей итерации текущего цикла continue пропускает все операторы, оставшиеся до конца тела цикла, и передает управление на начало следующей итерации.

Перепишем основной цикл листинга 6 с применением оператора continue:

Результат работы программы:

Оператор return

Оператор возврата из функции return завершает выполнение функции и передает управление в точку ее вызова. Синтаксис оператора:

return [выражение];

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





©2015 www.megapredmet.ru Все права принадлежат авторам размещенных материалов.