Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab_6

.pdf
Скачиваний:
10
Добавлен:
27.05.2015
Размер:
2.38 Mб
Скачать

1Лабораторная работа №6

Итерационные алгоритмы. Циклы

Очень часто программисту при решении задач приходится многократно вычислять значения по одним и тем же математическим зависимостям для различных значений входящих в них величин. Особенно часто такая необходимость возникает при решении математических задач методами последовательных приближений, получивших широкое распространение благодаря своей простоте и удобству их реализации на компьютерах. Такие многократно повторяемые участки вычислительного процесса называются циклами. В языке Си заложены широкие возможности организации циклов. Рассмотрим некоторые из этих возможностей на примере решения следующей несложной задачи. Необходимо вычислить квадратный корень из положительного числа x . Воспользуемся для этого формулой, исполь-

зовавшейся еще древним математиком Героном. Если известно начальное p

приближение x0 к X , то каждое последующее приближение находится по формуле

 

X + x2

 

xi+1 =

i

где i = 0; 1; 2; :::

(1)

 

 

2xi

 

Вычисления прекращаются, как только будет достигнута необходимая точность " , т.е. как только будет выполнено неравенство jxi+1 xij < " . Как видим, задача свелась к многократным вычислениям по одной и той же формуле (1). Приведенный алгоритм нахождения квадратного корня можно представить в виде блок-схемы, изображенной на рисунке 1. Язык Си дает программисту несколько возможностей для реализации на нем подобных алгоритмов. Рассмотрим их подробно.

Рис. 1 Блок-схема для вычисления квадратного корня по формуле Герона

1.1Организация итерационного цикла с помощью оператора while

Этот оператор имеет следующий синтаксис: while (выражение) оператор;

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

Пример 1

#include "stdafx.h" #include <stdio.h>

4

#include <conio.h> #include <math.h>

/* Программа нахождения квадратного корня. Вариант 1*/ void main()

{float X=3.0, x0, x, eps;

printf("\n Введите начальное приближение\n"); scanf("%f", &x);

printf("\n Введите погрешность вычисления\n"); scanf("%f", &eps);

while(fabs(x-x0)>eps)

{ x0=x; x=(X+x0*x0)/(2.0*x0);} printf("x=%f, x*x=%f\n", x, x*x); getch();

}

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

1.2Организация цикла с помощью оператора do-while

Данный оператор имеет следующий синтаксис: do {блок операторов}

while (выражение);

При использовании этого оператора программа Square Root примет следующий вид:

Пример 2

#include "stdafx.h"

#include <stdio.h>

#include <conio.h>

5

#include <math.h>

/* Программа нахождения квадратного корня. Вариант 2*/ void main()

{float X=3.0, x0, x, eps;

printf("\n Введите начальное приближение\n"); scanf("%f", &x);

printf("\n Введите погрешность вычисления\n"); scanf("%f", &eps);

do { x0=x; x=(X+x0*x0)/(2.0*x0);} while(fabs(x-x0)>eps);

printf("x=%f, x*x=%f\n", x, x*x); getch();

}

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

Пример 3

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

/* Программа нахождения квадратного корня. Вариант 3*/ void main()

{float X=3.0, x0, x, eps; int n=0;

printf("\n Введите начальное приближение\n"); scanf("%f", &x);

6

printf("\n Введите погрешность вычисления\n"); scanf("%f", &eps);

do { x0=x; x=(X+x0*x0)/(2.0*x0); n++; if(n>100) printf("\n n>100\n"); goto a;}

while(fabs(x-x0)>eps); printf("x=%f, x*x=%f\n", x, x*x);

a: getch();

}

Обратите внимание, что если прерывание выполнения цикла с передачей управления на внешний оператор (как мы это делали в примере 3) возможно, то обратная процедура запрещена, т.е. запрещается передавать управление программой в тело цикла извне. Приведем еще одну программу, позволяющую вычислять значение sin x для малых с заданной точностью " > 0 по формуле

sin x = x

 

x3

+

x3

 

=

1

( 1)2n+1x2n+1

 

3!

5!

Xn

(2)

 

 

 

 

 

 

=0

(2n + 1)!

 

 

 

 

 

 

 

 

 

Пример 4

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

/* Программа для вычисления sin(x).*/ void main()

{float x, a, eps, sum=0; int n=1;

printf("\n Введите начальное приближение\n"); scanf("%f", &x);

printf("\n Введите погрешность вычисления\n"); scanf("%f", &eps);

7

a=x;

do { sum+=a; n+=2; a*=(-x*x)/(n-1)/n;} // вычисление a_n while(fabs(a)>eps);

printf("sin(%f)=%f\n", x, sum); getch();

}

1.3Циклические структуры с заданным числом повторений. Вложенные циклы

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

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

ит.д. Для организации цикла с заданным числом повторений удобно использовать оператор for, синтаксис которого имеет следующий формат:

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

оператор или группа операторов;

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

Схема выполнения оператора for:

1)производится инициализация переменной цикла;

2)вычисляется условное выражение;

3)если значение условного выражения истинно, выполняется оператор;

8

4)вычисляется выражение итерации, т.е. происходит изменение переменной цикла;

5)вновь вычисляется условное выражение;

6)как только условное выражение становится неверным, управление передается на оператор, следующий за оператором for.

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

Пример 5

Вычислить сумму членов ряда

 

x

x2

 

x19

19

xk

z = 1 +

 

+

 

+ : : : +

 

