07 Localisation

Preview:

Citation preview

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

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

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

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

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

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

2

Види імен

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

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

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

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

3

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

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

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

© Бублик В.В. Програмування-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;• };

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

5

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

// root.h

• double root (double x, double eps);

© Бублик В.В. Програмування-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;• }

© Бублик В.В. Програмування-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;• }

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

8

Омоніми

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

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

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

9

Видимість

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

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

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

10

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

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

© Бублик В.В. Програмування-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, оскільки вони

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

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

12

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

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

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

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

13

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

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

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

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

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

© Бублик В.В. Програмування-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);

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

15

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

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

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

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

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

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

16

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

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

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

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

17

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

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

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

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

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

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

Point sum (Point a, Point b);

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

18

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

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

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

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

19

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

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

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

20

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

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

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

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

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

21

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

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

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

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

© Бублик В.В. Програмування-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;

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

23

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

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

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

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

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

24

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

• int x = 1;

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

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

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

25

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

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

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

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

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

26

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

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

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

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

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

27

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

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

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

© Бублик В.В. Програмування-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;• }

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

29

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

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

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

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

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

30

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

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

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

© Бублик В.В. Програмування-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;

© Бублик В.В. Програмування-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);

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

33

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

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

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

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

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

© Бублик В.В. Програмування-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;

© Бублик В.В. Програмування-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;

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

36

Вибір імен

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

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

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

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

37

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

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

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

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

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

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