Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
234
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

Препроцессорные операции в строке замещения.

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

В качестве полезного примера с операцией '#' рассмотрим следующее макроопределение:

#define print (A) printf (#А"=%f, А)

К макросу print (А) можно обращаться, подставляя вместо параметра А произвольные выражения, формирующие результаты вещественного типа. Пример:

print (sin (a/2)); - обращение к макросу;

printf ("sin (a/2)""=%f'', sin (a/2)); - макрорасширение.

Фрагмент программы:

Результат выполнения (на экране дисплея):

Операция '##', допускаемая только между лексемами строки замещения, позволяет выполнять конкатенацию лексем, включаемых в строку замещения.

Чтобы пояснить роль и место операции '##', рассмотрим, как будут выполняться макроподстановки в следующих трех макроопределениях с одинаковым списком параметров и одинаковыми аргументами.

#defme zero (a, b, с, d) a (bed)

#define one (a, b, c, d) a (b с d)

#define two (a, b, c, d) a (b##c##d)

Макровызов: Результат макроподстановки:

В случае zero( ) последовательность "bed" воспринимается как отдельный идентификатор. Замена параметров Ь, с, d не выполнена. В строке замещения макроса one( ) аргументы отделены пробелами, которые сохраняются в результате. В строке замещения для макроса two( ) использована операция '##', что позволило выполнить конкатенацию аргументов без пробелов между ними.

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

В отличие от директив #include, #define и всего набора команд условной компиляции (#if...) рассматриваемые в данном параграфе директивы не так часто используются в практике программирования.

Препроцессорные обозначения строк.

Препроцессорные обозначения строк. Для нумерации строк можно использовать директиву

#line константа

которая указывает компилятору, что следующая ниже строка текста имеет номер, определяемый целой десятичной константой. Директива может одновременно изменять не только номер строки, но и имя файла:

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

Как пишут в литературе по языку Си [5], директиву #line можно "встретить" сравнительно редко, за исключением случая, когда текст программы на языке Си генерирует какой-то другой препроцессор.

Смысл директивы #line становится очевидным, если рассмотреть текст, который препроцессор формирует и передает на компиляцию. После препроцессорной обработки каждая строка имеет следующий вид:

имя_файла номер_строки текст_на_языке_Си

Например, пусть препроцессор получает для обработки файл "www.c" с таким текстом:

После препроцессора в файле с именем "www.i" будет получен следующий набор строк:

Обратите внимание на отсутствие в результирующем тексте препроцессорных директив и комментария. Соответствующие строки пусты, но включены в результирующий текст. Для них выделены порядковые номера (1 и 4). Следующая строка за директивой #line обозначена в соответствии со значением константы (23) и указанным именем файла "file.c".