 |
директивах #define и #undef:
_STDC_
_FILE_
_LINE_
- 293,294 -
_DATE_
_TIME_
2. Две лексемы могут быть помещены вместе в макроопределение
с разделением их знаками ## (плюс необязательные пробелы с каждой
стороны). Препроцессор удаляет пробелы и ##, а также комбинирует
разделенные лексемы. Это может быть использовано для создания
идентификаторов, например, задав:
#define VAR(i,j) (i ## j)
при VAR(x,6) обращение вызовет подстановку x6. Это заменяет
иногда употребляемую, но не переносимую запись (i/**/j).
3. Вложенные макросы в строке макроопределения сработают
лишь тогда, когда сработает сам макрос, а не при его описании.
Это больше касается вложенных макросов #undef.
4. Символ #, помещаемый перед макроаргументом, указанном в
последовательности, преобразует аргумент в строку. При макроподс-
тановке производится замена #<формальный аргумент> на "<действи-
тельный аргумент>". Так, при задании макроопределения
#define TRACE(flag) printf(#flag "= %d\n", flag)
следующий фрагмент текста программы
highval = 1024;
TRACE(highval);
преобразуется в:
highval = 1024;
printf("highval" "= %d\n", highval);
который, в переводе, становиться
highval = 1024;
printf("higval=%d\n",hidhval);
5. В отличие от других реализаций, Турбо Си не подставляет
макроаргументы внутри строк и символьных констант.
- 295,296 -
Включение файла (K&R 12.2)
-----------------------------------------------------------------
В Турбо Си директива #include реализована согласно K&R, но с
некоторыми дополнительными особенностями. Если препроцессор не
нашел include файл в каталоге, установленном по умолчанию, (пред-
полагается, что вы используете запись include "filename"), тогда
он ищет каталоги, заданные опцией компилятора -I. Если вы исполь-
зуете форму #include <ИмяФайла>, тогда ищутся только каталоги,
заданные опцией -I. (Каталоги, перечисленные в меню по опции
O/Environment/Include, эквивалентны маршруту, указанному с по-
мощью опции -I pathname в командной строке.
Вы можете задать маршрут к #include, через граничные разде-
лители, используя макрорасширение. Если следующая после ключевого
слова строка начинается с идентификатора, то препроцессор прос-
матривает текст для макроса. Однако, если строка заключена в ка-
вычки или в острые скобки, то Турбо Си не будет проверять ее для
распознавания макроса. Например,
#define myinclude "c:\tc\include\mystuff.h"
#include myinclude
#include "myinclude.h"
1-ый #include оператор заставит препроцессор просматривать
C:\TC\INCLUDE\MYSTUFF.H, тогда как 2-ой вызовет просмотр
MYINCLUDE.H в каталоге по умолчанию.
Кроме того, вам нельзя использовать объединение литерных
строк и вставку лексем в макросе, который используется в операто-
ре include. Макрорасширение должно создавать текст, который чита-
ется как нормальная #include директива.
- 297,298 -
Условная компиляция (K&R 12.3)
-----------------------------------------------------------------
Турбо Си поддерживает определение условной компиляции K&R с
помощью замены соответствующих строк на пустые. Игнорируемые
строки начинаются с директив #if, #ifdef, #ifndef, #else, #elif,
и #endif, также как и все некомпилируемые строки, являющиеся ре-
зультатом этих директив. Все директивы условной компиляции должны
заканчиваться в исходной программе или include файле, в которых
они начались.
Турбо Си поддерживает также оператор ANSI defined(символ).
Значение 1 (true) присваивается, если символ был предварительно
определен (с использованием #define) и затем не был отменен (с
использованием undef); в противном случае присваивается 0
(false). Так, директива
#if defined(mysym)
адекватна директиве
#ifdef mysym
Преимущество в том, что можно повторно использовать defined
в сложном выражении, стоящем за директивой #if:
#if defined(mysym) || defined(yoursym)
Наконец, Турбо Си (в отличие от ANSI) позволяет использовать
оператор sizeof в выражениях препроцессора. Так вы можете напи-
сать следующее:
#if (sizeof(void *) == 2)
#define SDATA
#else
#define LDATA
#endif
- 299,300 -
Управление строками (K&R 12.4)
-----------------------------------------------------------------
Турбо Си поддерживает определение #line, данное в K&R. Рас-
ширения макросов в #line такие же, как и в #include.
Директива error (ANSI Си 3.8.5)
-----------------------------------------------------------------
Турбо Си поддерживает директиву #error, которая упоминается
(но не определена в полной мере) в ANSI-стандарте. Ее формат:
#error errmsg
и вызывает сообщение
Fatal: filename line# Error directive: errmsg
(Фатальная ошибка: Имяфайла строка# Ошибка в директиве: errmsg)
У программистов принято включать эту директиву в условный
препроцессор, что захватывает некоторые нежелательные состояния
во время компиляции. При благоприятном исходе это состояние не
будет true. В случае, если это состояние true, вы захотите напе-
чатать сообщение об ошибке и остановить компиляцию. Вы вставляете
директиву #error внутрь условия, для которого true является неже-
лательным исходом. Например, предполагается, что #define MYVAL
принимает значения либо 0 либо 1. Вы можете тестировать на некор-
ректность значение MYVAL, если включите в ваш исходный код следу-
ющее условие:
#if (MYVAL != 0 && MYVAL != 1)
#error MYVAL должен быть определен только либо 0 либо 1
#endef
Препроцессор просматривает текст, уничтожая комментарии, а
на экран выводит оставшийся текст без просмотра для выявления
макросов.
- 301,302 -
|