- •Int main() /* головна обов’язкова функція, де ключове слово int означає, що функція main() повертатиме у точку виклику результат цілого типу*/ 6
- •Засоби розробки с програм
- •Директиви препроцесора.
- •Using namespace std; // вказуємо, що будемо працювати з іменами із стандартної бібліотеки
- •Запитання
- •Тема 2. Данні
- •Команда присвоєння. Правила узгодження типів.
- •Запитання
- •Тема 3. Операції та вирази
- •Тема 4. Потоки. Введення - виведення даних
- •Форматування даних
- •Введення-виведенні засобами бібліотеки сstdіo
- •Тема 5. Адреси даних. Вказівники. Динамічна пам’ять
- •Тема 6. Файли
- •Тема 7. Розгалуження
- •Логічні вирази та логічні операції.
- •Команда ?
- •Тема 8. Цикли
- •Команда циклу з післяумовою do-while має вигляд
- •Тема 9. Функції (1)
- •Тема 10. Функції (2)
- •Тема 11. Масиви
- •Тема 12. Рядки
- •Тема 13. Структури, списки, стеки, черги, об’єднання
- •Тема 14. Виняткові ситуації
- •Http://www.Rate1.Com.Ua/strannosti/2633/ Самі фатальні помилки в програмному забезпеченні
- •Помилки під час виконання (виняткові ситуації, виключення) Exceptions - це помилки, що виникають у випадку, коли програма намагається виконати неприпустиму операцію.
- •Тема 15. Графіка
- •Написание простых графических программ
- •Http://www.Rsdn.Ru/article/opengl/ogltut2.Xml Графическая библиотека OpenGl
Тема 10. Функції (2)
Глобальні та локальні змінні. Операція видимості. Під час оголошення змінних в оперативній пам’яті комп’ютера резервується місце для зберігання їхніх значень. Обсяг наданої пам’яті залежить від типів змінної та компілятора. Кожна змінна характеризується:
областю дії - це частина програми, де змінна придатна для повноцінного опрацювання.
областю видимості - це частина програми, де змінна оголошена або, де до неї можна отримати доступ за допомогою операції надання видимості, що позначається
Області дії та можливої видимості, час дії змінної у певній програмі залежать від того, де і як оголошені змінні.
Змінні можна оголошувати
у блоці команд,
у тілі деякої функції
поза всіма функціями (глобальні змінні).
Локальними називаються змінні, які оголошені у тілі деякої функції або у блоці. Область дії локальних змінних поширюється лише на відповідну функцію чи блок. Під час виходу із функції (блока) частина оперативної пам’яті, відведеної під локальні змінні, вивільняється, тобто закінчується область дії змінної. Тому у різних функціях можна використовувати змінні з однаковими іменами.
Приклад 1. Скласти програму з використанням функції, яка знаходить максимальне серед трьох введених чисел.
#include <iostream>
#include <conio.h>
using namespace std;
float Max(float, float, float); //Оголошення функції
int main()
{
//float max, х1, х2, х3; // Оголошення змінних
float max, x1, x2,x3;
cout<< "Уведіть три числа \n";
cin>> x1>> x2>> x3;
max = Max(x1, x2, x3); // Обчислюємо максимальне серед уведених чисел
cout<< "\n Максимальним серед чисел " << x1 << ", " << x2 <<", " << x3;
cout <<" є "<< max;
getch();
}
// ----------------------------------------------------------------
float Max(float a, float b, float c)// Опис функції Max
{
float max;
if (a > b && a > c) max = a;
else if (b > a && b > c) max = b;
else max =c;
return max;
}
Зауважимо, що у цій програмі змінна max оголошена відразу у двох функціях main() і Мах().
Глобальними називають змінні, які описані поза всіма функціями, тобто на початку програми або у файлі заголовка. Вони видимі та доступні під час виконання всієї програми. До таких змінних можна звернутись з будь-якої функції чи блока.
Функція може повертати значення у основну програму за допомогою команди return, вказівників, посилань або через глобальні змінні. Значення глобальних змінних можна змінювати у тілі функцій. З огляду на це у великій програмі важко проаналізувати значення глобальної змінної на певному етапі її виконання. Тому варто якомога менше використовувати глобальні змінні, бо це ускладнює розуміння програми.
Деяка змінна може бути доступною, але в певний момент невидимою. Наприклад, якщо глобальна та локальна змінні мають однакове ім’я, то глобальна змінна у області дії відповідної локальної змінної буде невидимою. Тобто локальна змінна в області своєї визначеності перекриває дію глобальної змінної. Для того, щоб звернутись (доступитись) до глобальної змінної у деякому блоці чи функції, використовують операцію надання видимості. У цьому випадку до імені змінної зліва дописують два символи двокрапки.
Наприклад, ::prybutok, ::day тощо.
Приклад 2. Відомо, що потяг проїхав 5 (k) станцій зі сталою швидкістю v км/год. Час, затрачений на переїзд між станціями, та швидкість потягу треба ввести з клавіатури у режимі діалогу. Використовуючи функцію, визначити загальний шлях, який пройшов потяг, і відстані між станціями,
#include <iostream> // Про локальні та глобальні змінні
#include <conio.h>
using namespace std;
float d = 0; // Оголошення глобальної змінної d
int main()
{
int k = 5; float v, t;
cout << "Уведіть швидкість потягу \n";
cin>> v;
for (int n = 1; n <= k; n++)
{
cout << "Уведіть час, який затратив потяг на переїзд між зупинками "<<n <<" та " << (n+1) << "\n";
cin >>t;
float d; // Оголошення локальної змінної d
d = t * v;
cout << "Відстань від станції" << n<< " до "<< (n+1) << " є " << d <<" км"<< "\n";
::d = ::d + d; // Звертання до глобальної змінної
}
cout <<"\n Загальний шлях " << d << " км";
}
У цьому випадку змінна d, яка оголошена на початку прогрими, є глобальною. У блоці команди for оголошена локальна змінна d.
Зауваження 1. Для динамічних змінних не діють правила видимості та доступності. Динамічні змінні видимі та доступні у всіх функціях та блоках програми протягом усього часу їх визначеності.
Класи пам’яті. Для того, щоб безпосередньо вказати комп’ютеру як і де у його пам’яті мають зберігатися значення змінних чи функцій, як можна отримати доступ до цих даних, як визначити область видимості цих даних, використовують специфікатори класу пам’яті. Є п’ять специфікаторів (табл. 9).
Таблиця 9. Класи пам’яті
Клас пам’яті |
Час дії змінної |
Області видимості та дії змінної |
auto |
Тимчасово |
Локальна |
register |
Тимчасово |
Локальна |
extern |
Тимчасово |
Локальна |
static |
Постійно |
Локальна |
static |
Постійно |
Глобальна |
volatile |
Постійно |
Глобальна |
Розглянемо дії цих специфікаторів.
Специфікатор auto для локальних змінних застосовується за замовчуванням, тому зазначати його не обов’язково. Область видимості таких змінних обмежена блоком, у якому вони оголошені. Під час виходу з блока пам’ять, яка відведена для цих змінних, автоматично вивільняється, а змінні знищуються.
Специфікатор register вказує компілятору, що значення змінної слід зберігати у регістрах. Це зменшує час доступу до змінної і прискорює виконання програми. Якщо не можливо розмістити змінну у регістрі, то змінна буде збережена зі специфікатором auto. Області дії та видимості регістрових змінних, як і змінних зі специфікатором auto, обмежені блоком, у якому вони оголошені.
Специфікатор static можна застосовувати як до локальних, так і до глобальних змінних. На відміну від змінних зі специфікаторами auto чи register значення локальної статичної змінної зберігається після виходу з блока чи функції, де ця змінна оголошена. Під час повторного виклику функції змінна зберігає своє попереднє значення. Якщо змінна явно не ініціалізована, то за замовчуванням їй надається значення 0.
Приклад 3. Обчислити суму або добуток перших n цілих додатних чисел.
Обчислимо спочатку суму чисел.
// Обчислення суми
#include <iostream>
#include <conio.h>
using namespace std;
int cc(int n);
int main()
{
int n, S;
cout << "Уведіть число";
cin>> n;
for(int i=1;i<= n;i++)
S = cc(i);
cout << S;
getch();
}
//--------------------------------
int cc(int n)
{
static int S = 0;
S += n; return S;
}
Функція сс призначена для обчислення суми чисел. Якщо ж потрібно обчислити добуток чисел, то фунція таіп() залишиться без змін, а замість функції сс слід записати таку функцію:
іnt cc(int n)
{
static int S = 1;
S *= n; return S;
}
Глобальні статичні змінні ініціалізуються під час запуску програми. Області їх дії та видимості розповсюджуються лише на той файл, де оголошена ця змінна.
Часто, якщо програма складається з декількох файлів, виникає потреба передавати значення змінних з одного файлу в інший. У такому випадку до змінної застосовують специфікатор extern. Він дає змогу оголошувати глобальні змінні, дія яких поширюється на всі файли, з яких складається програма.
Специфікатор volatile застосовують до глобальних змінних, значення яких можуть надходити від периферійних пристроїв, наприклад, якщо змінна набуває значення від системного таймера.
Перевантаження функцій. Перевантаженням функцій, або поліморфізмом називається використання одного і того ім’я функції для різних наборів аргументів. Перевантаження використовують, поли необхідно викликати функцію з аргументами різних типів, або коли функція залежить від різної кількості аргументів. У таких випадках необхідно кожну функцію оголосити й описати окремо. Під час її виклику компілятор автоматично проаналізує сигнатури та виконає код відповідної функції.
Приклад 4. Використовуючи перевантаження функції, написати програму для упорядкування трьох уведених даних або символьного, або цілого типу.
#include <iostream>
using namespace std;
void Sort(int n1, int n2, int n3);
void Sort(char n1, char n2, char n3);
int main()
{
int i1, i2, i3, k;
char c1, c2, c3;
cout<< "Уведіть 1 для впорядкування cимволів, 2 - для чиcел\n";
cin>>k;
if (k ==1)
{
cout<< "Уведіть три cимволи";
cin>> c1 >> c2 >> c3;
Sort(c1,c2,c3);
}
if (k == 2)
{
cout<< "Уведіть три чиcла";
cin>> i1 >> i2>> i3;
Sort(i1,i2,i3);
}
}
// -----------------------------
void Sort(int n1, int n2, int n3)
{
int c;
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
if (n2 > n3) {c = n2; n2 = n3; n3 = c;}
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
cout << n1 << "\t" << n2 << "\t" << n3;
}
//---------------------------------
void Sort(char n1, char n2, char n3)
{
char c;
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
if (n2 > n3) {c = n2; n2 = n3; n3 = c;}
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
cout << n1 << "\t" << n2 << "\t" << n3;
}
Зауваження 2. Для функцій, які відрізняються типом значення, яке вони повертають, і мають однаковий набір аргументів, перевантаження у мові C++ не визначено, тобто їм надавати однакові імена не можна.
4. Шаблони функцій. Перевантаження функцій, часто буває корисним, але не завжди зручним. Як видно, один і той самий програмний код довелося записувати окремо для змінних символьного типу, а потім для цілих чисел. У мові C++ є змога уникнути таке дублювання за допомогою шаблонів.
Шаблон функції - цe опис функції, яка залежить від даних довільного типу. Крім того, така функція може повертати в основну програму результат довільного типу. Тобто користувач створює сигнатуру й описує функцію з аргументами деякого загального типу. Під час виклику такої функції компілятор автоматично проаналізує тип фактичних аргументів, згенерує для них програмний код і виконає відповідні дії. Це називається неявним створенням екземпляра шаблона. Такий підхід у програмуванні називається узагальненим програмуванням, оскільки він дає змогу створити функцію узагальненого типу. Сигнатуру шаблону функції можна описати так:
template <class <назва узагальненого типу>>
<тип функції> <назва функції>(<список формальних параметрів>);
У списку формальних параметрів замість стандартних конкретних типів даних зазначають назву узагальненого типу. Правила для описування шаблона функції такі самі, як і для функції користувача.
Зауваження 3. У стандарті ISO/ANSI замість ключового слова class прийнято записувати typename.
Якщо для деякого типу даних функцію необхідно описати окремо, то створюють явну специфікацію функції. Тоді у списках формальних параметрів шаблона зазначають конкретні типи аргументів.
Приклад 5. Переробимо програму з прикладу 4 для упорядкування трьох введених даних заздалегідь невідомого типу, використовуючи шаблони.
#include <iostream>
using namespace std;
template <class Mytype> // Оголошення шаблона функції
void Sort(Mytype nl, Mytype n2, Mytype n3);
int main()
{
int i1, i2, i3, k;
char c1, c2, c3;
cout<< "Уведіть 1 для впорядкування cимволів, 2 - для чиcел\n";
cin>>k;
if (k ==1)
{
cout<< "Уведіть три cимволи";
cin>> c1 >> c2 >> c3;
Sort(c1,c2,c3);
}
if (k == 2)
{
cout<< "Уведіть три чиcла";
cin>> i1 >> i2>> i3;
Sort(i1,i2,i3);
}
}
// -----------------------------
template <class Mytype> // Опис шаблона функції
void Sort(Mytype n1, Mytype n2, Mytype n3)
{
Mytype c;
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
if (n2 > n3) {c = n2; n2 = n3; n3 = c;}
if (n1 > n2) {c = n1; n1 = n2; n2 = c;}
cout << n1 << "\t" << n2 << "\t" << n3;
}
Вбудовані функції. Під час виконання програми генеруються коди для всіх функцій користувача. Коли відбувається звертання до тієї чи іншої функції, здійснюється виклик відповідного коду. Якщо до деякої функції звертаються багато разів, то робота програми сповільнюється. Щоб цього уникнути, можна використовувати так звані вбудовані функції. Коди таких функцій вставляються компілятором у кожну точку виклику в основному коді. Це вимагає додаткового обсягу оперативної пам’яті, проте прискорює процес виконання програми. Щоб створити вбудовану функцію, потрібно до її оголошення додати ключове слово inline.
Приклад 6. Використовуючи вбудовані функції, скласти програму для обчислення добутку
Використання
функції тут має ілюстративний характер.
#include <iostream> // Вбудовані функції
#define N 10
using namespace std;
inline float dob(int a);
int main()
{
float D;
for (int k = 1; k <= N; k++)
D = dob(k);
cout << "Добуток дорівнює = " << D;
}
//------------------------------------------------------------
float dob(int a)
{
static float d = 1;
d = d * (5*a + 2) / (a - 15);
return d;
}
Виконавши програму, одержимо значення добутку 28380,5.
Функція main() з параметрами.
Функція main() є у кожній програмі і виконує
керування програми після запуску
повертає значення в систему
приймає параметри із зовнішнього оточення
Стандарт передбачає два формати функції: // Без параметрів: int main ( )
{ / * ... * /}
// З двома параметрами : int main ( int argc, char * argv [])
{ / * ... * /}
Параметри називаються аргументами командного рядка. їх зазначають під час запуску програми (ехе-файлу) у командному рядку операційної системи.
Параметри функції main ( ) служать для передачі програмі аргументів командного рядка, тобто імен файлів, ключів, опцій і взагалі всього, що ви вводите з клавіатури після підказки DOS, запускаючи програму. При запуску програми з командного рядка параметри розділяються пробілами. Імена параметрів у програмі можуть бути будь-якими, але прийнято використовувати argc і argv .
Перший параметр argc визначає кількість параметрів, що передаються функції, включаючи ім'я самої програми,
другий параметр argv це вказівник на масив символьного типу. Кожен елемент масиву містить вказівник на окремий параметр командного рядка, що зберігається у вигляді С- рядка, що кінчається нуль- символом . Перший елемент масиву argv [ 0 ] посилається на повне ім'я файлу, що запускається на виконання, наступний argv [ l ] вказує на перший параметр, argv [2] - на другий параметр, і так далі. Параметр argv [ argc ] повинен бути рівний 0 .
в залежності від компілятора може бути ще один параметр env[], що служить для передачі параметрів для операційної системи, у якій виконується програма. Його використовують, наприклад, тоді, коли програму потрібно виконати в різних операційних системах.
Розглянемо приклад програми, яка роздруковує всі параметри програми main ( ), зазначені при виклику .
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
for (int i = 0; i<argc; i++)
cout << argv[i] << "\n";
}
Приклад 7. Нехай треба знайти мінімальне або максимальне значення функції у = х2 sinx, де х змінюється на проміжку [1; 2] з кроком h — 0,1.
#include <iostream> // Використання функції main() з параметрами
#include <conio.h>
#include <process.h> //для функцію exit(), яка дає змогу достроково завершити програму
#include <math.h>
#define h 0.1
#define b 2
using namespace std;
float Min(float y);
float Max(float y);
int main(int argc, char *argv[])
{
if (argc < 2) // Якщо параметр не задано
{
cout<< "Недостатньо аргументів \n";
cout<<"Уведіть параметр min або max";
exit (1); // Достроково виходимо з програми
}
float x,y;
cout << " X \t Y \n"; // Табyлюємо фyнкцію
for(x=1;x<=b;x+=h)
{
y=x*x*sin(x);
cout << x << "\t" << y << "\n";
}
// Перевіримо, чи другий параметр є min
if (*argv[1] == 'm' && *(argv[1]+1) == 'i' && *(argv[1]+2) == 'n')
cout << "Min = " << Min(y);
else
// Перевіримо, чи дрyгий параметр є max
if (*argv[1] == 'm' && *(argv[1]+1) == 'a' && *(argv[1]+2) == 'x')
cout << "Max = " << Max(y); else cout << "Параметр не визначено"; getch(); return 0;
}
// -----------------------------------------
float Min(float y)
{
float x= 1, m;
m = x * x * sin(x);
for ( ; x <= 2; x += h)
{
y = x * x * sin(x); if (m > y) m = y;
}
return m;
}
// ---------------------------------------
float Max(float y)
{
float x = 1, m;
m = x * x * sin(x);
for ( ; x <= 2; x += h)
{
y = x * x * sin(x); if (m < y) m = y;
}
return m;
}
Вправи
Наведіть приклади оголошення глобальних і локальних змінних.
Використовуючи перевантаження функцій, складіть програму для обчислення мінімального з п’яти введених даних. Дані можуть бути цілого або дійсного типів.
Використовуючи перевантаження функцій, складіть програму для обчислення добутку семи введених даних. Дані можуть бути цілого або дійсного типів.
Використовуючи шаблон, складіть функцію для визначення кількості введених із клавіатури даних (чисел чи символів) із заданого діапазону. Введення даних організуйте за допомогою команди циклу.
Використовуючи inline-функції, складіть програму для обчислення максимального з шести введених цілих чисел.
Наберіть програму з прикладу 6 у середовищі C++, збережіть її у своїй робочій папці, наприклад d:\lab\program.cpp. Виконайте програму і вийдіть із середовища. Введіть у командному рядку Windows або програм FAR, Windows Commander тощо послідовно команди
d:\lab\program.exe «Натисніть на клавішу вводу> d:\lab\program.exe min «Натисніть на клавішу вводу>
d:\lab\program.exe max «Натисніть на клавішу вводу> d:\lab\program.exe kil «Натисніть на клавішу вводу>
Які результати ви отримали? Занотуйте їх у звіт.
Модифікуйте програму з прикладу 6 так, щоб однією командою з командного рядка можна було знайти максимальне і мінімальне значеній! або лише одне з них.
Складіть програму для розв’язування задачі № 8 вашого варіанти, використовуючи функції, локальні та глобальні змінні.
Виконайте завдання № 8 вашого варіанта, використавши функцію main() з параметрами.
1.3.3, 1.3.4
1.5.
1.6
1.12
5.31.random
13.2.template function
