Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metod_pract_OTP-2004-ukr.doc
Скачиваний:
2
Добавлен:
17.11.2019
Размер:
964.1 Кб
Скачать

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ

УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ

МЕТОДИЧНІ ВКАЗІВКИ ДО ВИКОНАННЯ

ПРАКТИЧНИХ ТА ЛАБОРАТОРНИХ РОБІТ З КУРСУ

“ОБЧИСЛЮВАЛЬНА ТЕХНІКА ТА ПРОГРАМУВАННЯ"

для студентів денної форми навчання спеціальностей

7.091.001– "Конструювання і технологія ЕОЗ" ,

7.091.002– "Конструювання і технологія радіоелектронних засобів",

7.091.005– "Автоматизація технологічних процесів у виробництв

ектронних апаратів ",

7.090.802– "Електронні прилади та пристрої",

7.090.804– "Фізична та біомедична електроніка",

7.090.801– "Мікроелектроніка та напівпроводникові прилади".

ЗАТВЕРДЖЕНО

кафедрою Інформатики.

Протокол № __ від"___"_____ 2004р.

ХАРКІВ 2004

МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ

ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ

УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ

До друку і в світ дозволяо

Проректор з навчальної

та методичної роботи

В.В. Семенець

"___"____________ 2003р.

МЕТОДИЧНІ ВКАЗІВКИ ДО ВИКОНАННЯ

ПРАКТИЧНИХ ТА ЛАБОРАТОРНИХ РОБІТ З КУРСУ

"ОБЧИСЛЮВАЛЬНА ТЕХНІКА ТА ПРОГРАМУВАННЯ"

для студентів денної форми навчання спеціальностей

7.091.001– "Конструювання і технологія ЕОЗ" ,

7.091.002– "Конструювання і технологія радіоелектронних засобів",

7.091.005– "Автоматизація технологічних процесів у виробництв

ектронних апаратів ",

7.090.802– "Електронні прилади та пристрої",

7.090.804– "Фізична та біомедична електроніка",

7.090.801– "Мікроелектроніка та напівпроводникові прилади".

Всі цитати, цифровий, ЗАТВЕРЖДЕНО

фактичний матеріал і кафедрою Інформатики

бібліографічні відомості Протокол № 18 від 07.03.03р.

перевірено написання одиниць

відповідає стандартам

Упорядники: Бритік В.І.,

Алісейко О.В.,

Свинар М.К.,

Маркова Л.І.

Відповідальний за випуск Путятін Є.П.

П.С. Ковтун

Б.П. Косіковська

ХАРКІВ 2003

ЗМІСТ

Загальні вказівки 4

1 РОЗВ’ЯЗАННЯ ЗАДАЧ З ПРОСТИМИ ЗМІННИМИ 4

1.1 Мета роботи 4

1.2 Підготовка до роботи 4

1.3 Варіанти індивідуальних завдань до лабораторної роботи 1 13

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

2 РОЗВ’ЯЗАННЯ ЗАДАЧ З ВИКОРИСТАННЯМ ВЕКТОРІВ 16

2.1 Мета роботи 16

2.2 Підготовка до роботи 16

2.3 Варіанти індивідуальних завдань до лабораторної роботи 2 19

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

3 РОЗВ’ЯЗАННЯ ЗАДАЧ ІЗ ВИКОРИСТАННЯМ СТРУКТУР 21

3.1 Мета роботи 21

3.2 Підготовка до роботи 21

3.3 Варіанти індивідуальних завдань до лабораторної роботи 3 24

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

4 РОЗВ’ЯЗАННЯ ЗАДАЧ ІЗ ВИКОРИСТАННЯМ ФУНКЦІЙ 26

4.1 Мета роботи 26

4.2 Підготовка до роботи 26

4.3 Область існування й видимість змінних. Класи пам’яті 27

4.4 Організація взаємодії функцій у програмі 28

4.5 Варіанти індивідуальних завдань до лабораторної роботи 4 33

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

5 РОЗВ’ЯЗАННЯ ЗАДАЧ З ВИКОРИСТАННЯМ РЯДКОВИХ

ЛІТЕРАЛІВ 35

5.1 Мета роботи 35

5.2 Підготовка до роботи 35

5.3 Варіанти завдань до лабораторної роботи 5 37

6 ВВЕДЕННЯ/ВИВЕДЕННЯ ІНФОРМАЦІЇ 38

6.1 Мета роботи 38

6.2 Підготовка до роботи 38

6.3 Варіанти завдань до лабораторної роботи 6 42

Додаток А 45

Перелік посилань 47

ЗАГАЛЬНІ ВКАЗІВКИ

