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

Зубенко, Омельчук - Програмування. Поглиблений курс

.pdf
Скачиваний:
58
Добавлен:
07.03.2016
Размер:
5 Мб
Скачать
☆

Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++

<структурний-цикл>::=for([<вираз1>];[<цілий-вираз2>];[<вираз3>])\ <оператор>

Кожний із виразів (і всі одночасно) може бути відсутнім. Відсут- ність другого виразу еквівалентна виразу 1.

Семантика задається складеним оператором:

{<вираз1>; while (<цілий-вираз2>) {<оператор> <вираз3>;}}

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

Приклад 3.30. Обчислення біфакторіала:

long bifactorial(unsigned int n) { unsigned long k,p;

p=k=(n%2==0? 2:1); while (k<n) {

k+=2; /*k=k+2; */ p*=k; /*p=p*k; */

}

return p;

}

long bifactorial2(unsigned int n)

{unsigned long k, p;

for (p=k=(n%2==0? 2:1); k<n; k+=2) p*=k; return p;

}

У циклі for змінна k буде змінюватися після змінної p ■ Приклад 3.31. Швидке піднесення до степеня (див. прикл. 2.31):

double qpow(double x, unsigned int n) {double p, a=x;

unsigned int q=n; if (n%2==0) p=1; else p=x;

while (q>0)

{

a=a*a;

q=q/2;

321

ПРОГРАМУВАННЯ

if (q%2==1) p=p*a;

}

return p;

}

■

*Література для CР: оператори – [55, 102, 133, 136].

Контрольні запитання та вправи

1.Що таке оператор із семантичного погляду?

2.Описати синтаксис і семантику порожнього оператора.

3.Описати синтаксис і семантику операторів переходу.

4.Описати синтаксис і семантику оператора присвоювання.

5.Що таке оператор групового присвоювання?

6.Які складні оператори присвоювання є в мові С?

7.Описати синтаксис і семантику оператора виклику функції.

8.Що таке ініціалізація параметрів і локальних даних?

9.Описати синтаксис і семантику оператора-виразу.

10.Описати синтаксис і семантику операторів продовження й переривання.

11.Описати синтаксис і семантику оператора виходу з функції.

12.Описати синтаксис і семантику операторів розгалуження й обходу.

13.Описати синтаксис і семантику оператора-перемикача.

14.Описати синтаксис і семантику операторів ітерації, повто- рення та структурного циклу.

15.Робота з текстом програм. Що виведепослідовність операторів: int i=1, x=1, y=2;

while(i<=10)

{++i; x*=i; y*=2;

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

}

16.Робота з текстом програм. Що виведе програма:

а) #include <stdio.h> int main()

{int counter; printf("while\tcount\n"); counter=1; while(counter<=10) {printf("%d\n", counter); counter++;

}

return 0;

322

Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++

}

б) #include <stdio.h> int main()

{int counter; printf("while count\t"); counter=10; while(counter>=1)

{printf("\n%d", counter); counter--;

}

return 0;

}

в) #include <stdio.h> int main()

{char c; printf("while\talphabet\n"); c='A';

while(c<='Z')

{printf("%c\t", c);

c++;

}

return 0;

}

г) #include <stdio.h> int main()

{ int counter; printf("do-while\ncount\n"); counter=0;

do {counter+=2;

printf("%d\n", counter); } while(counter<20) return 0;

}

д) #include <stdio.h> int main()

{int counter; printf("while count\n"); counter=20; while(counter>=1)

{ printf("\t%d\n", counter); counter-=2;

}

return 0;

}

323

ПРОГРАМУВАННЯ

17.Робота з текстом програм. Перевірити й виправити про- граму. Що вона виведе?

а) #include <stdio.h) int main()

{ printf("Print\n\n\n\n) for(i=0; i<=10, i++) printf("i=%c", i); return 0;

}

б) (* program test *)

#include "stdio.h> int main()

(int ivalue;

float fvalue=3.14159; ivalue=12;

printf("Print\n",ivalue="%d", ivalue) printf("%f", fvalue);

}

return 0;

)

в) {comment} include <stdio.h> int main()

{ int counter=1;

printf("while count\n", counter); while(counter>0)

{printf("%d\n", counter); counter++;

}

return 0;

}

г) #include stdio.h int man()

{

integer i=2; printf("while\talphabet\n", i); while(i<=245)

{ printf('%c\t", c); c--;

]

return 0;

}

д) include <stdio.h> int main()

