freeCodeCamp/guide/russian/cplusplus/preprocessors/index.md

11 KiB
Raw Blame History

title localeTitle
Preprocessors Препроцессоры

Препроцессоры в C / CPP

Как видно из названия, препроцессоры - это программы, которые обрабатывают наш исходный код перед компиляцией. Существует несколько шагов, связанных с написанием программы и выполнением программы на C / C ++. Давайте посмотрим на эти шаги, прежде чем мы начнем узнавать о препроцессорах.

Img

Вы можете увидеть промежуточные шаги на приведенной выше диаграмме. Исходный код, написанный программистами, хранится в файле program.c. Затем этот файл обрабатывается препроцессорами, а файл расширенного исходного кода создается с именем program. Этот расширенный файл компилируется компилятором и создается файл объектного кода с именем program.obj. Наконец, компоновщик связывает этот файл объектного кода с объектным кодом библиотечных функций для генерации исполняемого файла program.exe.

Препроцессорные программы предоставляют директивы препроцессоров, которые сообщают компилятору предварительно обработать исходный код перед компиляцией. Все эти директивы препроцессора начинаются с символа # (хеш). Этот символ ('#') в начале инструкции в программе C / C ++ указывает, что это предпроцессорная директива. Мы можем разместить эти предпроцессорные директивы в любой нашей программе. Примерами некоторых препроцессорных директив являются: #include , #define , #ifndef и т. Д.

Типы предпроцессорных директив:

  1. макрос
  2. Включение файлов
  3. Условная компиляция
  4. Другие директивы

Макросы:

Макросы являются частью кода в программе, которому дано какое-то имя. Всякий раз, когда это имя встречается компилятором, компилятор заменяет это имя фактическим фрагментом кода. Директива #define используется для определения макроса.

  #include<iostream> 
  #define LIMIT 3 
  int main() 
  { 
    for(int i=0; i < LIMIT; i++) 
    { 
      std::cout<<i<<" " ; 
    } 
      return 0; 
  } 

Вывод:

0 1 2

В вышеприведенной программе, когда компилятор выполняет слово LIMIT он заменяет его на 3. Слово LIMIT в определении макроса называется макромодом, а «3» - расширением макроса.

В конце определения макроса не должно быть запятой (';'). Определения макросов не нуждаются в полуточке.

Включение файла:

Этот тип предпроцессорной директивы сообщает компилятору включить файл в программу исходного кода. Существует два типа файлов, которые могут быть включены пользователем в программу:

  • #### Файл заголовка или стандартные файлы: Эти файлы содержат определение предопределенных функций, таких как printf (), ... scanf () и т. Д. Эти файлы должны быть включены для работы с этими функциями. ... Различные функции объявляются в разных файлах заголовков. Например ... стандартные операции ввода-вывода находятся в файле «iostream», тогда как функции, которые ... выполняют строковые операции, находятся в файле «string».

Синтаксис:

#include< file_name > где file_name - это имя файла, который будет включен. Скобки < и > сообщают компилятору искать файл в стандартном каталоге.

  • #### Пользовательские файлы: Когда программа становится очень большой, целесообразно разделить ее на более мелкие файлы и включать в случае необходимости. Эти типы файлов являются определяемыми пользователем файлами. Эти файлы могут быть включены как: ... #include"filename"

Условная компиляция:

Условные директивы компиляции - это типы директив, которые помогают скомпилировать определенную часть программы или пропустить компиляцию некоторой определенной части программы на основе некоторых условий. Это можно сделать с помощью двух команд предварительной обработки ifdef и endif .

Синтаксис:

  ifdef macro_name 
    statement1; 
    statement2; 
    statement3; 
    . 
    . 
    . 
    statementN; 
  endif 

Если макрос с именем «macroname» определен, тогда блок операторов будет выполняться нормально, но если он не определен, компилятор просто пропустит этот блок операторов.

Другие директивы:

Помимо вышеуказанных директив есть еще две директивы, которые обычно не используются. Это:

  1. ##### #undef Директива: Директива #undef используется для определения существующего макроса. Эта директива работает как:
Синтаксис:

#undef LIMIT Использование этого оператора будет определять неопределенный существующий макрос LIMIT. После этого утверждения каждый оператор #ifdef LIMIT будет оценивать значение false.

  1. ##### # #pragma директива: Эта директива является директивой специального назначения и используется для включения или отключения некоторых функций. Этот тип директив специфичен для компилятора, т. Е. Они варьируются от компилятора к компилятору. Некоторые из директив #pragma обсуждаются ниже:
#pragma startup и #pragma exit :

Эти директивы помогают нам определить функции, которые необходимы для запуска до запуска программы (до того, как элемент управления переходит к main ()) и непосредственно перед выходом программы (как раз перед возвратом элемента управления из main ()).

#include<stdio.h> 
 void func1(); 
 void func2(); 
 #pragma startup func1 
 #pragma exit func2 
 void func1() 
 { 
    printf("Inside func1() "); 
 } 
 void func2() 
 { 
    printf("Inside func2() "); 
 } 
 int main() 
 { 
    printf("Inside main() "); 
 
    return 0; 
 } 

Вывод:
Inside func1() Inside main() Inside func2()
Вышеприведенный код будет выдавать результат, указанный ниже при запуске на компиляторах GCC:
Вывод:
Inside main()
Это происходит потому, что GCC не поддерживает запуск #pragma или выход. Однако вы можете использовать приведенный ниже код для аналогичного вывода на компиляторах GCC.

#include<stdio.h> 
 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; 
 } 
#pragma warn Директива:

Эта директива используется, чтобы скрыть предупреждающее сообщение, которое отображается во время компиляции. Мы можем скрыть предупреждения, как показано ниже:

#pragma warn -rvl :

Эта директива скрывает предупреждение, которое возникает, когда функция, которая должна возвращать значение, не возвращает значение.

#pragma warn -par :

Эта директива скрывает предупреждение, которое возникает, когда функция не использует переданные ей параметры.

#pragma warn -rch :

Эта директива скрывает предупреждение, которое возникает, когда код недостижим. Например: любой код, написанный после оператора return в функции, недоступен.