37
Бублик Володимир Васильович Програмування - 2 Лекція 7. Процедурне програмування. Області видимості в програмі Лекції для студентів 2 курсу

07 Localisation

Embed Size (px)

Citation preview

Page 1: 07 Localisation

Бублик Володимир Васильович

Програмування - 2

Лекція 7. Процедурне програмування.

Області видимості в програмі

Лекції для студентів 2 курсу

Page 2: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

2

Види імен

• Імена об'єктів• Імена типів (структур, класів)• Імена функцій

Кожне ім'я має унікальну інтерпретацію в межах своєї області видимості, яка може складатися з кількох файлів, кожен з яких може компілюватися окремо

Для забезпечення можливості осібної компіляції до файлу з текстом програми (.cpp) додаються заголовні файли (.h), в яких пояснюються (оголошуються) імена, необхідні для компіляції цього файлу

Page 3: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

3

Визначення і оголошення

• Визначення приводить до створення об'єктуВизначення розміщують в .cpp файлахНа підставі визначення будується об'єктний код побудови об'єкту

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

Page 4: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

4

Визначення функції root.cpp

• double root (double x, double eps)• {• double s=0.5*x;• double t;• do• {• t=s;• s=(s+x/s)*0.5;• }• while ((fabs(s-t)/s)>eps);• return s;• };

Page 5: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

5

Оголошення функції root

// root.h

• double root (double x, double eps);

Page 6: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

6

Використання функції root

• int main (int argc, char* argv[])• {• const double two=2.0;• const double prec = 0.000001;• cout.precision(17);// Де взяти інформацію про типи параметрів і

результату?• cout << root (two, prec)<<endl;• return 0;• }

Page 7: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

7

Використання функції root

#include "root.h“

