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

C _Учебник_МОНУ

.pdf
Скачиваний:
199
Добавлен:
12.05.2015
Размер:
11.12 Mб
Скачать

 

Програмування базових алгоритмів

139

int kol = 0; // кількості правильних відповідей,

 

int i;

// лічильнику циклів

 

time_t t;

// поточного часу – для ініціалізації генератора випадкових чисел.

printf("*** Перевірка знань таблиці множення ***\n");

 

printf("Введіть відповідь і натисніть <Enter>\n");

 

srand((unsigned) time(&t));

// Ініціалізація генератора випадкових чисел

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

// 10 тестів

{ numbl = rand()%7 +

2

;

// Два випадкових числа

numb2 = rand()%7 +

2

;

// у межах від 2 до 9

res = numbl * numb2;

printf("%i x %i=", numbl, numb2); scanf("%i",&otv);

if(otv == res)kol++;

else printf("Ви помилились! %i x %i = %i \n

Спробуйте ще раз\n", numbl, numb2, res);

}

printf("\nПравильних відповідей: %i\n", kol); printf("Ваша оцінка: ");

switch (kol)

{case 10: puts("Відмінно"); break; case 9: puts("Добре"); break; case 8: puts("Добре"); break;

case 7: puts("Задовільно"); break; default: puts("Погано"); break;

}

printf("\nДля завершення натисніть <Enter>"); getch();

return 0;

}

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

*** Перевірка знань таблиці множення ***

Введіть відповідь і натисніть <Enter> 8 х 4 = 32 3 х 2 = 6 5 х 7 = 35 9 х 6 = 56

Ви помилились! 9 x 6 = 54 Спробуйте ще раз

6 х 7 = 42

9 х 3 = 27

8 х 8 = 64

4 х 3 = 12

2 х 6 = 12

7 х 8 = 56

Правильних відповідей: 9 Ваша оцінка: Добре

Для завершення натисніть <Enter>");

140

Розділ 4

4.4.3 Вкладені цикли

Цикли може бути вкладено один в одного. При використанні вкладених циклів треба складати програму в такий спосіб, щоб внутрішній цикл повністю вкладався в тіло зовнішнього циклу, тобто цикли не повинні перетинатися. Своєю чергою, внутрішній цикл може містити власні вкладені цикли. Імена параметрів зовнішнього та внутрішнього циклів мають бути різними. Припускаються такі конструкції:

for(k=1; k<=10; k++)

{. . .

for(i=1; i<=10; i++) { . . .

for(m=1; m<=10; m++)

{

...

}

 

}

 

}

Приклади проектів програм із вкладеними циклами

m

i

i 1 k 3

 

Приклад 4.44 Обчислити S

 

 

 

 

, зна-

 

 

 

i 1 i 2 k 1

k

 

чення m ввести з екрана. З обчислень вилучити доданки та множники, які дорівнюють нулю в чисельнику чи то знаменнику.

Розв‟язок. В цьому прикладі програми наведені цикли є вкладеними один в одного, оскільки параметр внутрішнього циклу k залежить від параметра зовнішнього циклу і (k змінюється від 1 до і). Добуток

k 3 є співмножником доданка і обчислюється у

kk 1i 1

внутрішньому циклі у змінній P. Оскільки внутрішній цикл складається лише з одного оператора, то операторні дужки { } не є обов‟язковими.

Перед зовнішнім циклом для обчислення суми слід обнулити змінну S, в якій будуть накопичуватись доданки, а перед зовнішнім циклом для обчислення добутку змінній p слід присвоїти значення 1.

Оскільки при обчислюванні добутку беруть участь лише цілі числа, то, щоб при діленні не втратити дробову частину, слід перетворити чисельник до дійсного типу; для цього можна дописати крапку до числа 3: (k+3.)/k.

 

Початок

 

m

 

s = 0

 

i 1, m

Ні

i≠2

 

 

Так

 

