Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual_C_console.pdf
Скачиваний:
34
Добавлен:
16.05.2015
Размер:
954.14 Кб
Скачать

48

Циклы

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

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

Циклы с окончанием по внешнему условию достаточно часто (но не всегда) используются для решения задач методом последовательных приближений, называемым также итерационным процессом. При реализации итерационного процесса данные, полученные на предыдущем шаге вычислений, являются исходными данными для следующего шага вычислений. Для этой цели часто используются рекуррентные формулы, которые выражают последующее значение некоторой переменной через предыдущее значение. Например, для вычисления xn+1 используется xn, a подсчитанное в текущем шаге значение xn+1 является исходным значением для следующего шага вычислений.

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

49

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

В языке. С++ для реализации циклических процессов существуют три оператора: while, do-while и for. В принципе с помощью любого из этих операторов можно программировать любые циклические процессы, но более естественно (но не обязательно) оператор while применять для циклов с окончанием по внешнему условию, оператор do-while использовать для реализации итерационных процессов, а оператор for наиболее подходит для реализации циклов с заданным количеством повторений.

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

Формат этого оператора следующий: while (<условие>) <оператор>;

Оператор цикла while обеспечивает выполнение <оператора> (<оператор> может быть и составным, т.е. он может состоять из группы элементарных операторов), записанного после <условия>, до тех пор, пока условие выполнено. Если условие перестает удовлетворяться, то выполнение цикла прекращается. Если условие не удовлетворено перед началом цикла, то <оператор> не выполняется ни одного раза. Следует обращать особое внимание на то, чтобы одна из переменных, входящих в <условие>, обязательно изменялась в каком-либо из операторов, составляющих цикл (эти операторы обычно называют "телом" цикла). Если это требование не будет удовлетворено, то при повторном выполнении операторов цикла <условие> не будет изменяться, и цикл будет выполняться бесконечно (это явление называется "зацикливанием").

Один из простых способов обеспечения зацикливания заключается в записи точки с запятой (;) после круглой скобки, закрывающей <условие>. Наличие этой точки с запятой обозначает, что <оператор> является пустым (т.е. ничего не изменяет), а поэтому условие может не изменяться, что и приведет к зацикливанию. Указанная

50

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

Однако в языке C++ <условие> может содержать выражения, которые изменяют значения переменных при вычислении <условия>, и тем самым зацикливание может не происходить. Например, к вычисляемым выражениям при проверке условия можно отнести операции "++" и "--" и операцию присваивания, т.е. наличие точки с запятой после <условия> в операторе while не обязательно свидетельствует об ошибке.

Принципиально <условие> можно задать с помощью константы, имеющей значение "истинно", например, с помощью любого целого числа. Но в этом случае следует позаботиться, чтобы в "теле" цикла существовала проверка некоторого условия, изменение которого позволяет в итоге окончить выполнение оператора цикла.

Для иллюстрации использования оператора цикла while составим программу задачи определения количества цифр во введенном числе.

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

// Программа для подсчета количества цифр в числе.

#include "stdafx.h" #include <conio.h> #include <iostream> using namespace std; void _tmain()

{

long k;

// Вводимое число

int n = 0;

// Счетчик количества цифр в числе

51

cout << Введите число\n"; cin >> k;

while(k > 0)

{

k /= 10; n++;

}

cout << "Во введенном числе цифр: " << n; _getch();

}

Обрабатываемое число выбрано типа long, чтобы увеличить диапазон чисел

Оператор цикла do-while

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

do

{

операторы "тела" цикла

} while (<условие>);

Оператор цикла while отличается от оператора do-while проверкой условия продолжения цикла, которая осуществляется в конце, а не перед циклом. По этой причине операторы "тела" цикла всегда будут выполнены хотя бы один раз, независимо от условия выполнения цикла.

Составим программу для вычисления квадратного корня из числа 'а' по рекуррентной формуле Ньютона.

Xn+1 = 1 / 2 * (a / xn+ xn)

Если a >= 0, то с помощью этой формулы можно сформировать последовательность чисел, которая сходится к значению корня квадратного из числа a (если a < 0, то последовательность не имеет предела, поскольку квадратный корень из отрицательного числа извлечь нельзя).

52

Для вычисления по рекуррентным формулам необходимо задавать начальное значение переменных, которые будут исходными для первого шага расчета (в данном случае необходимо задать начальное значение xn). Обычно выбор начального значения переменных влияет только на количество повторений цикла: чем ближе выбранное число к конечному результату, тем меньше потребуется вычислений. Для приведенной формулы можно предполагать, что корнем из a является само число a. Это верно для a = 1, а для других значений a это не такой уж и плохой выбор.

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

Например, вычисление квадратного корня из 25 по приведенной рекуррентной формуле Ньютона при точности 0.00001 при начальном предположении x = 25 происходит следующим образом:

xn

Xn+1

Разность xn - Xn+1

25.00000

13.00000

12.0000000

 

 

 

13.00000

7.46153

5.5384600

 

 

 

7.46153

5.40602

2.0555100

 

 

 

5.40602

5.01524

0.3907790

 

 

 

5.01524

5.00002

0.1522240

 

 

 

5.00002

5.00000

0.0000229

 

 

 

5.00000

5.00000

0.0000000

 

 

 

Из примера видно, что для вычисления квадратного корня потребовалось 7 повторений цикла. Текст программы может иметь приведенный ниже вид:

// Программа вычисления квадратного корня по формуле Ньютона.

#include "stdafx.h" #include <conio.h> #include <math.h> #include <iostream>

 

53

using namespace std;

 

#define E 0.001

// Заданная точность вычисления корня

void _tmain()

 

{

 

double a,

// Число для извлечения корня

xold,

// Xn

xnew;

// Xn+1

cout << "Введите число \n";

cin >> a;

 

xnew = a; // Предположение о начальном значении корня

do

 

{

 

xold = xnew;

//

xnew = (a/xold + xold)/2;

} while (fabs (xold - xnew) > E); // Учет модуля разности cout << "Квадратный корень из " << a << " равен "<< xnew; _getch();

}

Вэтой программе для переменных используется тип double, поскольку программа должна работать с любыми числами. Функция fabs() вычисляет абсолютное значение своего аргумента. Прототип этой функции описан в заголовочном файле math.h. Вычисление абсолютного значения требуется из-за того, что при a > 1 последовательность сходится к корню квадратному сверху, а при a < 1 сходится снизу. Соответственно разность xold - xnew для этих случаев имеет разный знак.

Впрограмме вычисляются последующие члены последовательности, и постоянно проверяется разность между двумя последовательными членами. Перед каждым очередным вычислением последнее вычисленное значение (xnew) присваивается переменной xold и тем самым подготавливается вычисление следующего члена последовательности.

Таким образом, в "теле" цикла выполняются три действия:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]