Практическое занятие 5. Организация циклов

 

 

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

Операторы цикла задают многократное исполнение операторов тела цикла. В языке С++ определены три оператора цикла:

· цикл с предусловием:

while (выражение-условие)

тело_цикла

· цикл с постусловием:

do

тело_цикла

while (выражение-условие);

· цикл с параметром:

for (выражение-инициализатор;

выражение-условие; выражение-модификатор)

тело_цикла

 

Тело_цикла не может быть описанием или определением. Это либо отдельный (в том числе пустой) оператор, который всегда завершается точкой с запятой, либо составной оператор, либо блок (заключаются в фигурные скобки). Выражение-условие – это во всех операторах скалярное выражение (чаще всего логическое или арифметическое выражение), определяющее условие продолжения выполнения итераций цикла (если значение выражения-условия true, т.е. не равно нулю). Выражение-инициализ атор задаёт начальные значения необходимым параметрам; выполняется один раз перед первой итерации цикла; может содержать несколько выражений, разделённых запятой «,». Выражение-м одификатор задаёт изменение параметров цикла; выполняется после каждой итерации цикла; может содержать несколько выражений, разделённых запятой «,».

Прекращение выполнения цикла возможно в следующих случаях:

- ложное (false или 0) значение проверяемого выражения-условия;

- выполнение в теле цикла оператора передачи управления (break, goto, return) за пределы цикла.

 

Оператор while

 

Оператор while ("повторять, пока истинно условие") называется оператором цикла с предусловием. Он имеет следующий вид:

 

while (выражение-условие)

Тело_цикла

 

При входе в цикл вычисляется выражение-условие. Если его значение отлично от нуля (true), то выполняется тело_цикла. Затем вычисление выражения-условия и выполнение операторов тела_цикла повторяются последовательно, пока значение выражения-условия не станет ложным, т.е. равным false или 0.

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

 

// Бесконечный цикл с пустым оператором

while (1); // в качестве тела

 

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

 

Оператор do…while

 

Оператор do ("повторять") называется оператором цикла с постусловием. Он имеет следующий вид:

 

do тело_цикла

while (выражение-условие);

 

При входе в цикл do обязательно выполняется тело_цикла. Затем вычисляется выражение-условие и, если его значение равно true (¹0), вновь выполняется тело_цикла.

К выражению-условию в цикле do требования те же, что и для цикла while – его значение должно изменяться при итерациях либо за счёт операторов тела цикла, либо при вычислениях. Пример бесконечного цикла с пустым оператором в теле_цикла:

 

do; while(1);

 

Оператор for

 

Оператор цикла с параметром имеет формат:

 

for (выражение-инициализатор;

Выражение-условие; выражение-модификатор)

Тело_цикла

 

Выражение-инициализатор – это выражение или опреде­ление объектов одного типа. Обычно здесь определяются и инициализируются некие параметры цикла. Определяемые пара­метры должны быть только одного типа, их область видимости – тело цикла. Если в качестве выражения-инициализатораисполь­зуется не определение, а выражение, то чаще всего его операнды разделены запятыми. Все выражения, входящие в выражение-инициализатор, вычисляются только один раз при входе в цикл. Выражение-инициализатор в цикле forвсегда отделяется "точкой с запятой" от выражения-условия, которое также завершается точкой с запятой. Даже при отсутствии выражения-инициализа­тора, выражения-условия и выражения-модификатора разделяю­щие их 2 символа "точка с запятой" всегда присутствуют.

 

Выражение-условие такое же, как и в циклах while и do. Если оно равно true (отлично от нуля), выполняются операторы тела_цикла. Если оно равно false (нулю), то выполнение цикла прекращается. В случае отсутствия выражения-условия следу­ющий за ним разделитель "точка с запятой" сохраняется и пред­полагается, что значение выражения-условия всегда истинно.

 

Выражение-модификатор часто представляет собой выражение (последовательность скалярных выражений, разделён­ных запятыми; запятая – это операция перечисления). Это выражение вычисляется на каждой итерации после выполнения операторов тела цикла и до следующей проверки выражения-условия. Его назвают завершающим выражением цикла.

 

Тело_цикла может быть блоком, отдельным оператором, составным оператором и пустым оператором. Определённые в выражении-инициализаторе цикла объекты существуют только в заголовке и в теле цикла. Если результаты выполнения цикла нужны после его окончания, то их нужно сохранять во внешних относительно цикла объектах.

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

 

// Листинг 5.1. Разные формы цикла for

#include <iostream>

using namespace std;

int main() {

int k = 3, s = 0, i = 1;

for (; i <= k; ++i)

s += i*i; // Первый цикл

cout << "s(3) = " << s << endl;

 

s = 0; //Восстанавливаем начальное значение s

for (int i = 0, k = 4; i < k;)

s += ++i*i; // Второй цикл

cout << "s(4) = " << s << endl;

 

for (i = 1, s = 0, k = 5; i <= k; s += i*i, ++i)

; // Третий цикл

cout << "s(5) = " << s << endl;

return 0;

}

 

Результат выполнения программы:

s(3) = 14

s(4) = 30

s(5) = 55

 

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

Последовательность выполнения цикла for следующая. Определяются и инициализируются объекты или вычисляется выражение из выражения-инициализатора. Вычисляется значение выражения-условия. Если оно равно true (отлично от нуля), выполняются операторы тела_цикла. Затем вычисляется выражение-модификатор, вновь вычисляется выражение-условие и проверяется его значение. Далее цепочка действий повторяется.

При выполнении цикла for выражение-условие может изменяться либо при вычислении его значений, либо под действием операторов тела цикла, либо под действием за­вершающего выражения. Если выражение-условие не изменяется либо отсутствует, то цикл бесконечен. Следующие операторы обеспечивают бесконечное выполнение циклов:

 