Розв’язання практично всіх сучасних задач неможливе без використання обчислювальної техніки. При цьому значно зростає потреба в грамотних інженерах, здатних ставити й вирішувати задачі на ЕОМ.

В основу курсу покладене вивчення таких тем:

1. Основні типи даних та їхнє внутрішнє подання, константи та змінні, бібліотечні функції простого введення / виведення інформації;

2. Операції і вирази в С++, порядок виконання операцій;

3. Структура простих програм, область видимості та існування змінних;

4. Оператори управління;

5. Покажчики та посилання, вектори, зв'язок покажчиків та посилань із векторами;

6. Складені типи даних;

7. Функції, організація взаємодії функцій у програмі;

8. Строкові літерали, обробка текстів;

9. Класи;

10.Організація введення / виведення в С++.

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

Звіт до лабораторної роботи має містити: прізвище та ініціали студента з зазначенням групи та курсу; вхідні дані завдання, що виконується; роздрук тексту програми та результатів її виконання; аналіз помилок і висновки.

1 Розв’язання задач із простими змінними

1.1 Мета роботи

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

1.2 Підготовка до роботи

Необхідно ознайомитися з основними призначеними типами даних (цілочисельні типи, речовинні типи, тип char та логічний тип (bool)) [1, с. 42–49, конспект лекцій]. Стислі відомості щодо цілочисельних та речовинних типів можна отримати з наведених нижче таблиць (табл. 1.1 і табл. 1.2).

Т аблиця 1.1

Тип

Роз–мір

Десятковий

Шістнадцятковий

Вісімковий

біт

min

max

min

max

min – max

Unsigned int

16

0

65535

0x8000

0xffff

00.. 0177777

Short int

16

–32768

32767

0x0000

0x7fff

00.. 077777

Int

16

–32768

32767

0x0000

0x7fff

00.. 077777

Long

32

-2147483648

2147483647

0x10000

0x7fffffff

00.. 17777777777

Unsigned long

32

0

4294967295

0x0000000

0xffffffff

00.. 37777777777

Т аблиця 1.2

Тип

Роз–мір

Діапазон подання чисел

Діапазон біт виділених під

Знак

Точн.

біт

min

max

мантису

порядок

біт

10с/з

Float

32

3.4 E–38

3.4 E 38

0/22

23/30

31

7

Double

64

1.7 E–308

1.7 E 308

0/51

52/62

63

15

Long double

80

3.4 E–4932

3.4 E 4932

0/63

64/78

79

19

Логічні дані типу “bool”, введені в Borland C++ 5, займають у пам'яті один байт і мають два значення 1 (true) і 0 (false). Оголошення логічних змінних з ініціалізацією припускає використання двох постійних true (1) і false (0).

Наприклад:

bool dd=true;//dd=1

bool dd1=1;//dd1=true.

Дані типу char займають у пам'яті 1 байт, визначаються множиною значень кодової таблиці ПЕОМ. Код від 0 до 255 задає один із можливих символів кодової таблиці (звичайно, ASCII– таблиця). Дані типу char можуть розглядатися компілятором як дані «цілого» типу: дані зі знаком (signed char); дані без знака (unsigned char). Форма подання типу char як «ціле» у IDE задається опцією компілятора. Якщо тип char визначений як unsigned, тоді діапазон зміни значень – від 0 до 255, а якщо signed, тоді – від 128 до 127.

У програмі константа типу char являє собою символ, укладений в одиночні лапки – ‘A’, ‘F’, ‘$’ і т.п. Наприклад:

char sim;

sim=’A’;

Під час написання програми допускається використання символічних констант. Константи в С++ можуть задаватися: в десятковій; вісімковій і шістнадцятковій системах обчислень. Тип і система обчислення, в якій подана символічна константа, визначається компілятором за її записом (за замовчанням) або за допомогою суфіксів (явно) unsigned. Ознакою системи обчислення для компілятора є: для шістнадцяткової системи обчислення (с/о) – наявність у двох лівих символах літер ОХ (oх); для вісімкової с/о – наявність у якості першого символу цифри 0; для десяткової с/о – незадоволення двох описаних вище умов.

Ознакою типу символічної константи, що задається в явному вигляді, служать суфікси U (u) для констант типу unsigned; L (l) – для констант типу long. Дозволяється комбінувати ці суфікси в будь-якому порядку. Від’ємні константи додержуються застосуванням операції «- унарний мінус» до відповідної додатної константи. Нариклад:

8.27,–30201//десяткові мають тип int, якщо не перевищують максимально

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

6U, 30201U//unsigned int