p = 1

 

k 1, i 1

 

p=p (k+3)/k

 

s=s+p i/(i – 2)

 

s

 

Кінець

2x2i 1

Програмування базових алгоритмів

141

Текст програми для кнопки “Розв‟язок”:

void __fastcall TForm1::Button1Click(TObject *Sender)

{int i, k, m = StrToInt(Edit1->Text); float S = 0, p;

for(i = 1; i <= m; i++) if( i != 2)

{p = 1;

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

p*=(k+3.)/k;

S += i/(i-2.) * p;

}

Edit2->Text = FloatToStr(S);

}

7

Приклад 4.45 Обчислити суму ряду S , де i = 1, 2, …, 7.

i 1 3(2i 1)!

Розв’язок. Для обчислення суми S треба підсумувати сім доданків, для обчислення кожного з яких слід сформувати вкладений цикл для підрахунку факторіалів (2i 1)!. У даній програмі кожний доданок обчислюється в окремій

змінній а.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender)

{int i, k, fact;

float s=0, a, x=StrToFloat(Edit1->Text); for(i=1; i<=7; i++)

{fact=1;

for(k=1; k<=2*i–1; k++) fact *= k;

a = 2*pow(x,2*i–1)/(3*fact);

s += a;

}

Edit2->Text = FloatToStrF(s, ffGeneral, 4, 3);

}

Приклади консольних програм із вкладеними циклами

Приклад 4.46 Написати програму, котра генерує три послідовності з десяти випадкових чисел в діапазоні від 1 до 10, виводить на екран і обчислює середнє арифметичне кожної послідовності.

Текст програми:

// Обчислення середнього арифметичного послідовностей випадкових чисел

#include <vcl.h> #include <stdio.h> #include <conio.h> #include <time.h>

// Для послідовності з 10-ти чисел // генерується випадкове число // і виводиться його значення

142

Розділ 4

#pragma argsused //------------------------------------------------------------

int main(int argc, char* argv[])

{int

r;

// Випадкове число

int sum;

// Сума чисел послідовності

float sr;

// Середнє арифметичне

int i,j;

// Лічильники циклів

time_t t;

// Поточний час – для ініціалізації генератора випадкових чисел

// Ініціалізація генератора випадкових чисел (див. докладніше підрозд. 3.7) srand((unsigned) time(&t));

for(i = 1; i <= 3; i++) // Організуються три послідовності

{printf("\n Випадкові числа: "); sum =0;

for(j = 1; j <= 10; j++) { r = rand() % 10 +1 ; printf ("%i ", r) ;

sum += r;

}

sr = (float)sum / 10;

printf("\n Середнє арифметичне: %3.2f\n", sr);

}

printf("\n Для завершення натисніть <Enter>"); getch(); return 0;

}

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

Випадкові числа: 6 4 5 2 4 5 6 5 1 8 Середнє арифметичне: 4.60

Випадкові числа: 8 9 8 3 6 6 8 7 6 6 Середнє арифметичне: 6.70

Випадкові числа: 10 3 8 4 7 4 7 5 2 2 Середнє арифметичне: 5.20

Для завершення натисніть <Enter>

Приклад 4.47 Вивести на екран квадрат Піфагора – таблицю множення.

Текст основної програми:

#include <vcl.h> #pragma hdrstop #include <conio.h> #include <iostream.h> #pragma argsused

//------------------------------------------------------------

int main(int argc, char* argv[])

{ int i,j; // Номер рядка і стовпчика таблиці

printf("\n Квадрат Піфагора - таблиця множення \n\n"); for(j=1; j<=10; j++) printf("%4i", j);

// Екран буде очищено

Програмування базових алгоритмів

143

printf("\n \n"); for(i=1; i<=10; i++)

{ printf("%4i ", i);

for(j=1; j<=10; j++) printf("%4i", i*j); printf("\n");

}

printf("\n Для завершення натисніть <Enter>\n"); getch(); return 0;

}

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

