6. Комбинирование исходных файлов
Одна из основных задач С препроцессора - это передача информации
компилятору о месторасположении различных частей программы.
Код программы может формироваться из нескольких исходных файлов при
использовании директивы '#include'. Применение как директивы '#include',
так и условий с макросами приводит к изменению основного исходного файла.
Следует принимать во внимание значение нумерации строк С компилятором
(при сообщениях об ошибках) и отладчиком (например, GDB).
В С препроцессоре существует директива, позволяющая контролировать эту
возможность. Это может пригодиться в случае, если файлом ввода препроцессора
является файл вывода другой программы, такой как 'bison', которая
обрабатывает другой файл, являющийся основным исходным файлом. При подобной
обработке нумерация строк теряется.
Для устранения этого недостатка используется директива '#line', которая
позволяет указать номер строки реального исходного файла вместе с его именем.
Директива '#line' применяется в трех модификациях:
'#line LINENUM'
Здесь LINENUM это десятичная целая константа, указывающая, что следующая
строка является строкой исходного файла с номером LINENUM.
'#line LINENUM FILENAME'
Здесь LINENUM это десятичная целая константа, а FILENAME - строковая
константа, указывающая, что следующая строка является строкой исходного
файла с именем FILENAME, а ее номер - LINENUM. Значение FILENAME должно
быть заключено в двойные кавычки.
'#line ANYTHING ELSE'
Значение ANYTHING ELSE проверяется на наличие макро вызовов, которые
затем подставляются. Результатом должна быть десятичная целая константа,
за которой может следовать стороковая константа, как это рассмотрено выше.
Директива '#line' изменяет значения заранее определенных макросов
'__FILE__' и '__LINE__'.
Вывод препроцессора (который затем перенапрвляется в компилятор)
содержит директивы, подобные '#line', только они начинаются с символа '#',
в отличие от '#line', за которыми следует номер строки и имя файла.
7. Другие директивы препроцессора
В этом разделе рассматриваются три дополнительные директивы. Они
описываются для полноты и не являются часто используемыми.
"Пустая директива" состоит из символа '#', за которым следует символ
новой строки, причем между ними могут быть только пробелы (включая
комментарии). Пустая директива рассматривается как директива препроцессора и
не влияет на общий вывод. Основным значением этой директивы является то,
при обработке строки, содержащей символ '#', на вывод ничего не передается,
в отличие от выводимой строки, содержащей '#'.
Стандарт ANSI указывает, что директива '#pragma' имеет произвольное
значение, устанавливаемое при разработке. В препроцессоре GNU C она
не используется, за исключением значения '#pragma once'. Однако, она
остается при выводе препроцессора и может быть использована в процессе
компиляции.
Директива '#ident' используется для совместимости с некоторыми
системами. За ней следует строка с текстом. На некоторых системах этот
текст копируется в отдельное место объектного файла. Но в большинстве систем
он просто игнорируется и применение этой директивы не дает никакого эффекта.
В действительности, эта директива является единственной директивой,
используемой в подключаемых файлах и функционирует на тех системах,
которые ее поддерживают.
8. Вывод С препроцессора
Вывод С препроцессора выглядит примерно так же, как и ввод, только
все строки с директивами заменяются на пустые и комментарии заменяются
пробелами. Пробелы в середине строки не меняются. Однако пробел вставляется
после большинства макроподстановок.
Имя исходного файла и информация о номере строки передается в строках
следующей формы:
# LINENUM FILENAME FLAGS
которые вставляются в середину вводимого файла (но не в строчную или
символьную константу). Появление такой строки означает, что следующая
строка содержится в файле FILENAME и имеет порядковый номер LINENUM.
После имени файла следует нуль или более флагов, значения которых
могут быть '1', '2', '3' или '4'. Если флагов более одного, то они
разделяются пробелами. Далее следует описание этих флагов.
'1'
Указывает на начало нового файла.
'2'
Указывает на возврат в файл (после включения другого файла).
'3'
Указывает на то, что следующий текст исходит из системного
подключаемого файла, поэтому должны использоваться специальные
предупреждающие сообщения.
'4'
Указывает на то, что следующий текст должен рассматриваться как С код.
... 1-12. Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое - начертить гистограмму горизон- тально; вертикальная ориентация требует больших усилий. 1.7. Функции. В языке “C” функции эквивалентны подпрограммам или функ- циям в фортране или процедурам в PL/1, паскале и т.д. Функ- ции дают удобный способ заключения некоторой части вычисле- ний в черный ...
... , сложны для понимания и абсолютно непрозрачны, а возможности существенно уступают Форту и Лиспу. В общем, муть и мрак. Вавилонское столпотворение Всякий раз, когда появляется очередной новый язык, о котором говорят, как об «окончательном и безальтернативном», предрекая скорую смерть всех остальных, мне становится смешно. Сам по себе язык в отрыве от среды программирования —малоинтересен, да и все ...
... программе. В данном разделе они перечислены в алфавитном порядке и приводятся с объяснениями. Эти ошибки могут являться следствием случайного затирание памяти программой. Abnormal program termination Аварийное завершение программы Данное сообщение может появляться, если для выполнения программы не может быть выделено достаточного количества памяти. Более подробно оно рассматривается в конце ...
... доступа с записью равной байту. Такие файлы называются двоичными. Файлы прямого доступа незаменимы при написании программ, которые должны работать с большими объемами информации, хранящимися на внешних устройствах. В основе обработке СУБД лежат файлы прямого доступа. Кратко изложим основные положения работы с файлами прямого доступа. 1). Каждая запись в файле прямого доступа имеет свой номер ...
0 комментариев