НОУ ІНТУІТ, Лекція, Функції
Модульне програмування
Зі збільшенням обсягу програми стає незручно зберігати в одному файлі. Розбиття програми на функції є першим кроком у підвищенні рівня абстракції програми, наступний - угруповання функцій та пов'язаних з ними даних в окремі файли (модулі), що компілюються окремо.
Об'єктні модулі, що виявилися в результаті компіляції, об'єднуються у виконувану програму за допомогою компонувальника. Розбиття на модулі зменшує час перекомпіляції та полегшує процес налагодження. Чим незалежніші модулі, тим легше налагоджувати програму.
Модуль містить дані та функції їх обробки. Для того щоб використовувати модуль, потрібно знати лише його інтерфейс.Інтерфейсом модуляє заголовки всіх функцій та описи доступних ззовні типів, змінних та констант. Описи глобальних програмних об'єктів у всіх модулях програми мають бути узгоджені.
Модульність у мові С++ підтримується за допомогою директив препроцесора, просторів імен, класів пам'яті, винятків та роздільної компіляції.
Директиви препроцесора
Препроцесор називається перша фаза компілятора. Інструкції препроцесора називають директивами. Вони повинні починатися з символу #, перед яким у рядку можуть знаходитись лише пробілові символи .
Директива #include
Директива# include вставляє вміст зазначеного файлу в ту точку вихідного файлу, де вона записана. Файл також може містити директиви # include .
Пошук файлу, якщо не вказано повний шлях, ведеться в стандартних каталогах файлів, що включаються. Замість кутових дужок можуть використовуватися лапки (" ") - у цьому випадку пошук файлу ведеться в каталозі, що містить вихідний файл, а потім вже в стандартних каталогах.
У заголовному файлі не повинно бути визначень функцій та даних.
Директива #define
Директива# define визначає підстановку у тексті програми. Вона використовується для визначення:
- символічних констант. Формат визначення символічної константи:
Параметри використовуються при макропідстановці, наприклад, якщо текст програми використовується виклик макросу y = MAX(sum1, sum2); , він буде замінений на
Використання макросів та символічних констант у програмах слід уникати.
Області дії ідентифікаторів
Блок. Ідентифікатори, описані всередині блоку, локальні. Область дії ідентифікатора починається в точці визначення та закінчується в кінці блоку, видимість – у межах блоку та внутрішніх блоків, час життя – локальне. Після виходу із блоку пам'ять звільняється.
Файл. Ідентифікатори, описані поза будь-яким блоком, функцією, класом або простором імен, мають глобальну видимість і час життя і можуть використовуватися з моменту їх визначення.
Функція. Єдиними ідентифікаторами, що мають таку область дії є мітки операторів. В одній функції всі мітки повинні відрізнятися, але можуть збігатися з мітками інших функцій.
Клас. Елементи структур, об'єднань і класів (крім статичних елементів ) є видимими лише межах класу. Вони утворюються під час створення змінної зазначеного типу і руйнуються за її знищенні.
Названа область. С++ дозволяє явно задати область визначення імен як частину глобальної області за допомогою оператора namespace .
Область видимості збігається з областю дії крім ситуації, коли у вкладеному блоці описаназмінна з таким самим ім'ям. І тут зовнішня змінна у вкладеному блоці невидима, хоча і входить у її область дії . Проте до цієї змінної, якщо вона глобальна, можна звернутися за допомогою операції доступу до області видимості . Спосіб звернутися до прихованої локальної змінної відсутній.
У кожній області дії розрізняють про простори імен.Простір імен- область, у межах якої ідентифікатор має бути унікальним. У різних просторах імена можуть збігатися, оскільки дозвіл посилань здійснюється за контекстом ідентифікатора у програмі, наприклад:
В даному випадку суперечності немає, оскільки імена типу, змінної та елемента структури відносяться до різних просторів. У С++ визначено чотири роздільні класи ідентифікаторів.
- До одного простору імен відносяться імена змінних, функцій, типів, визначених користувачем (typedef) і констант перерахувань в межах однієї області видимості. Усі вони, крім імен функцій, можуть бути перевизначені у вкладених блоках.
- Інший клас імен утворюють імена типів перерахувань, структур, класів та об'єднань. Кожне ім'я повинне відрізнятися від імен інших типів у тій самій області видимості.
- Окремий клас складають елементи кожної структури, класу та об'єднання. Ім'я елемента має бути унікальним усередині структури, але може збігатися з іменами елементів інших структур.
- Мітки утворюють окремий простір імен.
Будь-якафункціяавтоматично помітна у всіх модулях програми. Якщо потрібно обмежити дію функції файлом, в якому вона описана, використовується модифікатор static .
Для того щоб зробити доступною в декількох модуляхзмінну або константу,необхідно:
- визначити її рівно в одному модулі як глобальну;
- в інших модулях оголосити її як зовнішню за допомогою модифікатора extern.
Всі описи однієї і тієї ж змінної повинні бути узгоджені.
Приклад опису двох глобальних змінних у файлах one. cpp та two. cpp за допомогою заголовкового файлу my_header.h :
Якщо змінна описана як static, область її дії обмежується файлом, у якому вона описана.
Названі області
Оголошення названої області (її також називають простором імен) має формат:
Якщо ім'я області не встановлено, компілятор визначає його самостійно за допомогою унікального ідентифікатора, різного для кожного модуля. Оголошення об'єкта в непойменованій області рівнозначне його опису як глобального з модифікатором static.
Не можна отримати доступ з одного файлу до елемента неназваної області іншого файлу.
Це застосовується для поділу інтерфейсу та реалізації. У такий спосіб не можна оголосити новий елемент простору імен.
Якщо ім'я часто використовується поза своїм простором, можна оголосити його доступним за допомогою оператора using :
Після цього можна використовувати ім'я без явної вказівки області.
Якщо потрібно зробити доступними всі імена з будь-якої області, використовується оператор using namespace :
Простір імен стандартної бібліотеки
Це забезпечує сумісність згори донизу. Для тих, хто не бажає присутності неявно доступних імен, визначено новий заголовний файл:
Якщо у програму включений файл, потрібно вказувати ім'я простору імен явно:
Механізм просторів імен разом з директивою #include забезпечують необхідну при написанні великихпрограм гнучкість шляхом поєднання логічного групування пов'язаних величин та обмеження доступу до непотрібних засобів.