Зубенко, Омельчук - Програмування. Поглиблений курс
.pdf
Розділ ІІІ. МОВИ ПРОГРАМУВАННЯ С ТА С++
<структурний-цикл>::=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
