Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodichka_PZ.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.66 Mб
Скачать

Общие сведения

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

Пусть необходимо протабулировать функ­цию F(x) на интервале [a,b] c шагом h (где, F(x)=xsin(x), a<b, h>0) и вывести получен­ные значения функции и аргумента.

Протабулировать функцию - значит вы­числить значения функции -F(х) на отрезке [a, b] в точках а, a + h, a + 2h и т.д.

Графическая схема алгоритма приведена на рис.12, программа – в примере pr13.

// Пример pr13

#include <stdio.h>

#include <conio.h>

#include <math.h>

void main()

{ float x,y,a,b,h;

printf("\nBведите a,b,h:");

scanf("%f %f %f,&a,&b,&h);

x=a;

43

do

{

y=x*sin(x);

printf("\nx=%7.2f, y=%7.2f ",x,y);

x=x+h; // К "старому" значению х добавляется h

// и результат пересылается снова в х

} while (x ≤ b);

getch();

}

Рис. 12

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

Оператор цикла с постусловием

В

44

вышеприведенном примере был использован оператор цикла с посту­словием. Синтаксис этого оператора следующий:

do <оператор> while(<условие>)

Здесь do, while - ключевые слова (перев. с англ.: выполнять и пока);

<оператор> - любой оператор C++ в том числе и составной (его на­зывают телом цикла);

<условие>,- выражение типа сравнения, используемое для выхода из цикла. Оператор работает следующим образом: сначала выполняются, опера­торы, расположенные в теле цикла, затем вычисляется условие и, если полу­чается ложное значение, осуществляется выход из цикла. Если значение вы­ражения истинно, то выполнение операторов тела цикла повторяется, а за­тем снова проверяется условие. Итак, операторы тела цикла выполняются хо­тя бы раз, а потом все зависит от условия выхода из цикла. Очевидно, один из операторов тела цикла должен влиять на значение условного выраже­ния, поскольку иначе цикл будет повторяться бесконечно.

Проиллюстрируем использование оператора цикла с постусловием на примере, в котором выводятся нечетные числа, меньшие 10. Схема алго­ритма приведена на рис.13, программа в примере - рr14.

// Пример pr14

#include <stdio.h>

#include <conio.h>

void main()

{

int i;

i=l;

do

{

printf("\n%d",i);

i=i+2;

}

while (i<=10);

getch();

}

В результате работы этой программы будут напечатаны в столбик все нечетные числа от 1 до 9.

Оператор цикла с предусловием

В отличие от оператора цикла с постусловием оператор цикла с пре­дусловием вычисляет и проверяет условие до выполнения операторов, со­ставляющих тело цикла. Синтаксис этого оператора следующий:

while (<условие>) <оператор>;

Здесь while - ключевое слово (перев. с англ.: пока);

<

45

оператор> - любой оператор C++, в том числе и составной (этот оператор называют телом цикла);

Рис. 13

<условие> - выражение типа сравнения, используемое для выхода из цикла.

Оператор работает следующим образом: сначала вычисляется условие и, если получается истинное значение, выполняется оператор, являющийся те­лом цикла, а затем снова проверяется условие. Если значение условного выражения ложно, то осуществляется выход из цикла. Таким образом, если условие было ложно при первом входе в цикл, то операторы тела цикла не выполнятся ни разу. Очевидно, один из операторов тела цикла должен влиять на значение условного выражения, поскольку иначе цикл будет повторяться бесконечно. Например, следующий фрагмент программы будет печатать сообщение бесконечное число раз, так как отсутствуют в цикле конструкции, изменяющие величину i:

i=1;

while(i<5)

printf("Доброе утро!");

Чтобы получить работающий фрагмент программы, добавим в тело цик­ла оператор, увеличивающий значение i;

i=1;

while(i<5)

{ printf(" Доброе утро! ");

i=i+1;

46

} Проиллюстрируем использование оператора цикла с предусловием на примере рr15 нахождения среднего арифметического последовательности чисел (схема алгоритма приведена на рис. 14). Последовательность чисел вводится с клавиатуры и завершается стоп-кодом. Использование стоп-кода в данном случае состоит в том, что какое-то числовое значение заведомо ис­ключается из входной последовательности и используется как стоп-код. Если мы заранее знаем, что - 1 у нас никогда не появится в последовательности, то можно - 1 использовать для указания ее конца.

Рис. 14

// Пример pr15

#include <stdio.h>

#include <conio.h>

void main()

{

float number, //вводимое число

sum; //сумма вводимых чисел

int c; //количество вводимых чисел

const float stopcod=-1;

sum=0;

с=0;

pririif("Bведите первое число последовательности:");

scanf("%f,&number);

while (number!=stopcod)

{

47

sum=sum+number;

c=c+1;

printf("Bвeдитe следующее число последовательности:");

scanf("%f ",&number);

} if (c==0) printf("Среднее значение равно нулю");

else printf("Cpeднee значение равно = %f ",sum/c);

getch(); }

Необходимо отметить, что перед первым, вхождением в цикл while зна­чение number должно быть прочитано, иначе number'не будет определено при первой проверке условия while. Если первым вводимым числом оказался стоп-код, то тело цикла не выполнится ни cразу, счетчик с останется равным нулю, и чтобы не произошло деление на нуль, используется условный оператор.

Кроме того, в этой программе впервые появилась константа stopcod, в отличие от переменной она не может получить новое значение в программе.

Следующий пример иллюстрирует работу оператора цикла с предусло­вием на задаче, вычисляющей с точностью е сумму следующего ряда: s=1+1/2+1/3+1/4+ ... .

Вычислить сумму ряда с точностью е значит завершить суммирование членов ряда тогда, когда очередной член ряда окажется меньше е по аб­солютной величине. Схема алгоритма приведена на рис.15, программа – в примере pr16

// Пример рr16

#include <stdio.h>

#include <conio.h>

void main()

{ int i;

float е,// точность

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

sum; // суммаa ряда

sum=0;

i=1;

printf("Bведите точность:");

scanf("%f ",&e);

k=1/ i;

while (k>e) // пока очередной член ряда больше точности

{

sum=sum+k;

i=i+1;

k=1/ i;

}

48

printf("Сумма ряда =%f ", sum);

getch();

}

Рис. 15

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

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

for(<п.ц.>=<н.з.> ; <условие> ; <коррекция п.ц.>)

<

49

оператор>;

Здесь for - ключевое слово (перев. с англ, для);

<п.ц.> - переменная цикла, которая может быть только простого типа;

<н.з.> - начальное значение - выражение такого же простого типа, как и переменная цикла;

<условие> - выражение типа сравнения, используемое для выхода из цикла.

<коррекция п.ц.> - оператор присваивания, задающий изменение пе­ременной цикла;

<оператор> - любой оператор C++, в том числе и составной, являю­щийся телом цикла.

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

Если начальное значение переменной цикла больше конечного значения, то операторы тела цикла не выполняются. Можно сказать, что оператор цикла со счетчиком - это оператор цикла с предусловием. Таким образом, следующий оператор не приведет к выполнению каких-либо операций: for(i=l; i<0; i++) printf("i=%d \n",i);

Следующий оператор распечатает целые числа от 1 до 10:

for(i=l; i<10; i++) printf("i=%d\n",i);

Если нужно выполнить несколько операторов в теле цикла, то пользу­ются составным оператором:

for(i=5; i<= 10; i++)

{

k=i*i;

printf("k=%d\n",k);

}

Теперь следует подчеркнуть гибкость оператора цикла со счетчиком [3]:

Можно применять операцию уменьшения для счета в порядке убыва­ния

for(i=10; i>0; i--)

printf("%d ceкунд! \n",i);

printf("Пуск!\n");

Можно вести счет двойками, десятками и т. д.

for(i=5; i<100; i+=15) printf("i=%d\n",i);

В этом примере будут напечатаны 5,20,35,50,65,80,95.

Можно вести подсчет с помощью символов, а не только чисел

for(ch='a'; 'ch<'z'; ch++)

p

50

rintf("Величина кода ASCII для %с равна %d\n",ch,ch);

При выполнении этого оператора будут выведены все буквы от а до z вместе с их кодами ASCII. Символы в памяти размещаются в виде чисел, по­этому в данном фрагменте на самом деле счет ведется с использованием це­лых чисел.

Можно проверить выполнение некоторого произвольного условия, отличного от условия, налагаемого на число итераций

for(i=2; i*i*i<100; i++) printf("i*i*i=%d\n",i*i*i);

Можно сделать так, чтобы значение некоторой величины возрастало в геометрической, а не в арифметической прогрессии

for(debt=100.0; debt<150; debt=debt*1.1)

printf("Ваш долг теперь $%.2f\n",debt);

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

у=0;

for(x=1;y<=75;y=5 *x++ + 50)

printf("x=%d y=%d\n",x,y);

Результат будет выглядеть так:

х =1 у =0

х = 2 у = 55

х = 3 у = 60

х = 4 у = 65

х = 5 у = 70

х = 6 у = 75

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

Можно опустить любое из трех выражений в круглых скобках, но при этом нельзя пропустить точку с запятой. у=2; for(x=3;y<=25;) у=у*х;

При выполнении цикла х остается равной 3. Значение у вначале будет равно 2, потом увеличится до 6, 18, а затем будет получена окончательная величина 54. Можно опустить все три выражения в круглых скобках:

for(;;)

printf("Хочу учиться! \n");

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

Первое выражение не обязательно должно инициализировать пере­менную. Вместо этого, например, там мог бы стоять оператор printf().

for(printf("Bведите числа! \n");num==6;)

s

51

canf("%d",&num);

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

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

for(i=1, f=1; i<=10; f=f*i, i++);

В этом случае i=1, f=1 выполняется один раз, а f=f*i, i++ в каждой итерации цикла, пока i<=10.

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

Пример полной программы рассмотрим на решении задачи нахожде­ния суммы n первых членов ряда:

10 102 103

s = — + —— + ——— + ...

1 1*2. 1*2*3

Схема алгоритма приведена на рис. 16, а программа представлена в при­мере рr17.

// Пример рr 17

#include <stdio.h>

#include <conio.h>

void main()

{

int i,n;

float sum, // сумма ряда

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

sum=0;

printf("Bведите число членов ряда:");

scanf("%d",&n);

k=1;

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

{

k=k*10.0/ i;

sum=sum+k;

}

printf("Cyмма ряда =%f ",sum);

getch();

}

Г

52

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

Рис. 16

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

if(a[i]) k++;

else break;

В данном примере выход из цикла произойдет, когда i станет больше n или когда встретится нулевое a[i].

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

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

{

if(i%13) continue;

printf("i=%d\n",i);

53

} В этом примере будут выведены числа, кратные 13 и меньшие 1000.

Контрольные вопросы

1. Определить значение переменной s после выполнения следующих операторов:

float s=0;

int i=0;

while(i<5) i++; s+=1/ i;

2. Определить значение переменной s после выполнения следующих операторов:

float s=0;

int i=0;

while(i<5) { i++; s+=1./ i; }

3. Определить значение переменной s после выполнения следующих операторов:

float s=0;

int i=0;

do

{ i++; s+=1./ i; }

while(i<5)

4. Чем отличается оператор цикла с предусловием от оператора цикла с постусловием?

5. Какие возможности предоставляет оператор цикла со счетчиком?

6. Для чего используются в операторах цикла операторы break, con­tinue.

7. Можно ли изменять переменную цикла в операторе цикла со счетчиком с шагом 0.1?

8. Составьте фрагмент схемы алгоритма, соответствующий следующему фрагменту программы: for (i=0; i<n; i=i+2) k=k*i;

9. Какие ошибки допущены в следующем фрагменте программы:

for (i=0; i<n) {k=k*i; ; i=i+2}

10. Напишите программу, вычисляющую s = 1!+2!+...+n! (n>1).

Варианты заданий

1. Не используя стандартные функции (за исключением abs), вычислить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

2. Не используя стандартные функции (за исключением abs), вычислить сумму n первых членов следующего ряда (n вводится с клавиатуры):

54

.

3. Дано действительное число x. Не используя стандартные функции (за исключением abs),вычислить сумму следующего ряда с заданной точностью Е>0 (Е, х вводятся с клавиатуры):

.

4. Дано действительное число x. Не используя стандартные функции (за исключением abs), вычислить сумму n первых членов следующего ряда (n, x вводятся с клавиатуры):

.

5. Дано действительное число х. Не используя стандартные функции, вычислить сумму следующего ряда с заданной точностью Е>0 (Е, х вводят­ся с клавиатуры):

.

6. Дано действительное число х. Не используя стандартные функции (за исключением abs), вычислить сумму n первых членов следующего ряда (n, х вводятся с клавиатуры):

.

7. Дано действительное число x. Не используя стандартные функции (за исключением abs), вычислить сумму следующего ряда с заданной точностью Е>0 (Е, х вводятся с клавиатуры):

.

8. Дано действительное число х. Не используя стандартные функции (за исключением abs), вычислить сумму n первых членов следующего ряда (n, х вводятся с клавиатуры):

.

9. Не используя стандартные функции (за исключением abs), вычислить сумму n первых членов следующего ряда (n вводится с клавиатуры):

.

10. Дано натуральное число n и действительное числo а. Вычислить n первых членов следующего ряда (n, а вводятся с клавиатуры):

.

11. Дано действительное число a. Вычислить сумму следующего ряда с заданной точностью Е > 0 (Е, а вводятся с клавиатуры):

55

.

12. Не используя стандартные функции (за исключением abs), вычислить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

13. Не используя стандартные функции (за исключением abs), вычис­лить сумму n первых членов следующего ряда (n вводится с клавиатуры):

.

14. Не используя стандартные функции (за исключением abs), вычис­лить сумму следующего ряда с заданной точностью Е>0 (Е вводится с кла­виатуры):

.

15. Не используя стандартные функции (за исключением abs), вычис­лить сумму n первых членов следующего ряда (n вводится c клавиатуры):

.

16. Не используя стандартные функции (за исключением abs), вычис­лить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

17. Не используя стандартные функции (за исключением abs), вычис­лить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

18. Вычислить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

19. Не используя стандартные функции (за исключением abs), вычислить сумму следующего ряда с заданной точностью Е > 0 (Е вводится с клавиатуры):

.

20. Не используя стандартные функции (за исключением abs), вычислить сумму следующего ряда с заданной точностью Е > 0 (E вводится с клавиaтуры):

56

.

21. Дано действительное число х. Не используя стандартные функции (за исключением abs и sin), вычислить сумму следующего ряда с заданной точностью Е > 0 (Е, х вводятся с клавиатуры):

.

22. Дано действительное число х. Не используя стандартные функции (за исключением abs и sin), вычислить сумму n первых слагаемых следующего ряда (х вводится с клавиатуры):

.

23. Дано действительное число х. Не используя стандартные функции (за исключением abs и cos), вычислить сумму следующего ряда с заданной точностью Е > 0 (Е, х вводятся с клавиатуры):

.

24. Дано действительное число х. Не используя стандартные функции (за исключением abs и cos), вычислить сумму n первых слагаемых следую­щего ряда (х, n вводятся с клавиатуры):

.

25. Не используя стандартные функции, вычислить сумму n первых членов следующего ряда (n вводится с клавиатуры):

.

57

ЛАБОРАТОРНАЯ РАБОТА №4

ОБРАБОТКА ОДНОМЕРНЫХ МАССИВОВ

Цель работы:

ознакомиться с обработкой одномерных массивов с использованием индексов и с использованием указателей, операторами цикла;

Порядок выполнения работы:

В соответствии с поставленной задачей необходимо разработать графи­ческую схему алгоритма, составить два варианта программы (один с индек­сами, другой с указателями) и отладить их в среде C++, продемонстрировать преподавателю, как изменяются основные переменные в отладочном окне при выполнении программы по шагам, подготовить отчет, ответить на кон­ контрольные вопросы и защитить лабораторную работу перед преподавателем.

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