( int counter=0;

324

Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++

printf("do-while\ncount\n"); do

( c+=2

printf("%d\n", counter); ) while(counter>0) return 0;

18.За цілим a > 0 обчислити найбільше n таке, що n ! < a .

19.Написати функцію обчислення n !, n ≥ 0 ( 0! =1).

20.Дано цілі числа m,n ≠ 0 . Знайти всі їхні загальні дільники.

21.Перевірити, чи є задане натуральне число простим.

22.Натуральне число називається досконалим, якщо воно збі-

гається із сумою всіх своїх власних (тобто менших за нього) дільників. Наприклад, першим таким числом є 6 =1+ 2 + 3 . Знайти всі досконалі числа не більші ніж n .

23.Обчислити вираз 1−1/2 +1/3 −... +1/999 −1/1000 : а) зліва

направо; б) зліва направо, але спочатку знайти суму членів із непарними знаменниками, потім – з парними, а потім узяти їхню різницю; в) справа наліво, г) див. б), але обчис- лення проводяться справа наліво. Порівняти й пояснити можливі розбіжності в результатах машинних обчислень.

24.Знайти, порівняти й пояснити різницю в машинних нулях

воколах чисел 1.0 та 1.0E9 . Це найбільші числа вигляду

δ =

1

такі, що 1+ δ =1 та 1.0E9 + δ =1.0E9 , відповідно.

n

 

2

 

25. Знайти наближені значення функцій ex та sin(x ) із зада- ною точністю ε > 0 за допомогою степеневих рядів відпові-

 

 

∞

 

i

 

∞

 

x

2i −1

 

дно

ex =

∑ x

 

та

sin(x )= ∑

(−1)i −1

 

 

. Ураховувати

 

(2i −1)!

 

 

i =0

i !

 

i =1

 

 

тільки ті члени ряду, які за абсолютною величиною більші ε .

26.Знайти наближені значення констант із заданою точністю

ε> 0 , використовуючи їхні подання у вигляді нескінченних

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

більш ніж на ε : а)

 

∞

1

;

б) 2/3 =

∞

(−1)i

1

;

2 =

∑

∑

i

i

 

 

i =0

2

 

 

i =0

 

2

 

325

ПРОГРАМУВАННЯ

в) π2

 

=

∞

 

1

 

; г) π2 /12 =

∞

(

−1 i −1

1

; д)

∞

1

;

/6

∑

 

 

∑

 

1/2 = ∑

 

 

 

 

 

 

 

 

 

 

 

)

i2

 

(2i −1)(2i +1)

 

 

 

 

i =1i2

 

 

 

i =1

 

 

 

i =1

 

 

 

 

∞

 

4i

2

.

 

 

 

 

 

 

 

 

е) π/2 = ∏

 

 

 

 

 

 

 

 

 

 

4i2

 

 

 

 

 

 

 

 

 

 

 

 

i =1

 

−1

 

 

 

 

 

 

 

 

27.Знайти наближені значення функцій із зад. 25 з урахуван- ням їх повільного спадання для великих аргументів. Вико- ристати тотожність ex = e[x ] e{x} , x ≥1 і періодичність фу- нкції sin(x ). Тут {x} – дробова частина числа x . Обчис-

лення першої ex

 

∞

xi

звести тільки

за допомогою ряду ∑

i !

 

 

i =0

 

 

 

 

 

∞

 

 

x

2i −1

 

 

 

для 0 < x <1, а другої – sin(x )= ∑

(−1)i −1

 

 

 

 

– тільки

 

(2i −1)!

 

i =1

 

 

 

для 0 ≤ x ≤ π/2.

З'ясувати, як змінюється точність обчис-

лення зі зростанням x = 0.1, 1.0 ,

10.0 ,

100.0

тощо для

ε =10−6 , порівнюючи відповідні значення зі значенням стандартних функцій exp(x ) та sin(x ) .

28.Знайти наближене значення числа π за формулою Мечина:

π/4 = 4arctg(1/5)-arctg(1/239) [33]. Для обчислення фун-

 

 

 

 

 

 

 

 

 

 

 

 

∞

(-1)

 

 

i+1

 

 

кції arctg скористатися рядом: arctg(1/x)= ∑

 

 

 

 

.

 

 

(2i −1)x2i −1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i=1

 

 

 

 

29.

Нехай

a = u;

b = v;

a

= 2b

 

+a

k −1

;

b

= 2a2

−1

+b .

 

 

1

1

k

k −1

 

 

 

k

 

k

 

k −1

 

 

 

 

 

 

 

 

 

 

 

 

n

akbk

 

 

 

 

 

 

 

Дано дійсні u ,

v , натуральне n . Знайти

∑

 