6UL, 30201UL//unsigned long

032.066, 077//вісімкові

0x27, OX77A//шістнадцяткові

0x27, 0X77a//шістнадцяткові довгі

Під час підготовки до заняття необхідно засвоїти пріоритет і порядок виконання арифметичних та логічних операцій.

Вирази складаються з операцій і операндів. В мові С в якості операндів можуть використовуватися константи, змінні, покажчики функцій і вирази. Оператори програми в мові С можуть бути простими й складними. Простий оператор – це оператор, який не містить інші оператори. Роздільником операторів служить крапка з комою – «;». Спеціальним випадком простого оператора є порожній оператор, який складається з одного символу «;». Цей оператор використовується, коли після позначки або операторів циклу не повинно слідувати жодного оператора. Наприклад:

label:;//позначка з порожнім оператором

while (лог. вираз);//доки лог. вираз true

//подальше виконання програми

Іншим спеціальним випадком простого оператора є оператор позначки. Оператор позначки – це оператор вираження (можливо, порожнього), обмежений крапкою з комою, перед яким стоїть ідентифікатор, що закінчується символом«:». Наприклад:

Point_out: return result;,

де: Point_out – позначка.

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

Складний оператор являє собою нуль або більше операторів, укладених у фігурні дужки. Використання цього оператора можливе в будь-якому місці програми, де допустимий простий оператор. Відокремлювана особливість складного оператора мови С++ від інших (наприклад, PASСAL) полягає в тому, що він визначає нову область чинності ідентифікатора. Змінні, які знаходяться всередині складного оператора, є локальними в ньому і переховують зовнішні змінні з тими ж іменами (для версії С++ 5.0 це правило не виконується).

Наприклад:

t=10.24;

{int t=a; a=b; b=t;}//t–локальна змінна, відмінна від попередньої змінної t.

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

Таблиця 1.3

Операції, що виконуються

зліва направо

з права наліво

() [] -->.

++ -- постфіксні

! ~ ++ - -+- & (type) sizeof унарні

++ - - префіксні

* / % арифметичні мультиплікативні

<< >> зрушення (що висуваються і втрачаються)

< <=> > = відношення 1

= = ! = відношення 2

& побітова кон’юнкція

^ побітова сума по mod2

| побітова диз’юнкція

&& логічна кон’юнкція (так)

|| логічна диз’юнкція (або)

?: умова

=+=-= *=/=%= &= ^=!=<<=>>=

, кома

У виразах на мові С++ може бути використано значне число функцій. Однак, в відміну від більшості мов високого рівня (Fortran, Pascal), використання функцій у виразах (не тільки математичних) вимагає підключення заголовочних файлів, у яких описано прототипи функцій, що використовуються. Наприклад, використання стандартних математичних функцій вимагає підключення заголовочного файлу <math. h>.

Математичні функції заголовочного файлу <math. h> наведені в таблиці 1.4.

Таблиця 1.4

Прототип функції

Ім'я

Зміст

double acos (double _x);

acos (x)

Арккосинус

double asin (double _x);

asin (x)

Арксинус

double atan (double _x);

atan (x)

Арктангенс

double atan2(double_y,double_x);

atan2 (y, x)

Арккотангенс від y/x

double ceil (double _x);

ceil (x)

Округлення в більшу сторону

double cos (double _x);

cos (x)

Косинус, x – в радіанах

double cosh (double _x);

cosh (x)

Косинус, гіперболічний

double exp (double _x);

exp (x)

e у ступені x (e^x)

double fabs (double _x);

fabs (x)

Абсолютне значення |x| типу double

double floor (double _x);

floor (x)

Повертає найближче ціле, не більше x

double fmod(double_x,double_y);

fmod (x)

Залишок від ділення x на y

double log (double _x);

log (x)

Натуральний логарифм

double log10 (double _x);

log10 (x)

Десятковий логарифм

double modf (double _x, dou);

modf (x, &p)

Виділяє цілу й дробову частини числа

double pow (double_x,double_y);

pow (x, y)

xy x у ступені y

double sin (double _x);

sin (x)

Синус x, в радіанах

double sinh (double _x);

sinh (x)

Синус, гіперболічний

double sqrt (double _x);

sqrt (x)

Корінь з x, x>0

double tan (double _x);

tan (x)

Тангенс x, x у радіанах

double tanh (double _x);

tanh (x)

Тангенс, гіперболічний

int abs (int _x);

abs (x)

Модуль x типу int

double atof (const char*_s);

atof (s)

Перетворює рядок символів у число з плаваючою комою

double hypot (double_x,double_y);

hypot (x, y)