Квадрат Піфагора – таблиця множення

 

1

2

3

4

5

6

7

8

9

10

1

1

2

3

4

5

6

7

8

9

10

2

2

4

6

8

10

12

14

16

18

20

3

3

6

9

12

15

18

21

24

27

30

4

4

8

12

16

20

24

28

32

36

40

5

5

10

15

20

25

30

35

40

45

50

6

6

12

18

24

30

36

42

48

54

60

7

7

14

21

28

35

42

49

56

63

70

8

8

16

24

32

40

48

56

64

72

80

9

9

18

27

36

45

54

63

72

81

90

10

10

20

30

40

50

60

70

80

90

100

Для завершення натисніть <Enter>

Приклад 4.48 Увести цілі числа m і n та вивести на екран:

**********

**********

**********

де m – кількість рядків “зірочок” і n – кількість “зірочок” у рядку.

Розв‟язок. Для розв‟язання поставленого завдання слід організувати два вкладені цикли: зовнішній – для організації виведення окремих m рядків, тобто переходу на новий рядок, і внутрішній – для безпосереднього виведення n “зірочок” у рядок.

Текст основної програми:

#include <conio.h> #include <iostream.h>

//------------------------------------------------------------

int main(int argc, char* argv[])

{int i, j, m, n;

cout << "Ввести кількість рядків m: "; cin >> m;

cout << "Ввести кількість рядків n: "; cin >> n;

clrscr();

144

Розділ 4

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

 

{ for(j=1;j<=n;j++) cout << "*";

// Виведення рядка з n “зірочок”

cout << endl;

// Перехід на новий рядок

}

 

getch(); return 0;

 

}

 

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

Ввести кількість рядків m: 2 Ввести кількість рядків n: 8

Приклад 4.49 Увести кількість рядків і вивести на екран трикутник “зірочок”:

*

**

***

****

. . .

Розв‟язок. Як і у попередньому прикладі, для виведення одного рядка слід сформувати окремий цикл, а для виведення кількох таких рядків необхідно вкласти перший цикл у цикл, який буде формувати перехід до наступного рядка. У першому рядку має бути лише одна “зірочка”, у другому – дві, у третьому

– три і т. д. Тобто рядок з номером і має складатися з і “зірочок”, тому внутрішній цикл виконуватиметься і разів.

Текст програми:

#include <conio.h> #include <iostream.h>

//------------------------------------------------------------

int main(int argc, char* argv[])

{int i, j, m;

cout << "Ввести кількість рядків m: "; cin >> m;

clrscr();

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

{for(j=1; j<=i; j++) cout << "*"; cout << endl;

}

getch(); return 0;

}

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

Ввести кількість рядків m: 5

Умова?
Ні
Оператори

Програмування базових алгоритмів

145

4.4.4Оператори циклу з передумовою while та післяумовою do-while

Оператори з передумовою та післяумовою використовуються для організації циклів і є альтернативними операторові for. Зазвичай цикл з передумовою використовується, якщо кількість повторювань заздалегідь є невідома або немає явно вираженого кроку змінювання параметра циклу. А для багаторазових повторювань тіла циклу відомим є вираз умови, за істинності якої цикл продовжує виконання. Цю умову слід перевіряти кожного разу перед черговим повторенням. Приміром, при зчитуванні даних з файла умовою є наявність цих даних у файлі, тобто повторювати читання даних слід аж допоки вказівник не добудеться кінця файла (докладніше див. розд. 12).

Синтаксис циклу з передумовою:

while (<умова>)

 

 

{ <тіло циклу> };

 

 

Послідовність операторів (тіло циклу) виконуєть-

 

Ні

ся, допоки умова є істинна (true, має ненульове значен-

Умова?

 

ня), а вихід з циклу здійснюється, коли умова стане хиб-

 

Так

 

ною (false, матиме нульове значення). Якщо умова є

 