.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

k =1 (k +1)

!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

100 x

i

 

 

30.

Нехай x1 = x2 = x3 =1; xi

= xi −1 + xi −3, i = 4,5,... Знайти

 

∑

 

.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i =1

2i

 

31.

Нехай

a0 = a1 =1; ak = kak −1 +1/ak −2.

 

Дано натуральне

 

n . Отримати an .

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

32.

Нехай

x1 = y1 =1; xi

= 0.3xi −1;

 

yi

= xi −1 + yi −1, i = 2,3,...

 

 

 

 

 

n

x

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Дано натуральне n . Знайти ∏

 

.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i =11+

y

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

326

Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++

33. Нехай a1 = b1 =1; ak = 3bk −1 + 2ak −1; bk = 2ak −1 +bk −1. Дано

натуральне n . Знайти

n

 

2k

 

 

.

 

 

 

∑

 

 

 

 

 

 

 

 

 

 

 

 

k =1

(1+ak2 +bk2 )k !

 

 

 

34. Нехай

 

= 1

 

 

 

;

 

 

 

 

 

 

a

=b

=1; a

b

+ 1

a

b

= 2a2

−1

+b

, k = 2,3,...

1

1

k

 

k −1

2

k −1

k

 

k

k −1

 

 

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

Дано натуральне n . Знайти

∑ akbk .

 

 

 

 

 

 

 

 

 

 

k =1

 

 

 

 

 

 

3.4. Тип масивів

¾Специфікатор масивів

¾Динамічні масиви

¾Масиви як параметри функцій

¾Масиви й символьні рядки

Ключові слова: тип масивів, масив, оператори опису й декларації ма- сиву, гнучкий тип, специфікатор масиву, багатовимірні масиви, змінні з індексами, операція індексування, ініціатор масиву, динамічні масиви, маси- ви як формальні й фактичні параметри функцій, символьні рядки, ініціалі- зація символьних рядків.

Тип масивів – це тип, значеннями якого є вектори фіксованої до- вжини з однотипними компонентами. Дані цього типу називаються масивами. Тип компонентів масивів задають у їхньому описі або де- кларації. Обмежень на нього немає. Єдине – він не може бути непов- ним (див. підрозд. 3.4.1) або порожнім типом voіd.

3.4.1. СПЕЦИФІКАТОР МАСИВІВ

Специфікатор змінної-масиву задає її ім'я та довжину. Тип компо- нент задають у операторі опису масиву:

<специфікатор_масиву>::=\(<специфікатор-одновимірного-масиву>\)| \(<специфікатор-масиву>\) \[<константний_вираз>\] <cпецифікатор-одновимірного-масиву>::= <ім'я>\[<константний_вираз>\]

327

ПРОГРАМУВАННЯ

Усі неодновимірні масиви називаються багатовимірними. Увага! Круглі дужки в специфікаторі масиву можна опустити. Їх ви-

користовують для поліпшення читабельності деяких специфікаторів ► Приклад 3.32. Опис масивів:

char ascii[256];/*ascii – одновимірний символьний масив довжи-

ною 256*/

static int a[10]; /*a – статичний цілий масив довжиною 10*/ int y [2]; /*y – цілий масив довжиною 2*/

int (c[2])[3]; /*c – двовимірний масив довжиною 2 з компонентами – цілими масивами довжиною 3*/

int c[2][3]; /*c – те саме*/

int ((z[2])[3])[4]; /*z – тривимірний масив довжиною 2 з компонентами – двовимірними масивами довжиною 3 з компонентами – цілими масивами довжиною 4*/

int z[2][3][4]; /*те саме, що й у попередньому прикладі*/ T x[n]; /*x – масив типу Т довжиною n, n-константа*/

■

Далі наведені масиви без спеціального посилання будуть викорис- товуватися для ілюстрації тих чи інших конструкцій, пов'язаних із масивами.

Компоненти масиву розміщують послідовно в одному полі ОП. На- приклад, цілому масиву y відповідає поле довжиною 4 байти – по

2 байти на кожний компонент.

На масивах визначена єдина операція sizeof, яка повертає розмір пам'яті масиву в байтах. Для описаних вище масивів:

sizeof(ascii)=256*sizeof(char)=256,

sizeof(a)=10*sizeof(int)=20.