=

Xk

 

 

 

 

 

k

1

2

19

 

=0

 

 

 

 

 

 

 

 

 

 

Для вычисления члена ряда целесообразно использовать рекуррент-

ную формулу yi = yi 1 x i=(i + 1) , причем сумму слагаемых необходимо вычислять путем прибавления полученного слагаемого к сумме предыдущих. Формула, используемая для накопления суммы, имеет вид: si = si 1 + yi . В первом выполнении s1 = 1 + y1 , y = x . Далее в цикле вычисляем si , yi через si 1 и yi 1 для i = 2; : : : ; 19 .

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

#define N=19 /* Число слагаемых */ void main()

{float s=1.0, x; int i=0;

9

printf("\n Input x\n");

scanf("%f", &x);

y=x;

for(i=1;i<=N;i++)

{ s+=y; printf("x=%f \t", y); y=y*x*i/(i+1); }

printf("\n sum=%f \t", s);

getch();

}

Пример 6

Программа вычисления двойной суммы

100

50

1

XX

(i2 + j)

i=1 j=1

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

#define N=100 /* Число слагаемых */ #define M=50 /* Число слагаемых */ void main()

{float s=1.0, x; int i,j;

printf("\n Программа вычисления двойной суммы\n"); for(i=1;i<=N;i++)

{for(i=1;i<=N;i++)

{ x=(i*i+j); x=1.0/x; s+=x; }

}

printf("\n sum=%f \t", s); getch();

}

Пример 7

10

Вычисление факториала целого числа. Согласно

определению

n! = 1 2 3 4 : : : = Qkn=1 k , причем полагается, что 0!

= 1 .

/* Программа вычисления факториала */ #include "stdafx.h"

#include <stdio.h> #include <conio.h> #include <math.h> void main()

{int p=1, i, n=0; for(i=1;i<=N;i++)

p*=i;

printf("\n %d!=%d", n, p); getch();

}

1.4Задания к лабораторной работе

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

A 1. Вычислить и вывести на экран в виде таблицы значения функции

f(x)

на интервале от xнач до xконеч с шагом dx

 

 

 

 

 

 

 

 

 

 

 

 

 

8

 

x

+a

 

при

 

0 и

 

6= 0

 

 

 

 

 

 

 

 

 

 

 

 

 

>

ax2

 

 

b;

 

x <

 

b

 

;

 

 

 

 

 

 

 

 

 

 

 

f =

 

x

 

b

; при x > 0 и b = 0 ;

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<

 

 

x

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>

 

 

c

;

 

 

в остальных случаях

 

 

 

 

где

a

,

b

,

c

действительные>

числа. Значения a , b , c , x

нач

, x

конеч

,

 

 

 

 

:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

dx ввести с клавиатуры.

2. Вычислить и вывести на экран в виде таблицы значения функции

11

f(x) на интервале от xнач до xконеч с шагом dx

 

 

8

 

x

+a

при

 

0 и

 

6= 0

 

 

>

ax2

b;

 

x <

 

b

 

;

f =

 

x

 

;

при x > 0 и b = 0 ;

 

>

 

 

b

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

<

 

 

x

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

>

 

 

c ;

 

в остальных случаях

 

>

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

:

где a , b , c – действительные числа. Значения a , b , c , xнач , xконеч ,

dx ввести с клавиатуры.

3. Вычислить и вывести на экран в виде таблицы значения функции

f(x) на интервале от xнач до xконеч с шагом dx

 

8

cx

a;

при x < 0 и b 6= 0 ;

 

>

 

2x

 

c

 

f =

 

 

x

a

 

 

 

 

 

 

;

при x > 0 и b = 0 ;

 

>

 

 

 

 

>

 

 

x

 

c

 

 

>

 

 

 

 

 

>

 

 

 

 

 

 

 

 

<

 

 

 

 

 

 

 

 

>

x c

 

 

 

 

>

 

 

 

 

 

 

 

 

>

c 2x;

 

 

в остальных случаях

 

>

 

 

 

>

 

 

 

 

 

 

 

:

где a , b , c – действительные числа. Значения a , b , c , xнач , xконеч ,

dx ввести с клавиатуры.

4. Вычислить и вывести на экран в виде таблицы значения функции

f(x) на интервале от xнач до xконеч с шагом dx

 

8

ax3

x

 

a

при

 

и

6

f =

>

 

+ bx2;

 

x < 0

 

b = 0 ;

 

 

 

;

при x > 0 и b = 0 ;

 

>

 

 

x

 

c

 

 

 

 

 

>

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

<

x + 5

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

 

>

 

10);

 

 

в остальных случаях

 

> c(x

 

 

 

>

 

 

 

 

 

 

 

 

 

 

>

:

где a , b , c – действительные числа. Значения a , b , c , xнач , xконеч ,

dx ввести с клавиатуры.

5. Вычислить и вывести на экран в виде таблицы значения функции

f(x) на интервале от xнач до xконеч с шагом dx

 

8

(

 

+

x a

при

 

и

6

 

>

a

x

 

c)2

b;

 

x < 0

 

b = 0 ;

f =

 

 

 

 

;

при x > 0 и b = 0 ;

 

>

 

 

 

c

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

<

 

 

 

x

 

 

 

 

 

 

>

 

 

 

 

 

 

 

 

 

 

>

 

 

a + c ;

 

в остальных случаях

 

>

 

 

 

 

>

 

 

 

 

 

 

 

 

 

:

12

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