Оператори

 

хибною при входженні до циклу, то послідовність опе-

 

 

 

раторів не виконуватиметься жодного разу, а керування

 

 

передаватиметься до наступного оператора програми.

 

 

Цикл з післяумовою використовується, якщо є потреба перевіряти умову

кожного разу після чергового повторення. Відмінність циклу з передумовою від

циклу з післяумовою полягає в першій ітерації: цикл з післяумовою завжди ви-

конується принаймні одноразово незалежно від умови.

 

 

Синтаксис циклу з післяумовою:

 

 

do {

<тіло циклу>

} while (<умова>);

Послідовність операторів (тіло циклу) виконуєть-

ся один чи кілька разів, допоки умова стане хибною

(false чи дорівнюватиме нулю). Якщо умова є істинна (ненульова), то оператори тіла циклу виконуються поТак вторно. Оператор циклу do-while використовується в

тих випадках, коли є потреба виконати тіло циклу хоча б одноразово, оскільки перевірка умови здійснюється після виконання операторів.

Якщо тіло циклу складається з одного оператора, то операторні дужки {} не є обов‟язкові.

Оператори while та do-while можуть завчасно завершитись при виконуванні операторів break (див. п. 4.4.5), goto (див. п. 4.3.2), return (вихід з поточної функції, див. підрозд. 8.1) усередині тіла циклу.

146

Розділ 4

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

Розглянемо відмінність роботи різних операторів циклу на прикладі обчислювання суми всіх непарних чисел у діапазоні від 10 до 100:

1) з використанням оператора for

int i, s=0;

for(i=11; i<100; i += 2) s += i;

2) з використанням оператора while

int s=0, i=11;

while(i<100) { s += i; i += 2; }

3) з використанням оператора do-while

int s=0, i=11;

do { s += i; i += 2;} while(i<100);

Приклади програм із застосуванням циклів while та do-while

 

 

x2k 1

Приклад 4.50

Обчислити суму ряду S

 

, підсумовуючи чле-

(2k 1)!

 

k 1

 

 

ни ряду, значення яких за модулем перевищують задану точність 10 4. Визначити кількість доданків. Значення х (– 2 < x < 2) вводити з клавіатури.

Розв‟язок. Для цього завдання в програмі недоцільно використовувати оператор циклу з параметром for, оскільки кількість повторювань попередньо є невідома. Доцільним буде використання оператора циклу з післяумовою do-while, оскільки на момент першої перевірки умови вже треба знати значення першого доданка.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float x, a, s=0;

// Оголошення змінних і встановлення

int f, i, k=0;

// їхніх початкових значень

x=StrToFloat(Edit1->Text);

// Введення значення х

do

// Цикл з післяумовою

{ k++;

// Збільшення змінної k на 1

for(i=1,f=1; i<=2*k-1; i++) f *= i; // Обчислення факторіала

a=pow(x, 2*k+1)/ f;

// Обчислення k-го доданка

s+=a;

// Підсумовування доданків

}

 

while(fabs(a)>=1e-4);

 

Edit2->Text=FloatToStr(s) ;

// Виведення обчисленої суми

Edit3->Text=IntToStr(k);

// та кількості доданків

}

 

 

Програмування базових алгоритмів

 

 

 

147

 

5

( 1)

i

x

i 1

Приклад 4.51

Обчислити суму знакозмінного ряду S

 

 

трьома

i!

 

 

i 1

 

 

 

 

 

 

 

 

варіантами, використовуючи різні оператори циклу.

Розв‟язок. Тут (–1)i+1 за непарних значень i (1, 3, 5, …) дорівнює 1, а за парних значень i (2, 4, 6, …) – (–1), тобто розглядається знакозмінний ряд, де всі парні доданки будуть від‟ємними, а всі непарні – зі знаком “+”.

Схеми алгоритмів усіх трьох програм наведено нижче.

 

Початок

 

 

