Препроцесор С/С++ — програмний інструмент, який використовується в мовах програмування C та C++, препроцесор, що змінює код програми для подальшої компіляції й збірки.
Мова препроцесора C/C++ не є повною за Тюрінгом хоча б тому, що за допомогою директив неможливо змусити препроцесор «зависнути».
Директиви
Директивою препроцесора називається рядок у коді, який має такий вигляд #ключове_слово параметри. Є чітко визначений список ключових слів: define — Задає макровизначення (макроси) або константу undef — Скасовує попереднє визначення include — Вставляє текст з зазначеного файлу (імпортує) if — Здійснює умовну компіляцію при істинності константного виразу ifdef — Здійснює умовну компіляцію, якщо константа визначена ifndef — Здійснює умовну компіляцію при невизначеності константи else — Гілка умовної компіляції при хибності висловлювання elif — Гілка умовної компіляції, утворена злиттям else та if endif — Кінець гілки умовної компіляції line — Препроцесор змінює номер поточного рядка й ім'я файлу для компіляції error — Висвітлення повідомлення з зупинки компіляції pragma — Дію, що залежить від конкретної реалізації компілятора warning — Висвітлення повідомлення без зупинки компіляції порожнє слово — пуста дія
Опис директив Константи та макроси #define Константи та макроси препроцесора використовуються для визначення невеликих фрагментів коду. Зазвичай константи визначаються за допомогою великих літер. // константа #define BUFFER_SIZE 1024 #define PI 3.14 // макрос #define NUMBER_OF_ARRAY_ITEMS(array) (sizeof(array)/sizeof(*(array))) Кожна константа і кожен макрос замінюються відповідним їм визначенням. Макроси мають параметри, схожі на функції, використовуються для зменшення коду.
Приклад визначення макроса max, який приймає два аргументи: a і b та повертає більше з двох число: #define max( a, b ) ( (a) > (b) ? (a) : (b) ) Макрос викликається як звичайна функція: z = max(x, y); Після заміни макроса код виглядатиме так: z = ((x) > (y) ? (x) : (y));
Директива #include При виявленні директив #include "..." або #include <...>, де «…» — ім'я файлу, препроцесор читає вміст зазначеного файлу, виконує директиви й заміни (підставлення).
Для #include "..."пошук файлу виконується в цій теці й теках, зазначених в командному рядку компілятора. Для #include <...> пошук файлу виконується в теках, що містять файли стандартної бібліотеки (шлях до цих тек залежать від компілятора).
Файли, що включаються зазвичай містять: оголошення функцій; оголошення глобальних змінних; визначення інтерфейсів; визначення типів даних; структури та інше. Директива #includeзазвичай вказується на початку файлу (в заголовку), тому включаються файли називаються заголовками.
Приклад включення файлів зі стандартної бібліотеки мови C:#include <math.h> // імпортування математичних функцій(стандартна бібліотека) #include <foo.h> // імпортування файлу не зі стандартної бібліотеки
Використання препроцесора вважається неефективним з наступних причин: кожен раз при включенні файлів виконуються директиви й заміни (підставляння); компілятор міг би зберігати результати препроцесорування для використання в майбутньому; множинні включення одного файлу доводиться запобігати вручну за допомогою директив умовної компіляції; компілятор міг би виконувати цю задачу самостійно. Починаючи з 1970-х років стали з'являтися способи, якими замінено включення файлів. У мовах Java і Common Lisp використовуються пакети (ключове слово package) (див. Package в Java), в мові Паскаль — англ. units (ключові слова unitі uses), у мовах Modula, OCaml, D, Haskell і Python — модулі. Використовуються ключові слова moduleі import.
Посилання The C Preprocessor