Препроцесор C

Препроцесор С/С++ — програмний інструмент, який використовується в мовах програмування 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), у мовах ModulaOCamlDHaskell і Python — модулі. Використовуються ключові слова moduleі import.

Посилання

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.