Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
119
Добавлен:
13.03.2016
Размер:
470.02 Кб
Скачать

2.3. Краткие сведения о препроцессоре Си

Получение исполняемой программы (с расширением .exe) из исходного текста на языке Си происходит в несколько этапов. На самом первом этапе с исходным текстом программы работает специальная программа - препроцессор. Основная цель препроцессора - закончить формирование исходного текста программы на Си. Затем окончательный текст программы подвергается компиляции, в результате которой генерируется объектный файл. После этого компоновщик формирует загрузочный модуль. Обычно препроцессор вызывается компилятором автоматически. Однако при необходимости можно использовать автономную программу препроцессора CPP.EXE. Результатом ее работы является окончательно сформированный препроцессором файл со всеми включенными файлами и другими выполненными директивами препроцессора.

Возможный вид команды вызова препроцессора:

СРР -Р- IДиректория ИмяИсхФайла

где ИмяИсхФайла - имя файла с расширением .с или .срр, -Р-  отключение опции вывода номеров строк в результирующем файле, IПуть - опция указания директории, где находятся включаемые файлы.

О других опциях программы СРР можно узнать, вызвав ее без параметров. Результатом работы препроцессора является текстовый файл с тем же именем, что и исходный, но с расширением .i.

Директивы препроцессора позволяют заменять сокращения (так называемые макро) на полный текст, отыскивать необходимые файлы и вставлять в программу их содержимое, влиять на условия компиляции и выполнять некоторые другие функции (распознавать модель памяти, выводить сообщения об ошибках и др.).

Директивы препроцессора (иногда называемые командными строками) начинаются со знака #в первой позиции строки.

2.3.2.Директива макроопределения #define

Директива #defineопределяет макро (макрос, макроопределение).

Общий вид директивы:

#define Имя_МакроПоследовательность_Символов

Каждое вхождение Имя_Макрозаменяется препроцессором наПоследовательность_Символов. Процесс замены называетсярасширением макро. Расширению не подлежат группы символов, входящие в состав комментариев, строковых литералов и символьных констант.

Директиву #define можно отменить директивой #undef:

#undef ИмяМакро

После директивы #undef ИмяМакро становится неопределенным.

Наиболее распространенное применение #define - это обозначение часто встречающихся констант, числовых и строковых. Например,

#define N 100

#define PRIGL "Введите исходные данные"

Принято для обозначения макро использовать большие буквы, так же как малые для имен переменных программы (но это не обязательно).

Если последовательность символов не помещается на одной строке, то для переноса используется символ \:

#define PRIMER "Наш текст не помещается\

на одной строке"

Макро может иметь параметры. Каждый раз при расширении параметры заменяются параметрами макро в программе. Общий вид описания макро с параметрами:

#define Имя_Макро(Список_Параметров) Тело_Макро

Пример:

#define square(x) ((x)*(x)) /*макро с формальным параметром*/

... int i,j; ...

j=square(i); /*расширяется в j=((i)*(i)) */

Аргумент макро необходимо заключать в круглые скобки, чтобы вместо формального параметра можно было подставлять выражение. Пример "неприятности" при отсутствии скобок:

#define square(x) x*x /*макро с форм. параметром без скобок*/

... int i,j,l;...

j=square(i+l);/*расширяется в j=i+l*i+l -нет перемножения аргументов*/

Макро с параметрами похожи на процедуры - но только на первый взгляд! Отличия макро от процедур:обращение к процедуре генерируетв объектном модулекоманду безусловного перехода с возвратом и передачу параметров, обращение к макро приводит к вставкев исходную программу тела макро; поэтому применение макро увеличивает код программы, но экономит время выполнения (за счет отсутствия пересылки параметров).

Обычно не рекомендуется использовать макро вместо процедур, так как при применении макро отсутствует всякий контроль правильности подстановки параметров.

Существуют предопределенные макро, имена которых нельзя использовать в других целях. Примеры таких макро вBorland C++.

__DATE__ строка - месяц/день/год получения объектного модуля;

__TIME__ строка - часы:минуты:секунды - время начала компиляции;

__FILE__ строка, содержащая имя компилируемого файла;

__COMPACT__, __HUGE__, __LARGE__ , __MEDIUM__, __SMALL__, __TINY__ задают используемую модель памяти; причем определен один из этих макросов;

макро __сplusplus определено равным 1 для программ, компилируемым в среде Turbo C++ или Borland C++; в остальных случаях неопределено.