for (;;);//Бесконечный цикл, тело – пустой оператор

for (;0.5;) cout << "Hello!\n"; // Бесконечный цикл

 

Разрешено и широко используется вложение любых циклов в любые циклы.

 

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

 

Оператор break

 

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

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

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

 

{ // операторы

if (условие) break;

// операторы

}

 

Циклы и операторы-переключатели могут быть многократно вложенными. Однако следует помнить, что оператор break позволяет выйти только из самого внутреннего цикла или переключателя в область, его объемлющую. При многократном вложении циклов и переключателей оператор break не может организовать передачу управления из самого внутреннего уровня непосредственно на самый внешний.

 

Рассмотрим программу, в которой вычисляется произведение чисел последовательности 2, 7, 12,..., 152 до тех пор, пока произведение не станет больше 200.

 

// Листинг 5.2

#include <iostream>

using namespace std;

 

int main() {

int p = 1, mn = 2;

 

while (mn <= 152) {

p *= mn;

 

// Выход из цикла, если произведение

if (p > 200) break; // стало больше 200

 

cout << p << endl;

mn += 5;

}

 

cout << "p = " << p << endl;

return 0;

}

 

Результат выполнения программы:

p = 2856

 

Оператор continue

 

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

 

Рассмотрим программу, вычисляющую сумму натуральных чисел, не больших 150, которые делятся нацело на 17 и на 4.

 

// Листинг 5.3

#include <iostream>

using namespace std;

 

int main() {

int sum = 0, i = 0;

 

do {

i += 17;

// Если очередное слагаемое не делится

// на 4,переходим к следующей итерации

if (i%4!= 0) continue;

sum += i;

} while (i <= 150);

 

cout << "sum = " << sum << endl;

return 0;

}

 

Результат выполнения программы:

sum = 204

 

 

Рассмотрим задачу вычисления при значении x с точностью ε значения функции ch(x) (гиперболический косинус) с помощью бесконечного ряда Тейлора по формуле:

и при этом же значении x вычислить гиперболический косинус с помощью функции cosh(x) из стандартной библиотеки.

Решение:

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

Для уменьшения количества выполняемых действий следует воспользоваться рекуррентной формулой получения последующего члена ряда через предыдущий Cn +1 = T*Cn, где T – некоторый множитель. Подставив в эту формулу Cn и Cn +1, получим выражение для вычисления T:

Рассмотрим программу для решения данной задачи.

//Листинг 5.4

#include<iostream>

#include<cmath>

using namespace std;

int main() {

//Установка поддержки русского языка

//в Visual Studio

setlocale(LC_CTYPE,"Russian");

//именованная константа

const int MAXITER = 500;

double x, eps;

int n;

// признак достижения точности

bool done = true;

// первый член ряда и нач. значение суммы

double ch = 1, y = ch;

// ввод с клавиатуры значения x

cout<<"x= ";

cin>>x;

// ввод с клавиатуры значения eps

cout<<"eps= ";

cin>>eps;

for (n = 0; fabs(ch) > eps; n++)

{

// очередной член ряда

ch *= x*x/(2*n+1)/(2*n+2);

// добавление члена ряда к сумме

y += ch;

if (n > MAXITER)

{

cout<<"Ряд расходится\n";

done = false; break;

}

}

if (done)

{

cout<<"Результаты:\n";

//вывод вычислений

cout<<"x = "<<'\t'<<"y = "<<y<<'\t'

<<"n = "<<n

<<'\t'<<"Ch = "<<cosh(x)<<'\n';

}

return 0;

}

 

Задание. Создать программу на языке С++ для вычисления с точностью ε и вывода на экран в виде таблицы значений функции, заданной с помощью ряда Тейлора, на интервале от x нач до x кон c шагом dx. Таблицу снабдить заголовком и шапкой. Каждая строка таблицы должна содержать значение аргумента x, значение функции (вычисленное как сумма членов ряда), количество просуммированных членов ряда для обеспечения заданной точности, значение функции (вычисленное с помощью вызова функции стандартной библиотеки).

Вариант 1

Вариант 2

Вариант 3

Вариант 4

Вариант 5

Вариант 6

Вариант 7

Вариант 8

Вариант 9

Вариант 10

Вариант 11

Вариант 12

Вариант 13

Вариант 14

Вариант 15

;

(Ареа-тангенс )

Вариант 16

Вариант 17

 

Вариант 18

(Ареа-котангенс )

 

Вариант 19

 

Вариант 20

 

Практическое занятие 6. Указатели. Одномерные массивы в языке С++

 

Указатели

 

Указатель – это переменная, в которой хранится адрес другого объекта (другой переменной или начало области памяти).

Значениями указателей служат адреса участков памяти, выделенных для объектов конкретных типов. Указатели делятся на три категории – указатели на объекты, указатели на void и указатели на функции. Выделение этих категорий связано с отличиями в свойствах и правилах использования указателей. Указатели на функции будут рассмотрены позже. Рассмотрим указатели на объекты.

Простейшее объявление указателя на объект имеет вид:

 

тип_указателя * имя_указателя;

 

где тип_указателя – обозначение типа, символ «*» в этом контексте используется для объявления переменной-указателя на объект указанного типа, имя_указателя – идентификатор. Тип указателя может быть любым, кроме ссылки и битового поля, причём тип может быть к этому моменту только объявлен, но еще не определён (в структуре, например, может присутствовать указатель на структуру того же типа).

Для того чтобы определить несколько указателей на объекты одного и того же типа, символ * помещают перед каждым именем. Например, определение

 

int *p1, *p2, k;

 

вводит два указателя на объекты целого типа с именами p1, p2 и переменную k целого типа.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: