4.3.2. Нестандартные заранее определенные макросы
Обычно С препроцессор имеет несколько заранее определенных макросов,
значения которых различаются в зависимости от используемой платформы и
операционной системы. В данном руководстве не представляется возможным
рассмотреть все макросы. Здесь описаны только наиболее типичные из них.
Для просмотра значений заранее определенных макросов можно воспользоваться
командой 'cpp -dM'.
Некоторые нестандартные заранее определенные макросы более или менее
подробно описывают тип используемой операционной системы. Например,
'unix'
Этот макрос обычно определен на всех системах Unix.
'BSD'
Этот макрос определен на последних версиях системы Berkley Unix
(возможно только в версии 4.3).
Другие макросы описывают тип центрального процесора. Например,
'vax'
Определен на Vax компьютерах.
'mc68000'
Определен на большинстве компьютеров, использующих процессор Motorola
68000, 68010 или 68020.
'm68k'
Также определен на большинстве компьютеров с процессором 68000, 68010
или 68020. Хотя некоторые разработчики используют 'mc68000', а некоторые -
'm68k'. Некоторые заранее определяют оба макроса.
'M68020'
Определен на некоторых системах с процессором 68020 в дополнение к
макросам 'mc68000' и 'm68k', которые являются менее специфичными.
'_AM29K'
'_AM29000'
Определены на компьютерах с процессорами из семейства AMD 29000.
'ns32000'
Определен на компьютерах, использующих процессоры серии National
Semiconductor 32000.
Другие нестандартные макросы описывают изготовителей компьютерных
систем. Например,
'sun'
Определен на всех моделях компьютеров Sun.
'pyr'
Определен на всех моделях компьютеров Pyramid.
'sequent'
Определен на всех моделях компьютеров Sequent.
Эти заранее определенные символы являются не только нестандартными, но
они к тому же не соответствуют стандарту ANSI, потому что их имена не
начинаются с символа подчеркивания. Поэтому опция '-ansi' запрещает
определение этих символов.
Это приводит к тому, что опция '-ansi' становится бесполезной, так как
большое количество программ зависит от нестандартных заранее определенных
символов. Даже системные подключамые файлы проверяют их значения и
генерируют неправильные объявления в случае если требуемые имена не
определены. В результате очень мало программ компилируется с опцией '-ansi'.
Что же нужно сделать в ANSI C программе для того, чтобы проверить тип
используемого компьютера?
Для этой цели GNU C предоставляет параллельную серию символов, имена
которых состоят из обычных символов с добавлением строки '__' с начала и
с конца. Таким образом символ '__vax__' используется на системах Vax, и
так далее.
Набор нестандартных заранее определенных символов в GNU C препроцессоре
изменяется (при компиляции самого компилятора) с помощью макроса
'CPP_PREDEFINES', которым является строка, состоящая из опций '-D',
разделенных пробелами. Например, на системе Sun 3 используется следующее
макроопределение:
#define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Dm68k"
Этот макрос обычно указывается в файле 'tm.h'.
4.4. Стрингификация
"Стрингификация" означает преобразование фрагмента кода в строковую
константу, которая содержит текст этого фрагмента кода. Например, в результате
стрингификации 'foo (z)' получается '"foo (z)"'.
В С препроцессоре, стрингификация является опцией, используемой при
замене аргументов в макросе макроопределением. При появлении имени аргумента
в теле макроопределения, символ '#' перед именем аргумента указывает на
стрингификацию соответствующего аргумента при его подстановке в этом месте
макроопределения. Этот же аргумент может быть заменен в другом месте
макроопределения без его стрингификации, если перед именем аргумента нет
символа '#'.
Вот пример макроопределения с использованием стрингификации:
#define WARN_IF(EXP) \
do { if (EXP) \
fprintf (stderr, "Warning: " #EXP "\n"); } \
while (0)
Здесь аргумент 'EXP' заменяется один раз обычным образом (в конструкции
'if'), а другой - с использованием стрингификации (аргумет функции
'fprintf'). Конструкция 'do' и 'while (0)' является реализацией макроса
'WARN_IF (ARG);'.
Возможности срингификации ограничены до преобразования одного макро
аргумента в одну строковую константу: не существует методов комбинирования
аргумента с другим текстом и посследующей стрингификации полученных данных.
Хотя рассмотренный выше пример показывает как может быть достигнут подобный
результат в стандартном ANSI C с использованием возможности объединения
смежных строковых констант в одну. Препроцессор стрингифицирует реальное
значение 'EXP' в отдельную строковую константу и в результате получается
следующий текст:
do { if (x == 0) \
fprintf (stderr, "Warning: " "x == 0" "\n"); } \
while (0)
но С компилятор обнаруживает три строковые константы, расположенные друг
за другом и объединяет их в одну:
do { if (x == 0) \
fprintf (stderr, "Warning: x == 0\n"); } \
while (0)
Стрингификация в С является не только заключением требуемого текста в
кавычки. Необходимо помещать символ backslash перед каждым дополнительным
символом кавычки, а также перед каждым символом backslash в символьной или
строковой константе для получения строковой константы в стандарте С. Поэтому
при стрингификации значения 'p = "foo\n";' в результате получится строка
'"p = \"foo\\n\";"'. Однако символы backslash, не принадлежащие символьной
или строковой константе, не дублируются: значение '\n' стрингифицируется в
'"\n"'.
Пробелы (включая комментарии), находящиеся в тексте, обрабатываются
в соответствии с установленными правилами. Все предшествующие и последующие
пробелы игнорируются. Любые последовательности пробелов в середине текста
в результате обработки заменяются на отдельный пробел.
... 1-12. Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое - начертить гистограмму горизон- тально; вертикальная ориентация требует больших усилий. 1.7. Функции. В языке “C” функции эквивалентны подпрограммам или функ- циям в фортране или процедурам в PL/1, паскале и т.д. Функ- ции дают удобный способ заключения некоторой части вычисле- ний в черный ...
... , сложны для понимания и абсолютно непрозрачны, а возможности существенно уступают Форту и Лиспу. В общем, муть и мрак. Вавилонское столпотворение Всякий раз, когда появляется очередной новый язык, о котором говорят, как об «окончательном и безальтернативном», предрекая скорую смерть всех остальных, мне становится смешно. Сам по себе язык в отрыве от среды программирования —малоинтересен, да и все ...
... программе. В данном разделе они перечислены в алфавитном порядке и приводятся с объяснениями. Эти ошибки могут являться следствием случайного затирание памяти программой. Abnormal program termination Аварийное завершение программы Данное сообщение может появляться, если для выполнения программы не может быть выделено достаточного количества памяти. Более подробно оно рассматривается в конце ...
... доступа с записью равной байту. Такие файлы называются двоичными. Файлы прямого доступа незаменимы при написании программ, которые должны работать с большими объемами информации, хранящимися на внешних устройствах. В основе обработке СУБД лежат файлы прямого доступа. Кратко изложим основные положения работы с файлами прямого доступа. 1). Каждая запись в файле прямого доступа имеет свой номер ...
0 комментариев