Корінь із (x2+y2)

long labs (long _x);

labs (x)

Абсолютна величина типу long |x|

double pow10 (int _p)

pow10 (p)

Повертає 10p

Визначений також і ряд констант pi, log2=1. 44..., log10==0. 43... І т. п.

Оператори керування обчислювальним процесом використовуються для організації розгалуження, циклічного повторення операторів програми, а також передачі управління в необхідне місце програми в залежності від виконання будь-яких умов. Мова С++ підтримує умовні оператори (if, switch) і оператор break.

Оператор розгалуження if має такий вигляд:

if (вираз) True_оператор;

Наступний оператор;

де «вираз» – вираз довільного вигляду, що інтерпретується мовою С як логічне, де будь-яке відмінне від нуля значення трактується як True а у протилежному випадку як False. Цим оператором виконується така робота: обчислюється вираз; якщо значення виразу не дорівнює нулю, то виконується True–оператор, а після цього наступний за if оператор; якщо значення дорівнює нулю, то True–оператор пропускається й управління передається до наступного за if оператора.

Наприклад :

int i=0, j=0;

.............

if (m [j] <0) i++; //i–лічильник від’ємних елементів масиву m.

.............

Наведений вище оператор if можна розглядати як приватний випадок оператора if... else, що має вигляд:

if (вираз) True–оператор;

else

False–оператор;

Наступний оператор;

Цим оператором (if.. else) виконується така робота: якщо обчислений вираз не дорівнює нулю, то виконується True_оператор, а після цього наступний за if.. else оператор; якщо обчислений вираз дорівнює нулю, то виконується False_оператор, а після цього наступний за if.. else оператор.

Наприклад:

int i=0, j=0, k=0;//int i=j=k=0;

.......

if (m [j] <0) i++;// лічильник від’ємних елементів

else

k++;// лічильник додатніх елементів

........

Оператор if.. else можуть бути вкладеними. В цьому випадку оператори True_оператор або False_оператор можуть подаватись такою само конструкцією if.. else.

Наприклад:

int i=0, j=0, k=0, n=0;

................

if (m [j] ==0) n++; //лічильник нульових елементів

else

if (m [j] <0) i++; // лічильник від’ємних елементів

................

Для усунення неоднозначності компілятор С інтерпретує вкладені if таким чином, що вітка else відносить його до найближчого попереднього if.

Оператор switch має форму:

switсh (switch_вираз;) {//початок тіла оператора switch

case константний цілочисельний вираз 1: оператор 1; [break;]

case – – – – – – – – –//– – – – – – – – – – – – – – – – 2: оператор 2; [break;]

case – – – – – – – – –//– – – – – – – – – – – – – – – – n: оператор n; [break;]

[default: оператор n+1;]}//кінець оператора switch

Наступний оператор;//у цю крапку передається управління.

Оператор switch працює таким чином: спочатку обчислюється switch_вираз (switch_вираз – вираз цілочисельного типу ); обчислений вираз порівнюється зі значеннями констант або константних виразів.

Якщо будь-який з константних цілочисельних виразів співпав зі значенням switch_виразу, то виконується відповідний оператор і управління (за наявності оператора break) передається наступному за оператором switch оператору; якщо відповідного збігу не виявлено, то виконується оператор n+1 вітки default (якщо він є) та управління передається наступному після switch оператору.

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

Слід знати, що за відсутності операторів break в тілі оператора switch і збігу значення switch_вираження з яким-небудь константним цілочисельним виразом виконується прохід наскрізь через всі оператори, що залишалися в тілі оператора switch, включаючи і оператор вітки default.

Мова С++ підтримує три оператори циклу while, do... while і for.

Оператор while у загальному вигляді записується:

while (вираз)

Оператор;

Наступний за циклом while оператор;

Оператор while забезпечує реалізацію циклу з передумовою. Це означає, що оператор у тілі циклу взагалі не обчислюється, якщо обчислений вираз дорівнював нулю (лож), а управління передається наступному за циклом while оператору. Якщо вираз не дорівнює нулю (істинно), тоді обчислюється оператор, і управління передається назад до початку циклу. В результаті тіло циклу оператора while-оператор, виконується до тих пір, доки вираз прийме значення нуль (неістинно), а управління буде передано наступному за циклом оператору. Наприклад:

int i=0, p=1;

while (i<=10) {//Обчислення 10!

if (i==0) p=i;

else p*=i;

i++;

}

Оператор do.. while у загальному вигляді записується:

do

Оператор;

while (вираз);

Наступний за оператором do оператор;

