![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 3.6
#include “stdafx.h” #include < iostream> #include < math.h> using namespace std;
// Точность вычислений. const double eps = 1e-10;
int _tmain(int argc, _TCHAR* argv[]) { double x = 1., xp, a; setlocale(LC_ALL, " Russian"); cout < < “Введите значение a: “; cin > > a; if(a < = 0) { cout < < “Неверное значение a! \n”; return 1; }
do { xp = x; // Предыдущее значение x. x = (x + a/x)/2; // Текущее значение x. } while(fabs(x - xp) > eps)
cout < < “Квадратный корень “ < < x < < endl < < “Точное значение “ < < sqrt(a) < < endl;
getch(); return 0; }
Любой цикл while может быть приведен к эквивалентному ему циклу for и, наоборот, по следующей схеме: for(b1; b2; b3) оператор; b1; while(b2) { оператор; b3; } Часто встречающиеся ошибки при программировании циклов - использование в теле цикла неинициализированных переменных и неверная запись условия выхода из цикла. Чтобы избежать ошибок, рекомендуется: - проверить, всем ли переменным, встречающимся в правой части операторов присваивания в теле цикла, присвоены до этого начальные значения (а также возможно ли выполнение других операторов); - проверить, изменяется ли в цикле хотя бы одна переменная, входящая в условие выхода из цикла; - предусмотреть аварийный выход из цикла по достижению некоторого количества итераций - если в теле цикла требуется выполнить более одного оператора, нужно заключать их в фигурные скобки. Операторы цикла взаимозаменяемы, но можно привести некоторые рекомендации по выбору наилучшего в каждом конкретном случае. Оператор do while обычно используют, когда цикл требуется обязательно выполнить хотя бы раз (например, если в цикле производится ввод данных). Оператор for предпочтительнее в большинстве остальных случаев (однозначно - для организации циклов со счетчиками). Оператором while удобнее пользоваться в случаях, когда число итераций заранее не известно, очевидных параметров цикла нет или модификацию параметров удобнее записывать не в конце тела цикла. В C++ есть четыре оператора, изменяющих естественный порядок выполнения вычислений: - оператор безусловного перехода goto; - оператор выхода из цикла break; - оператор перехода к следующей итерации цикла continue; - оператор возврата из функции return. Оператор безусловного перехода goto. Оператор безусловного перехода имеет вид: goto идентификатор; где идентификатор - имя метки оператора, расположенного в той же функции, где используется оператор безусловного перехода. Передача управления разрешена на любой помеченный оператор в теле функции. Однако существует одно важное ограничение: запрещено «перескакивать» через описания, содержащие инициализацию объектов. Это ограничение не распространяется на вложенные блоки, которые можно обходить целиком. Следующий фрагмент иллюстрирует сказанное:
goto В; // Ошибочный переход, минуя описание float х = 0.0; // Инициализация // не будет выполнена goto В; // Допустимый переход, минуя блок { int n = 10; /* Внутри блока определена переменная*/ x = n*x + x; } В: cout < < " \tx = " < < х;
Все операторы блока достижимы для перехода к ним из внешних блоков. Однако при таких переходах необходимо соблюдать то же самое правило: нельзя передавать управление в блок, обходя инициализацию. Следовательно, будет ошибочным переход к операторам блока, перед которыми помещены описания с явной или неявной инициализацией. Это же требование обязательного выполнения инициализации справедливо и при внутренних переходах в блоке. Принятая в настоящее время дисциплина программирования рекомендует либо вовсе отказаться от оператора goto, либо свести его применение к минимуму и строго придерживаться следующих рекомендаций: - не входить внутрь блока извне; - не входить внутрь условного оператора, т.е. не передавать управление операторам, размещенным после служебных слов if или else; - не входить извне внутрь переключателя (switch); - не передавать управление внутрь цикла. Следование перечисленным рекомендациям позволяет исключить возможные нежелательные последствия бессистемного использования оператора безусловного перехода. Полностью отказываться от оператора goto вряд ли стоит. Есть случаи, когда этот оператор обеспечивает наиболее простые и понятные решения. Один из них - это ситуация, когда в рамках текста одной функции необходимо из разных мест переходить к одному участку программы. Если по каким-либо причинам эту часть программы нельзя оформить в виде функции (например, это может быть текст на ассемблере), то наиболее простое решение - применение безусловного перехода с помощью оператора goto. Такое положение возникает, например, при необходимости обрабатывать ошибки, выявляемые в процессе выполнения программы. Второй случай возникает, когда нужно выйти из нескольких вложенных друг в друга циклов или переключателей. Оператор break прерывания цикла и выхода из переключателя здесь не поможет, так как он обеспечивает выход только из самого внутреннего вложенного цикла или переключателя. Например, в задаче поиска в матрице хотя бы одного элемента с заданным значением для перебора элементов матрицы обычно используют два вложенных цикла. Как только элемент с заданным значением будет найден, нужно выйти сразу из двух циклов, что удобно сделать с помощью goto. Оператор break. Оператор break служит для принудительного выхода из цикла или переключателя. Определение «принудительный» подчеркивает безусловность перехода. Например, в случае цикла не проверяются и не учитываются условия дальнейшего продолжения итераций. Оператор break прекращает выполнение оператора цикла или переключателя и осуществляет передачу управления (переход) к следующему за циклом или переключателем оператору. При этом в отличие от перехода с помощью goto оператор, к которому выполняется передача управления, не должен быть помечен. Оператор break нельзя использовать нигде, кроме циклов и переключателей. Необходимость в использовании оператора break в теле цикла возникает, когда условия продолжения итераций нужно проверять не в начале итерации (циклы for, while), не в конце итерации (цикл do), а в середине тела цикла. В этом случае тело цикла может иметь такую структуру: { операторы; if(условие) break; операторы; } Циклы и переключатели могут быть многократно вложенными. Однако следует помнить, что оператор break позволяет выйти только из самого внутреннего цикла или переключателя. При многократном вложении циклов и переключателей оператор break не может вызвать передачу управления из самого внутреннего уровня непосредственно на самый внешний. Например, при решении задачи поиска в матрице хотя бы одного элемента с заданным значением удобнее всего пользоваться не оператором break, а оператором безусловной передачи управления (goto). Оператор continue. Оператор continue употребляется только в операторах цикла. С его помощью завершается текущая итерация и начинается проверка условия дальнейшего продолжения цикла, т.е. условий начала следующей итерации. Для объяснений действия оператора continue рекомендуется рассматривать следующие три формы основных операторов цикла: while(< условие>) { … if(< условие_прерывания>) continue; … }
do { … if(< условие_прерывания>) continue; … } while(< условие>);
for(< список_инициализации>; < условие>; < следующая_итерация>) { … if(< условие_прерывания>) continue; … }
В каждой из форм многоточием обозначены операторы тела цикла. Вслед за ними размещен пустой оператор с меткой continue. Если среди операторов тела цикла есть оператор continue и он выполняется, то его действие эквивалентно оператору безусловного перехода на метку continue. Пример 3.7. Вычислить значение специальной функции (интегральной показательной функции)
по ее разложению в ряд с точностью Чтобы вычислить сумму ряда найдем рекуррентное соотношение, позволяющее определить следующий член ряда исходя из значения текущего. Для этого разделим следующий член ряда на текущий. Текущий член ряда задается выражением
тогда как следующий член ряда может быть определен следующим образом
воспользовавшись свойством факториала
Отношение следующего и текущего членов ряда
Следовательно
Первый член ряда
Условие завершения вычисления суммы ряда может быть записано следующим образом
|