• int main (int argc, char* argv[])• {• const double two=2.0;• const double prec = 0.000001;• cout.precision(17);// З файлу root.h• cout << root (two, prec)<<endl;• return 0;• }

Page 8: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

8

Омоніми

Чи може ім'я root використовуватися в програмі за іншим призначенням?

Так, в іншій області видимості

Page 9: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

9

Видимість

• Глобальна область видимості (вся програма)• Простори імен • Локальна область видимості

– блок,– функція,– файл,– клас (з'явиться пізніше)

Page 10: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

10

Глобальна область видимості

Глобальна область видимості об'єкти, функції і типи, визначені за межами блоків будь-якого типу

Page 11: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

11

Глобальні визначення

//unit1.cpp• int g_Var = 20; //Визначення глобальної

змінної

• void f(void) //Визначення функції• {• cout<<"I am f () from unit1 and I see g_Var=";• cout<<g_Var<<endl;• return;• }Функція void f(void) бачить змінну g_Var, оскільки вони

визначені в одному файлі

Page 12: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

12

Доступ до глобальних імен і функцій

Як відкомпілювати програму, що використовує глобальні об'єкти з іншого файлу? Як дати функції int main() можливість побачити змінну g_Var?

//unit2.cpp• int main()• {• cout<<g_Var<<endl; //Як використати змінну• f(); // g_Var з unit1.cpp?• return 0;• }

Page 13: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

13

Заголовний файл

Для розповсюдження інформації про об'єкти, визначені у файлі unit1.cpp, створюємо заголовний файл

//unit1.h// Оголошення глобальних об'єктів• void f(void);• extern int g_Var;

Оголошення функції відрізняється від визначення відсутністю її тіла.

Щоб відрізнити оголошення змінної від її визначення додають ключове слово extern

Page 14: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

14

Використання оголошень

//unit2.cpp• #include “unit1.h"// #include “unit1.cpp“// чому не коректно приєднувати текст .cpp файлу?• int main()• {• cout<<g_Var<<endl; //Використано

оголошення• f(); //з unit1.h• return 0;• }

extern int g_Var;void f(void);

Page 15: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

15

Глобальні типи

Де розміщувати визначення структур?

• struct Point • {• double _x, _y;• };

1. Якщо безпосередньо в .cpp файлі, то як дати доступ до цього визначення з різних файлів?

2. Якщо в заголовному файлі .h, то як усунути повторні визначення при приєднанні одного заголовного файлу до різних .cpp файлів?

Page 16: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

16

Захист заголовного файлу

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

//File Point.h#ifndef _POINT_H_#define _POINT_H_• struct Point • {• double _x, _y;• };#endif

Page 17: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

17

Оголошення типів

Чи всі програмні файли потребують визначення структури і відповідного #include? ― Ні, часом досить лише оголошення структури

Часто #include в іншому заголовному файлі недоречний (доробка на майбутнє)

//Some.hstruct Point; //оголошення структури

//досить для указника без ініціалізаціїPoint * p;

//досить для оголошення функції без виклику

Point sum (Point a, Point b);

Page 18: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

18

Простір імен. Оголошення

Простір імен дає можливість зібрати пов'язані між собою позначення в одному місці та відрізняти їх від інших імен з глобального контексту

//File.h• void f(void);• namespace myNames• {• void f(void);• void g(void);• }Тут присутні дві різні функції void f(void)

Page 19: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

19

Визначення елементів простору імен

//File.cpp• void f(void)• {• cout<<"I am global";• return;• }• void myNames::f(void)• {• cout<<"I am f from myNames";• return;• }

Page 20: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

20

Операція розв'язання області видимості

//Source.cpp• #include "File.h "

• int main()• {• f(); //взяти f з глобального

контексту• myNames::f(); //взяти f з простору myNames• myNames::g(); //взяти g з простору myNames• return 0;• }

Page 21: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

21

Приєднати простір імен

//Source.cpp• #include "File.h "• using namespace myNames;

• int main()• {• ::f(); //взяти f з глобального

контексту• myNames::f(); //взяти f з простору myNames• g(); //взяти g з простору myNames• return 0;• }

Page 22: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

22

Стандартний простір імен std

Стандартний простір імен містить визначення імен і типів

Наприклад,• cin, сout, endl• istream, ostreamЇх можна вживати через операцію розв'язання області дії• std::сout, std:: endl• std:: ostream, std:: istreamНаприклад,std::cout<<"x="<<x<<std::endl;Можна приєднати простір іменusing namespace std;

Page 23: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

23

Локальна область видимості

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

Деякі імена з ширшого контексту при цьому можуть затінятися локальними іменами.

Погодження. Локальні області видимості не можуть містити визначень функцій, але можуть містити визначення типів даних

Page 24: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

24

Розв'язання глобальної області видимості

• int x = 1;

• int main()• {• int x = 2;• cout<<"x="<<x<<endl; //локальна х• cout<<"::x="<<::x<<endl; //глобальна х• return 0;• }Локальна змінна затіняє однойменну змінну з

ширшого контексту. Розв'язання (доступ до глобальної) можливе

Page 25: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

25

Глобальні об'єкти

Рекомендується уникати глобальних об'єктів (чому?), але глобальні сталі абсолютно правомірні

Визначення//some.cppconst float pi = 3.14159;

Оголошення//some.hextern const float pi;

Page 26: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

26

Вкладені блоки

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

Чим вужча область видимості кожного об'єкту, тим краще

• double x, y;……………………• if (x>y)• {• double z = x; x=y; e=z;• } • cout<<z; //ERROR: undeclared identifier

Page 27: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

27

Вкладені блоки

• int main()• {• int x = 1;• {• int x = 2;• cout<<"x="<<x<<endl; //синя х• }• cout<<"x="<<x<<endl; //зелена х• return 0;• }Внуьтрішня змінна затіняє однойменну локальну

змінну з ширшого контексту. Розв'язання неможливе

Page 28: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

28

Область видимості функції

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

• const int n=10;• double prod(double x[], double y[])• { //{n} + {x, y, sum} + {i}• double sum = 0;• for (int i=0; i<n; i++)• sum += x[i]*y[i];• return sum;• }

Page 29: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

29

Файл як область видимості

Можна обмежити видимість об'єктів .cpp файлом, у якому вони визначені. Такі об'єкти називають статичними

//some.cppstatic unsigned currentID = 0;void increaseID(){ ++currentID; return;}

int getFreeID(){ increaseID(); return currentID; }

Page 30: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

30

Персистентність

Персистентність визначає тривалість життя об'єктів від моменту зв'язування до моменту видалення

Зв'язування об'єкту з його значенням• раннє (статичне)• пізнє (динамічне)

Page 31: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

31

Статичне зв'язування

При складанні програми• константи препроцесора (уникаємо їх – чому?)

#define PI 3.14159• ім'я функції з її тілом

void f() { cout <<« I am f()"<<endl; return; }

При компіляції• іменовані константи

const float pi = 3.14159;• глобальні і статичні змінні

static unsigned int currentID = 0;

Page 32: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

32

Динамічне зв'язування

• Після входу в блок{ double z=x; x=y; y=z;}

• При виклику функціїu = root (v, e);// double x = v, double eps = e

• При виділенні пам'ятіint * p = new int (1);

Page 33: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

33

Тривалість життя

• Локальні об'єкти живуть до кінця виконання блоку чи функції (в стеку)

• Створені програмою (за допомогою new) об'єкти живуть, доки їм дозволяє програма (видалення за допомогою delete) (в купі, in heap)

• Глобальні і статичні об'єкти живуть до кінця виконання програми

• Постійні об'єкти можуть зберігатися у файлах (базах даних) і жити вічно

Page 34: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

34

Призначення об'єктів

Кожній змінній ― одне призначення//Багатоцільові змінні ознака кепського тону!• temp = sqrt(b*b – 4*a*c)• root[0] = (-b -temp)/(2*a);• root[1] = (-b+temp)/(2*a);• …………………….• temp = root[0];• root[0] = root[1];• rout[1] = temp;

Page 35: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

35

Призначення об'єктів

Кожній змінній ― одне призначення//Добре• double discriminant = sqrt(b*b – 4*a*c)• root[0] = (-b - discriminant)/(2*a);• root[1] = (-b+ discriminant)/(2*a);• …………………….• double replacer = root[0];• root[0] = root[1];• rout[1] = replacer;

Page 36: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

36

Вибір імен

1. Ім'я повинно виражати суть об'єкту2. Чим ширша область видимості об'єкту, тим

важливіша виразність його імені. Імена виду x, i, k, тощо, якщо вживаються, то вказують на те, що їх область видимості кілька рядків

Приклади• currentDate, linesPerPage• done, found

Page 37: 07 Localisation

© Бублик В.В. Програмування-2. 7. Процедурне програмування. Видимість

37

Дисципліна іменування

Корисно називати об'єкти так, щоб ім'я виражало його роль. Корисно розрізняти

• імена типів, наприклад, size_t• імена структур і класів ― зазвичай з великої

літери, наприклад, Point, Collection• імена членів структур, наприклад, _x• імена констант, наприклад, LOCAL_CONSTANT,

kConst• глобальні імена, наприклад, gThisGlobal

Особливо важлива дисципліна іменування у великих проектах