Початок

 

 

 

 

 

 

 

Початок

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

S = 0, i=1

 

 

 

 

 

 

 

 

 

 

S = 0

 

 

 

 

 

 

 

 

 

 

 

 

 

S = 0, i=1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Введення

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Введення

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Введення

 

 

 

 

 

 

 

 

 

 

 

 

 

х

 

 

 

 

 

 

 

 

 

 

 

 

х

 

 

 

 

 

 

 

 

 

 

 

 

 

х

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i <= 5

 

 

 

Ні

 

 

 

 

 

 

i = 1, 5

 

 

 

 

 

 

 

 

f=1, k=1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Так

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

f = 1, k=1

 

 

 

 

 

 

 

 

 

 

f = 1

 

 

 

 

 

 

 

 

 

 

 

 

 

f=f*k, k=k+1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ні

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

k <= i

 

 

 

Так

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

k = 1, i

 

 

 

 

 

 

Так

 

 

 

 

 

 

 

 

 

 

 

 

 

k <= i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

f=f*k, k=k+1

 

 

 

 

 

 

Ні

 

f = f * k

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

S=S+(–1) i xi+1/f

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

S=S+(–1)

i

x

i+1

/f

 

 

 

 

 

 

i = i + 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

S=S+(–1) i xi+1/f

 

 

 

 

 

 

 

 

 

 

 

 

 

Так

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i = i + 1

 

 

 

 

 

i <= 5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Виведення

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ні

 

 

 

Виведення

 

 

 

Виведення

 

S

 

 

 

 

 

 

 

 

 

S

 

 

 

 

 

 

 

 

 

 

S

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Кінець

 

 

Кінець

 

 

 

 

 

 

 

 

Кінець

 

a

 

 

 

б

 

 

 

 

 

 

 

 

 

 

в

Схеми алгоритмів програм з різними операторами циклу: a – for; б – while; в – do-while

Програма з використанням різних операторів циклу:

void __fastcall TForm1::Button1Click(TObject *Sender) // for

{ int i, f, k;

float S=0, x=StrToFloat(Edit1->Text);

for(i=1; i<=5;

i++)

{for(k=1, f=1; k<=i; k++) f *= k; S += pow(–1,i)*pow(x,i+1)/f;

}

Edit2->Text = FloatToStr(S);

}

//------------------------------------------------------------

148

Розділ 4

void __fastcall TForm1::Button2Click(TObject *Sender) // while

{int i=1, f, k;

float S=0, x=StrToFloat(Edit1->Text); while(i<=5)

{f=1; k=1;

while(k<=i) { f *= k; k++; }

S += pow(–1, i) * pow(x, i+1) / f;

i++;

}

Edit3->Text = FloatToStr(S);

}

//------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender) // do-while

{int i=1, f, k;

float S=0, x=StrToFloat(Edit1->Text); do

{f=1; k=1; do

{f *= k;

k++;

}

while(k <= i);

S += pow(–1, i) * pow(x, i+1) / f; i++;

}

while(i <= 5);

Edit4->Text = FloatToStr(S);

}

 

 

1

x

 

 

 

k

 

2k

Приклад 4.52

Обчислити суму ряду y

 

, підсумовуючи

2k(2k 1)!

 

k 1

 

 

 

 

члени ряду, значення яких за модулем є більшими за задану точність . Визначити кількість доданків. Значення х (– 2 < x < 2) та 10 4 вводити з клавіатури.

Розв‟язок. Наведемо два способи розв‟язання цього завдання. Для наочності й контролю правильності окремо виведемо усі доданки.

П е р ш и й с п о с і б р о з в ‟ я з а н н я

#include <math.h>

void __fastcall TForm1::Button1Click(TObject *Sender) {Memo1->Clear();

float x, y = 0, u, eps;

x = StrToFloat(Edit1->Text); eps = StrToFloat(Edit2->Text); int i, f, k = 1;

do

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