В описі довільного масиву x типу T ім'я x не тільки подає відповідний вектор елементів, а й має певне значення в системі базових типів – це покажчик-константа, що адресує перший компонент масиву. Усю об- робку масивів забезпечують змінні з індексами. Компоненти масиву x індексуються числами від 0 до n-1 і автоматично зв'язуються з вираза- ми x[0],…,x[n-1], які називаються змінними з індексами. Адреса змінної x[0] є значенням x як покажчика. Змінні з індексами забезпечують до- ступ до компонентів масиву відповідно до їхнього типу T. Наприклад, для масивів із прикл. 3.32 змінні ascii[0],…, ascii[255] – символьні,

a[0],…, a[9] – цілі, (c[2])[0], (c[2])[1], c[2][0] та c[2][1] – теж цілі, а

змінна c[2] – цілий масив із трьох компонентів.

328

Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++

Ефективна обробка масивів базується на індексованих виразах, що будуються за допомогою операції індексування. Для масиву x ці вирази мають вигляд x[e], де e – цілий арифметичний вираз. Значенням індек- сованого виразу x[e] є змінна з індексом x[к], де к – значення виразу е.

Приклад 3.33.

int i,j;

ascii[0]='\0'; /*нульовий компонент ascii замінюється на 0*/ a[і]=a[i]+1; /*і-й компонент масиву a збільшується на 1*/ a[i]++; /*те саме*/

c[i][j]=2*c[i][j]; /*j-й компонент масиву c[i] подвоюється*/ z[i][j][n]=i+j+n; /*n-й компонент масиву z[i][j] замінюється на

суму індексів*/

Наступні два цикли вводять значення компонентів масиву a зі ста- ндартного вхідного потоку й виводять на екран масив c:

/*виведення масиву a*/

for (i=0; i<10; i++) scanf ("%d", &a[i]); /*&a[i] – адреса змінної a[i]*/

/*виведення масиву с*/ for (i=0; i<2; i++)

{printf ("\n"); /*перехід на новий рядок екрана*/ for (j=0; j<3;j++ ) printf ("%d", (с[i])[j]);

}

У зовнішньому циклі спочатку вибирається і-й компонент c[i] масиву с, у внутрішньому – безпосередньо виводяться на екран усі його компоненти c[i][j] ■

В описі за допомогою ініціатора можна присвоїти початкові зна- чення компонентам масиву:

<ініціатор-масиву>::={<вираз>{,<вираз>}}

Вирази в правій частині мають відповідати типу компонентів ма- сиву. Стандарт С99 допускає неконстантні ініціатори, а також пра- вила для скорочення запису ініціаторів. Зокрема, якщо ініціаторів полів менше ніж потрібно, то використовуються їхні значення за умо- вчанням або хвіст масиву просто не ініціалізується, якщо більше – це викликає помилку в роботі компілятора. В описах з ініціалізацією ма- сиву можна використовувати специфікатори масиву без довжини. У цьому випадку компілятор сам установлює довжину масиву за кіль- кістю елементів у ініціаторі.

329

ПРОГРАМУВАННЯ

 

 

 

 

 

 

 

Приклад 3.34. Ініціалізація масивів:

 

 

 

а) int b[5]={0,1,2,3,4} ; /*ініціалізація цілого масиву b*/

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

 

 

 

 

0

 

1

 

2

3

4

 

 

b[0] b[

 

b[2

] b[2]

b[3]

b[4]

 

 

 

1]b[1]

 

 

 

Таким самим буде результат описів: int n=4;int b[]={0,1,2,3,n};

б) char line [6]={‘A',‘B',‘C',‘D',‘E' };

 

 

/*ініціалізація символьного масиву line: останній компонент не

ініціалізується*/

 

 

 

 

 

 

 

65

66

67

 

68

69

?

line[0]

line[1]

line[2]

line[3]

line[4]

line[5]

в) int c[2][3]={{2,2,2}, {3,3,3}}; /*ініціалізація двовимірного

масиву с*/

 

 

 

 

 

 

 

 

2

2

2

 

3

 

3

3

c[0][0]

c[0][1]

c[0][2]

c[1][0]

c[1][1]

c[1][2]

Таким самим буде й результат описів з ініціалізаціями:

int c[2][3]={2,2,2,3,3,3}; та int c[][3]={{2,2,2}, {3,3,3}}; ■

Неповний специфікатор масиву в операторі декларації має формат

<неповний-специфікатор-масиву>::=<ім'я>[]| (<неповний-специфікатор-масиву>)[<константний_вираз>]

Кажуть, що задекларований масив має неповний тип, оскільки в ньому відсутня інформація про довжину масиву. Такі масиви вико- ристовуються як параметри функції, у невизначальних зовнішніх де- клараціях і при ініціалізації масивів. Однак у будь-якому разі, якщо типом компонент є масив, то його опис має бути повним.

330