Вівторок, 19.03.2024, 12:39
Гость

Мішатронік

Мобільна версія | Додати у вибране  | Мій профіль | Вихід | RSS |
Меню сайту
Наше опитування
Оцініть мій сайт
Всього відповідей: 12
Статистика

Онлайн всього: 1
Гостей: 1
Користувачів: 0


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

Командные строки препроцессора используются для условной компиляции различных частей исходного текста в зависимости от внешних условий.

 
#if константное_выражение
 

Пример:

 
#if ABC + 3
 

Истина, если константное выражение ABC + 3 не равно нулю.

 
#ifdef идентификатор
 

Пример:

 
#ifdef ABC
 

истина, если идентификатор ABC определен ранее командой #define.

 
#ifndef идентификатор
 

Пример:

 
#ifndef ABC
 

истина, если идентификатор ABC не определен в настоящий момент.

 
#else
 . . .
#endif
 

Если предшествующие проверки #if#ifdef или #ifndef дают значение "Истина", то строки от #else до #endifигнорируются при компиляции.

 

Если эти проверки дают значение "Ложь", то строчки от проверки до #else (а при отсутствии #else - до #endif ) игнорируются.

 

Команда #endif обозначает конец условной компиляции.

 

Пример:

 
#ifdef DEBUG
fprintf (stderr, "location: x = %d\n", x);
#endif
 

Вспомогательные директивы

Номер строки и имя файла

#line целая_константа "имя_файла"
 

Пример:

 
#line 20 "ABC"
 

Препроцессор изменяет номер текущей строки и имя компилируемого файла. Имя файла может быть опущено.

 

Одна из целей использования условной компиляции - сделать программу более мобильной. Изменяя несколько ключевых определений в начале файла, мы можем устанавливать различные значения и включать различные файлы для разных систем.

 

Пример:

 
#define N 3/*определение константы */
void main( )
{
#line 55 "file.c"
double x[3*N];
}

Реакция на ошибки

#error последовательность лексем
 

Обработка директивы приводит к выдаче диагностического сообщения в виде, определенном последовательностью лексем. Применение этой директивы совместно с условными препроцессорными командами.

 

Пример:

 
#define NAME 15
 

В дальнейшем можно проверить ее значение и выдать сообщение, если у NAME окажется другое значение:

 
#if (NAME !=15)
#error NAME должно быть равно 15!
 

Сообщение будет выглядеть так:

 
error <имя_файла><номер_строки >; 
error directive: NAME должно быть равно 15!
 

Пустая директива

#
 

Использование этой директивы не вызывает никаких действий.

 

Прагмы

#pragma
 

Эта директива определяет действия, зависящие от конкретной реализации компилятора. Например в некоторые компиляторы входит вариант этой директивы для извещения компилятора о наличии в тексте программы команд на языке Ассемблер. Возможности команды #pragma могут быть разнообазными. Стандарта для них не существует. Если конкретный препроцессор встречает прагму, которая ему неизвестна, он ее просто игнорирует как пустую директиву. В некоторых реализациях включена прагма.

 

#pragma pack(n), где n= 124. Прагма pack позволяет влиять на упаковку смежных элементов в структурах и объединениях (см. лекцию 14).

 

Соглашение может быть таким:

 

pack(1) - выравнивание элементов по границам байтов;

 

pack(2) - выравнивание элементов по границам слов;

 

pack(4) - выравнивание элементов по границам двойных слов;

 

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

 

Встроенные макроимена

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

 

__DATE__ - строка символов в формате: "месяц число год", определяющая дату начала обработки исходного файла. Например, после препроцессорной обработки текста программы, выполненной 29 января 2005 года, оператор

 
printf(__DATE__);
 

станет таким

 
printf("%s", "January 29 2005");
 

__LINE__ - десятичная константа - номер текущей обрабатываемой строки файла с программой на Си. Принято, что номер первой строки исходного файла равен 1 ;

 

__FILE__ - строка символов - имя компилируемого файла. Имя изменяется всякий раз, когда препроцессор встречает директиву#include с указанием имени другого файла. Когда включения файла по команде #include завершаются, востанавливается предыдущее значение макроимени __FILE__ ;

 

__TIME__ - строка символов вида "часы:минуты:секунды", определяющая время начала обработки препроцессором исходного файла;

 

__STDC__ - константа, равная 1, если компилятор работает в соответствии с ANSI-стандартом. В противном случае значениемикроимени __STDC__ не определено. Стандарт языка Си предполагает, что наличие имени __STDC__ определяется реализацией, так как макрос __STDC__ относится к нововведениям стандарта. В конкретных реализациях набор предопределенных имен гораздо шире. Для получения более полных сведений о предопределенных препроцессорных именах следует обращаться к документации поконкретному компилятору.

 

Форма входа
Пошук
Друзі сайту
Календар
«  Березень 2024  »
ПнВтСрЧтПтСбНд
    123
45678910
11121314151617
18192021222324
25262728293031

Єдина Країна! Единая Страна!