На відміну від попереднього оператор do реалізує цикл з постумовою, що гарантує виконання тіла циклу хоча б один раз, після чого виконується обчислення виразу. Якщо значення виразу не дорівнює нулю (істинно), тоді управління передається назад до початку оператора do і процес обчислення повторюється. Якщо значення виразу «нуль» (неістинно), управління передається наступному за оператором do оператору.

Наприклад:

void main()

{

int chislo,p1,p2,s=0;

cout<<"vvedite chislo\n";

cin>>chislo;

do

{p1=chislo%10;

p2=chislo/10;

chislo=p2;

s+=p1;

} while(chislo);

cout<<"sum = "<<s<<"\n";

cin>>s;

}

Оператор циклу for записується

for (оператор1; вираз1; вираз2)

Оператор2;

Оператор;//– наступний за оператором For оператор;.

Оператор for працює таким чином. Спочатку виконується оператор1 (зазвичай це оператор ініціалізації), що в окремому випадку може бути порожнім. Після цього обчислюється вираз1. Якщо значення виразу1 дорівнює нулю (неістинно), то управління передається наступному за оператором for оператору, і оператору2, коли значення виразу1 не дорівнює нулю. Після цього виконується вираз2 і управління передається на вираз1. Таким чином оператор2 (тіло циклу) повторюється, доки вираз1 не прийме значення 0.

Наприклад:

int min=а [0]

for (int i=0, i<100, i++)

if (min>a [i]) min=a [i];

Під час підготовки до роботи слід вивчити засоби організації ітераційних циклів [1, c. 101–103], засоби програмної реалізації ітераційних циклів на мові С++. В даній роботі навики організації ітераційних циклів набуваються при складанні лейбніцівських рядів з необхідною точністю.

Нагадаємо, що лейбніцівським називається ряд вигляду

S= (1.1)

де , і .

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

Ця властивість часто використовується при близьких обчисленнях. Точність складання лейбніцевського ряду вважається досягнутою, якщо Cn< для деякого n. На практиці значення Cn задаються як функції n, тобто

(1.2)

Як правило, обчислювальні алгоритми, в яких Cn обчислюється безпосередньо за формулою (1.2), виявляються неефективними, бо на їхню реалізацію витрачається багато машинного часу.

Може виявитися, що значення Cn обчислюватиметься простіше, якщо скористуватися рекурентним співвідношенням

(1.3)

Тоді

(1.4)

Пояснимо на прикладі. Нехай необхідно підсумувати ряд

n (1.5)

З точністю e=1E–4 в точці X0=0. 5.

При обчисленні Сn безпосередньо з формули (1.2) виникає необхідність при кожному n обчислювати міри X2n–1 і факторіали (2n+1)!. З більшими n ця процедура знижує як швидкість, так і точність обчислень.

Обчислення же Cn за допомогою рекурентного співвідношення виявляються більш простими. Справді, якщо підставити в (1.3) значення Cn і Cn–1, виконавши необхідні перетворення, отримаємо:

R= (1.6)

Підставивши отримане значення R у (1.4), отримаємо рекурентну формулу для обчислення Cn:

(1.7)

В цьому випадку алгоритм обчислень можна скласти так:

n=0; x=0. 5; e=1e-4;

Перед входом в ітераційний цикл у s1 заноситься значення x. Тому

s1=x; s=s1;

Доки |x|> повторювати

s1*=x*x/(2*n* (2*n+1));

s=s1.

Нижче наводиться приклад програми виконаної на мові C++.

#include <stdio.h>

#include <iostream.h>

#include <math.h>

void main ()

{int n=1, k;

float x=0.5, e=1.0E–10, s, s1;

s=s1=x;

while (s1>e)

{s1*=x*x/(2*n* (2*n+1));

cout<<"s1="<<s1<<'\n';

s+=s1; n++;}

cout<<"s="<<s<<'\n';

cin>>n;

}

1.3 Варіанти індивідуальних завдань до лабораторної роботи 1

Варіанти індивідуальних завдань до лабораторної роботи 1 (табл. 1.5).

Таблиця 1.5

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

З точністю

1

S=

=10–2

2

S=

=

3

S=

=

4

S=

=

5

S=n

=

6

S= (–1) n

=

X0=0. 3 .

7

S= (–1) n

=

X0= /9.

8

S= (–1) n+1

=

X0=1. 6

9

S= (–1) n+1

=

X0=1. 22

10

S= (–1) n

=

X0=0. 6785

11

S=

=

12

S= (–1) n+1

=

13

S=n

=

14

S

=

15

S=

=

16

S= (–1) n

=

X0=2. 44

17

S=

=

18

S=4 (–1) n

=10–2

