logo

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

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

  • Це перший крок, через який проходить вихідний код C під час перетворення у виконуваний файл.
  • Основні типи директив препроцесора:  Макроси Умовна компіляція включення файлів та інші директиви, такі як #undef #pragma тощо.
  • В основному ці директиви використовуються для заміни певної частини коду C на інший код C. Наприклад, якщо ми напишемо «#define PI 3.14», то препроцесор замінить PI на 3.14.
C Препроцесори

Типи препроцесорів C

Всі перераховані вище препроцесори можна класифікувати на 4 типи:

команда arp-a

Макроси

Макроси використовуються для визначення констант або створення функцій, які замінюються препроцесором перед компіляцією коду. Два препроцесори #визначити і #undef використовуються для створення та видалення макросів у C.



#визначити символічна вартість
#undef жетон

де після попередньої обробки жетон буде розширено до його значення в програмі.

приклад:

C
#include  // Macro Definition #define LIMIT 5 int main(){  for (int i = 0; i < LIMIT; i++) {  printf('%d n' i);  }  return 0; } 

Вихід
0 1 2 3 4 

У наведеній вище програмі перед початком компіляції слово LIMIT замінено на 5. Слово "ОБМЕЖЕННЯ" у визначенні макросу називається шаблоном макросу і «5» — розширення макросу.

Примітка У кінці визначення макросу немає крапки з комою (;). Визначення макросів не потребують крапки з комою в кінці.

Є й такі Попередньо визначені макроси в C які корисні для надання різноманітних функцій нашій програмі.

Раніше визначений макрос можна скасувати за допомогою препроцесора #undef. Наприклад, у наведеному вище коді

успадкування в java
C
#include  // Macro Definition #define LIMIT 5 // Undefine macro #undef LIMIT int main(){  for (int i = 0; i < LIMIT; i++) {  printf('%d n' i);  }  return 0; } 


Вихід:

./Solution.c: In function 'main': ./Solution.c:13:28: error: 'MAX' undeclared (first use in this function) printf('MAX is: %dn' MAX); ^ ./Solution.c:13:28: note: each undeclared identifier is reported only once for each function it appears in

Макроси з аргументами

Ми також можемо передавати аргументи макросам. Ці макроси працюють подібно до функцій. Наприклад

# визначити foo(a b) a + b
#define func(r) r * r

Давайте зрозуміємо це за допомогою програми:

C
#include  // macro with parameter #define AREA(l b) (l * b) int main(){  int a = 10 b = 5;    // Finding area using above macro  printf('%d' AREA(a b));  return 0; } 

Вихід
Area of rectangle is: 50 

Пояснення: У наведеній вище програмі макрос ПЛОЩА (l b) визначається для обчислення площі прямокутника шляхом множення її довжина (л) і ширина (б) . Коли ПЛОЩА (a b) називається воно розширюється на (а * б) і результат обчислюється та друкується.

Будь ласка, зверніться Типи макросів у C для додаткових прикладів і типів.

Включення файлу

Включення файлів дозволяє вам включати зовнішні файли (бібліотеки файлів заголовків тощо) до поточної програми. Зазвичай це робиться за допомогою #включити директива, яка може включати як системні, так і визначені користувачем файли.

Синтаксис

Є два способи включити файли заголовків.

#включити
#включити 'ім'я файлу'

if else if java

The '<' і дужки '>' скажіть компілятору шукати файл у стандартний довідник поки подвійні лапки ( ' ' ) скажіть компілятору шукати файл заголовка в каталозі вихідного файлу.

приклад:

C
// Includes the standard I/O library #include   int main() {  printf('Hello World');    return 0; } 

Вихід
Hello World

Умовна компіляція

Умовне складання дозволяє включати або виключати частини коду залежно від певних умов. Це корисно для створення специфічного для платформи коду або для налагодження. Існують наступні директиви умовного препроцесора: #if #ifdef #ifndef else #elif і #endif

Синтаксис

період ключ

Загальний синтаксис умовних препроцесорів:

#якщо
// деякий код
#еліф
// ще трохи коду
#інше
// Ще трохи коду
#endif

Директива #endif використовується для закриття директив відкриття #if #ifdef і #ifndef.

приклад

C
#include  // Defining a macro for PI #define PI 3.14159 int main(){   // Check if PI is defined using #ifdef #ifdef PI  printf('PI is definedn'); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE)  printf('Square is definedn'); // If neither PI nor SQUARE is defined trigger an error #else  #error 'Neither PI nor SQUARE is defined' #endif // Check if SQUARE is not defined using #ifndef #ifndef SQUARE  printf('Square is not defined'); // If SQUARE is defined print that it is defined #else  printf('Square is defined'); #endif  return 0; } 

Вихід
PI is defined Square is not defined

Пояснення: Цей код використовує умовні директиви препроцесора ( #ifdef #elif і #ifndef ), щоб перевірити, чи певні макроси ( ПІ і КВАДРАТ ) визначені. Оскільки PI визначено, програма друкує ' ПІ визначено ' потім перевіряє, чи SQUARE не визначено, і друкує ' Квадрат не визначено '.

Інші директиви

Крім основних директив препроцесора, C також надає інші директиви для керування поведінкою компілятора та налагодженням.

#pragma:

Надає конкретні інструкції компілятору для контролю його поведінки. Використовується для вимкнення вирівнювання набору попереджень тощо.

Синтаксис

#прагма директива

Деякі з директив #pragma обговорюються нижче: 

  1. #pragma запуск: Ці директиви допомагають нам визначити функції, які необхідно виконати перед запуском програми (до того, як керування перейде до main()).
  2. #pragma вихід : Ці директиви допомагають нам указати функції, які необхідно запускати безпосередньо перед виходом з програми (безпосередньо перед поверненням керування з main()).

приклад

java, якщо інше
C
#include  void func1(); void func2(); // specifying funct1 to execute at start #pragma startup func1 // specifying funct2 to execute before end #pragma exit func2 void func1() { printf('Inside func1()n'); } void func2() { printf('Inside func2()n'); } int main(){  void func1();  void func2();  printf('Inside main()n');  return 0; } 

Вихід
Inside main() 

Наведений вище код створюватиме вихідні дані, як наведено вище, якщо працюватиме на компіляторах GCC, тоді як очікуваний результат буде:

Очікуваний результат

Inside func1() Inside main() Inside func2() 

Це відбувається тому, що GCC не підтримує запуск або вихід #pragma. Однак ви можете використовувати наведений нижче код для очікуваного результату на компіляторах GCC. 

C
#include  void func1(); void func2(); void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2(); void func1() {  printf('Inside func1()n'); } void func2() {  printf('Inside func2()n'); } int main() {  printf('Inside main()n');  return 0; } 

Вихід
Inside func1() Inside main() Inside func2() 

У наведеній вище програмі ми використали деякі специфічний синтаксис так що одна з функцій виконується перед основною функцією, а інша – після основної функції.

Створіть вікторину