Фраза "Структурная переменная описывается с помощью переменной структурного типа" на мой Взгляд является тафтология. Из нее сложно понять суть утверждения. Хотелось бы полке понятного описания. |
Препроцессор языка Си
Общие сведения
В интегрированную среду подготовки программ на Си или в компилятор языка как обязательный компонент входит препроцессор. Назначение препроцессора - обработка исходного текста программы до ее компиляции. Препроцессорная обработка включает несколько стадий, выполняемых последовательно. Конкретная реализация может объединять несколько стадий, но результат должен быть таким, как если бы они выполнялись в следующем порядке:
- Все системно-зависимые обозначения перекодируются в стандартные коды.
- Каждая пара из символов ' \ ' и "конец строки" вместе с пробелами между ними убираются, и тем самым следующая строка исходного текста присоединяется к строке, в которой находилась эта пара символов.
- В тексте распознаются директивы и лексемы препроцессора, а каждый комментарий заменяется одним символом пустого промежутка.
- Выполняются директивы препроцессора и производятся макроподстановки.
- Эскейп-последовательности в символьных константах и символьных строках заменяются на их эквиваленты.
- Смежные символьные строки конкатенируются, то есть соединяются в одну строку.
- Каждая препроцессорная лексема преобразуется в текст на языке Си.
Поясним, что понимается под препроцессорными лексемами или лексемами препроцессора. К ним относятся символьные константы, имена включаемых файлов, идентификаторы, знаки операций, препроцессорные числа, знаки препинания, строковые константы и любые символы, отличные от пробела.
Стадия обработки директив препроцессора. При ее выполнении возможны следующие действия:
- замена идентификаторов заранее подготовленными последовательностями символов;
- включение в программу текстов из указанных файлов;
- исключение из программы отдельных частей ее текста, условная компиляция;
- макроподстановка, то есть замена обозначения параметризованным текстом, формируемым препроцессором с учетом конкретных аргументов.
Символические константы: #define
Если в качестве первого символа в строке программы используется символ #, то эта строка является командной строкой препроцессора (макропроцессора). Командная строка препроцессора заканчивается символом перевода на новую строку. Если непосредственно перед концом строки поставить символ обратной косой черты " \ ", то командная строка будет продолжена на следующую строку программы.
Директива #define, подобно всем директивам препроцессора, начинается c символа # в самой левой позиции. Она может появиться в любом месте исходного файла, а даваемое определение имеет силу от места появления до конца файла. Мы активно используем эту директиву для определения символических констант в наших примерах программ, однако она имеет более широкое применение, что мы покажем дальше.
Замена идентификаторов
#define идентификатор строка
Пример:
#define ABC 100
Заменяет каждое вхождение идентификатора ABC в тексте программы на 100:
#undef идентификатор
Пример:
#undef ABC
Отменяет предыдущее определение для идентификатора ABC.
Пример:
/* Простые примеры директивы препроцессора */ #define TWO 2 /* можно использовать комментарии*/ #define MSG "Текст 1.\ Продолжение текста 1" /* обратная косая черта продолжает определение на следующую строку */ #define FOUR TWO*TWO #define PX printf("X равен %d.\n", x) #define FMT "X равен %d.\n" int main( ) { int x = TWO; PX; x = FOUR; printf(FMT,x); printf("%s\n",MSG); printf("TWO: MSG\n"); return TWO; }
В результате выполнения нашего примера будем иметь:
X равен 2 X равен 4 Текст 1. Продолжение текста 1 TWO: MSG
Разберем, что произошло. Оператор
int x = TWO;
превращается в
int x = 2;
Затем оператор
PX;
превращается в
printf("X равно %d.\n",x);
поскольку сделана полная замена. Теперь мы видим, что макроопределение может представлять любую строку, даже целое выражение на языке Си. Заметим, что это константная строка. PX напечатает только переменную, названную x.