19

S=

=

X0=2. 334

Продовження таблиці 1.5

20

S=

=

21

S=2

=

X0=0. 4357

22

S=

=10–2

23

S=

=

24

S=

=

25

S=

=

26

S=

=

27

S=

=

28

S=

=10–2

29

S=4 (–1)n+1

=10–2

30

S= (n–1)

=10–5

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

1. Як ввести початкові значення змінних?

2. Яке місце розташування операторів опису типу в програмі?

3. Які форми подання чисел у С++?

4. Яка послідовність виконання операцій у виразах?

5. Що розуміється під терміном «тіло циклу»?

6. Якого типу можуть бути позначки в операторі switch?

7. Які існують форми запису умовного оператора?

2 РОЗВ’ЯЗАННЯ ЗАДАЧ З ВИКОРИСТАННЯМ ВЕКТОРІВ

2.1 Мета роботи

Засвоєння засобів роботи з векторами на мові С++; отримання навичок роботи з покажчиками.

2.2 Підготовка до роботи

Під час підготовки до роботи слід вивчити засоби організації користувальчих типів. Необхідно ознайомитися з основними типами даних «Покажчик», «Вектор», а також навчитися використовувати змінні типу «Заслання» [1, с. 75–90; 2, ç. 89–96; конспект лекцій].

Покажчики. Покажчики – особливий тип даних, що призначений для зберігання адреси в пам'яті. В мові C визначено два види покажчиків: покажчики на об'єкт без певного типу – void*; покажчики об'єктів певного типу.

Покажчики на об'єкти певного типу бувають також двох видів: покажчики константи і покажчики змінні. Покажчики змінні визначаються в операторах оголошення за допомогою символу «*», що розташован перед ідентифікатором покажчика. Наприклад:

int*p;

long a, *c;,

де int* – тип покажчик на деяку змінну типу int; p – ідентифікатор покажчика на змінну; c – ідентифікатор покажчика на деяку змінну типу (long*).

Ініціалізація покажчика виконується за допомогою оператора вилучення адреси – «&». Тому якщо в тілі програми зустрівся оператор оголошення «long L;», тоді використання оператора «&L» дасть у результаті адресу розташованого в пам'яті значення змінної L. Ініціалізація покажчиків може бути виконана в розділі оператора оголошення

long L, *a=&L, G, *p;//a вказує на L.

p=&G;//p вказує* на G

Відзначимо, що використання покажчика в тілі програми виробляється без використання символу «*». Оскільки допустимий діапазон значень будь-якого покажчика включає спеціальну адресу 0 і набір додатних цілих чисел, що інтерпретуються як машинні адреси, то допускається ініціалізація покажчиків з використанням символічних констант. Наприклад:

Long L, *a=&L, b, *p, *pt= (Long*) 300;

де покажчик pt одержує початкове значення 300. Використання символічних констант допустимо і в тілі програми. Наприклад:

long L, *a=&L, b, *p, *pt= (long*) 300;

p= (long*) 400;//покажчик p має значення 400.

Особливе місце займає покажчик, значення якого дорівнює 0 – null. Цей покажчик використовується як спеціальний прапор умови. Наприклад: під час роботи з динамічними змінними вичерпана вільна пам'ять; кінець динамічної структури даних (списку, стека, дерева). Слід знати, що оскільки покажчик–змінна теж має адресу, то можлива організація побічної адресації (в покажчикові зберігається адреса іншого покажчика на будь-яку змінну).

Наприклад:

long L, *p, *a=&L;

p=(long*) &a;//p зберігає адресу покажчика a на змінну L.

Під час роботи з покажчиками часто використовується операція одержання адреси – «&». Але необхідно знати, що ця операція має такі обмеження: не можна визначити адресу символічної константи; не можна визначити адресу арифметичного виразу; не можна визначити адресу змінної, описаної як register.

Операція розіменування – одномісна операція «*» з тим же пріоритетом і асоціативністю справа наліво, що й інші одномісні операції. Сенс цієї операції полягає в переході від покажчика до значення на яке він вказує. Таким чином, якщо в програмі є оголошення

int a, *p;//p – покажчик на int

a=1;

.........

p=&a;,

то вираз “++*p; //*p=*p+1;” означає збільшення значення змінної цілого типу a на одиницю (a=2).

Як бачимо, з описаного вище прикладу, унарна операція розіменування «*», що використовується в тілі програми, ідентифікується компілятором за наявністю відповідного оголошення покажчика.

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

*p++;//відповідає (p+1) або (*p) ++

++*p;//*p=*p+1

Вектори. Тісний зв'язок з покажчиками має визначений в мові C++ тип даних – вектор. Вектори – це структурований тип даних, який являє собою безперервні блоки пам'яті, що містять безліч елементів одного і того ж типу. Ознакою вектора при описі є наявність парних квадратних дужок [].

Вектор описується шляхом зазначення типу елементів, імені і квадратних дужок. Додатна константа або константний вираз всередині квадратних дужок задає число елементів вектора. Елементи вектора нумеруються з 0. Наприклад:

long arr1 [32];

char arr2 [79];,

де проголошені вектори arr1, що містять 32 елементи типу long і arr2, що містить 79 елементів типу char.

В C++ розв'язані два засоби доступу до елементів вектора: з використанням механізму покажчиків; за допомогою індексу (класичний). Доступ до елементів вектора шляхом зазначення назви імені та індексу в квадратних дужках не вимагає особливого пояснення, оскільки широко використовується практично в усіх мовах програмування. Застосування же механізму покажчиків засноване на використанні факту, що ім'я вектора є покажчиком – константою, що дорівнює адресі початку вектора – першого байта першого елементу вектора (arr1==&arr1 [0]). В наслідок цього, використовуючи операцію розіменувания «*» можна забезпечити доступ до будь-якого елементу вектора. Так, еквівалентні будуть звернення до i–го елементу вектора з використанням індексу – arr1 [i] і заслання

*(arr1+i), оскільки

(arr1+i) ==&arr1 [i].

Слід звернути увагу, що вираз *(arr1+1) не еквівалентний помилковому *(arr1++), оскільки arr1 є покажчик – константа. Під час використання операції інкремента (декремента) необхідно визначити проміжну змінну – покажчик.

Наприклад, таке визначення змінних

int arr [20];

int*ukar=&arr [0];

дозволяє в операторах циклу для доступу до елементів використати вираз

*ukar++.

Під час опису вектора може бути виконана ініціалізація його елементів. В C++ визначені два правила ініціалізації: за замовчанням; явна ініціалізація.

Правило ініціалізації “за замовчанням” визначене для статичних та зовнішніх змінних: векторів, багатомірних векторів (масивів), рядків, покажчиків, структур та об'єднань. За замовчанням усі елементи цих змінних иніціалізують нулями.

Явна ініціалізація вектора відбувається шляхом завдання набору початкових значень елементів, поділених комами та укладених в фігурні дужки:

int b [3] ={1, 2.3};//b [0] =1, b [1] =2, b [2] =3

У мові С++* допускається неминучість значення індексу вектора і числа початкових значень елементів. Коли число початкових значень менше значення індексу, то иніціалізують тільки перші елементи вектора, а інші або дорівнюються нулю, або не визначені. Наприклад:

int b [3] ={1};//b [0] =1, b [1] =0, b [2] =0

Якщо число початкових значень більше значення індексу, то буде згенероване повідомлення про помилку.

int b [3] ={1, 2.3, 4};//помилка

Масиви. На відміну від інших мов високого рівня в С++ вектори мають тільки одну вимірність. Багатовимірні масиви в С++ надаються у вигляді векторів покажчиків на вектори – багатовимірні вектори. Багатовимірні вектори описуються наступним чином :

int V[3][3];//3 вектори з 3 int кожний

float BV[5][5][5];//5 векторів покажчиків на 5 векторів з 5 float

Синтаксис мови С++ не обмежує вимірність векторів. Однак реально використовуються вимірності не вище трьох.

Звернення до елементів багатовимірних векторів може відбуватися як класичним засобом (шляхом указання значень індексів), наприклад:

V[1][2] =3;,

так і з використанням механізму покажчиків

*(V [1] +2) =3; //V[1][2] =3.

Використання механізму покажчиків для доступу до деякого i, j, k–ого елементу тривимірного вектора зручно розглянути на прикладі таких еквівалентних звернень :

BV[i][j][k]==*(BV[i][j] +k)==*(*(BV[i] +j) +k)==*(*(*(BV+i) +j) +k)

У цих зверненнях використовується той факт, що ім'я багатовимірного вектора є покажчиком–константою на вектор покажчика–константи вектора рядка, перший елемент якого є теж покажчик–константа рядка. Елементи багатовимірних векторів зберігаються в пам'яті в порядку зростання самого правого індексу – за рядками.

Аналогічно одновимірним векторам багатовимірні можуть бути також иніціалізовані при їхньому описі, наприклад:

float BV[3][3][3] ={1. 1.1. 2.1. 3,

2.1, 2.2, 2.3,

3.1, 3.2, 3.3};

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

Приклад програми обчислення суми елементів головної діагоналі матриці:

#include<stdio. h>

void main ()

{int V[][3] ={1, 2.3,

4.5, 6,

7.8, 9};

int i, s, s2; s1=0; s2=0;

for (i=0; i<3; i++)

s1+=V[i][i];

for (i=0; i<3; i++)

s2+=*(*(V+i) +i);

printf (“s1=%d s2=%d“, s1, s2);

}

2.3 Варіанти завдань до лабораторної роботи 2

Вхідні числові дані вибираються довільно.

1.Обчислити суму додатних і кількість від’ємних елементів багатовимірного вектора v[5][5].

2. Задані два вектори X і Y , що містять по десять елементів. Трактуючи їх як координати точок площини, обчислити відстань між ними.

3. Заданий вектор X[20]. Додатні числа переписати в масив Y, а від’ємні – в масив W.

4. Змінити місцями мінімальний і максимальний елементи головної діагоналі матриці (багатовимірного вектора v[5][5]).

5. У векторі з 20 елементів переставити елементи так, щоб спочатку розташувались всі від’ємні елементи, а після цього – всі інші елементи без порушення порядку їхнього слідування.

6. У цілочисельній квадратній матриці (багатовимірного вектора v[5][5]) визначити номери рядків (значення векторів покажчиків на вектори), всі елементи яких парні, знайти суми елементів цих рядків.

7. Знайти добуток двох матриць (багатовимірних векторів) 5x6 і 6x5 елементів.

8. У багатовимірному векторі 4x6 елементів знайти мінімальний елемент і його індекси.

9. У матриці (багатовимірному векторі) 4x6 елементів змінити місцями стовпці, що містять мінімальний та максимальний елементи. Врахувати особливості мови С++.

10. Відсортувати елементи третього рядка матриці (багатовимірного вектора) 5x6 елементів за зростанням значень. Врахувати особливості мови С++.

11. У багатовимірному векторі V[4][5] замінити нулем максимальний і одиницею мінімальний елементи.

12. Замінити від'ємні елементи багатовимірного вектора V[4][5] нулями та знайти їхню кількість.

13. У векторі V [23] змінити місцями максимальний і мінімальний елементи.

14. У векторі V[23] є однакові числа. Знайти кількість чисел, які часто зустрічаються.

15. Знайти суму трьох багатовимірних векторів розміром 4x6 елементів.

16. У векторі V [23] знайти добуток додатних елементів, що розташовані на парних місцях, і кількість всіх від’ємних елементів.

17. У векторі V [23] знайти середнє арифметичне всіх від’ємних і середнє геометричне додатних чисел.

18. У кожному рядку матриці (вектора покажчиків на вектори) V[4][5] знайти кількість елементів, що діляться на три, і записати їх у вектор.

19. Відсортувати елементи головної діагоналі матриці (багатовимірного вектора) 6x6 елементів за зростанням.

20. У векторі V[23] знайти максимальний елемент і вивести в один рядок всі числа, розташовані до нього, а числа, розташовані після нього – в інший рядок.

21. Заповнити квадратну матрицю (багатовимірного вектора) 8x8 елементів одиницями в шаховому порядку.

22. Знайти суму парних елементів багатовимірного вектора V[4][4], розташованих нижче головної діагоналі.

23. Знайти добуток додатних елементів другого рядка (вектора) матриці (багатовимірного вектора) V[4][4] і кількість всіх від’ємних елементів.

24. Всі елементи вектору V[25], що зустрічаються більше одного разу переписати в інший вектор.

25. У векторі V[23] числа, що знаходяться між максимальним і мінімальним елементами, помістити в інший вектор.

26. Задані два вектори G[15] та H[10]. Сформувати вектор, що складається з однакових елементів цих векторів.

27. Знайти суму непарних елементів багатовимірного вектора V[4][4], розташованих вище головної діагоналі.

28. Відсортувати елементи побічної діагоналі матриці (багатовимірного вектора) 6x6 елементів за зростанням.

29. Змінити місцями задані в діалозі рядки матриці (багатовимірного вектора).

30. Піднести до квадрата всі від’ємні елементи багатовимірного вектора B[6][6] і витягти корінь з усіх додатних.

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

1. Які форми доступу до елементів масиву передбачені синтаксисом мови С++?

2. Які передбачені засоби ініціалізації векторів?

3. Якою вимірності можуть бути вектори?

4. Чи можуть бути проголошені масиви без вказівки кількості елементів?

5. Чи може масив містити елементи різноманітних типів?

6. Чи передбачений контроль кількості елементів масиву?

7. Який зв'язок між масивами і покажчиками?