Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Общие сведения. В интегрированную среду подготовки программ на Си или в компилятор языка как обязательный компонент входит препроцессор

В интегрированную среду подготовки программ на Си или в компилятор языка как обязательный компонент входит препроцессор. Назначение препроцессора - обработка исходного текста программы до ее компиляции. Препроцессор можно использовать для настройки языка программирования под отдельное приложение или стиль программиста. Препроцессорная обработка включает несколько стадий, выполняемых последовательно. Конкретная реализация может объединять несколько стадий, но результат должен быть таким, как если бы они выполнялись в следующем порядке:

1. Все системно-зависимые обозначения перекодируются в стандартные коды.

2. Каждая пара из символов ' \ ' и "конец строки" вместе с пробелами между ними убираются, и тем самым следующая строка исходного текста присоединяется к строке, в которой находилась эта пара символов.

3. В тексте распознаются директивы и лексемы препроцессора, а каждый комментарий заменяется одним символом пустого промежутка.

4. Выполняются директивы препроцессора и производятся макроподстановки.

5. Эскейп-последовательности в символьных константах и символьных строках заменяются на их эквиваленты.

6. Смежные символьные строки конкатенируются, то есть соединяются в одну строку.

7. Каждая препроцессорная лексема преобразуется в текст на языке Си.

Поясним, что понимается под препроцессорными лексемами или лексемами препроцессора. К ним относятся символьные константы, имена включаемых файлов, идентификаторы, знаки операций, препроцессорные числа, знаки препинания, строковые константы и любые символы, отличные от пробела.

При обработке директив процессора выполняются следующие действия:

· замена идентификаторов заранее подготовленными последовательностями символов;

· включение в программу текстов из указанных файлов;

· исключение из программы отдельных частей ее текста, условная компиляция;

· макроподстановка, то есть замена обозначения параметризованным текстом, формируемым препроцессором с учетом конкретных аргументов.

Символические константы: утверждение #define

Если в качестве первого символа в строке программы используется символ #, то эта строка является командной строкой препроцессора (макропроцессора). Командная строка препроцессора заканчивается символом перевода на новую строку. Если непосредственно перед концом строки поставить символ обратной косой черты " \ ", то командная строка будет продолжена на следующую строку программы.

Директива #define, подобно всем директивам препроцессора, начинается c символа # в самой левой позиции. Она может появиться в любом месте исходного файла, а даваемое определение имеет силу от места появления до конца файла или до директивы undef. Одним из основных применений утверждения define является присваивание символических имен константам программы.

Пример:

#define ABC 100

Заменяет каждое вхождение идентификатора ABC в тексте программы на 100:

#define YES 1

Заменяет каждое вхождение идентификатора YES в тексте программы на 1.

Действие утверждения define отменяет утверждение undef: #undef идентификатор

Пример: #undef ABC // отменяет предыдущее определение для идентификатора ABC.

 

Пример:

/* Простые примеры директивы препроцессора */#define TWO 2 /* можно использовать комментарии*/#define MSG "Текст 1"#define FOUR TWO*TWO#define PX printf("X равен %d.\n", x)#define FMT "X равен %d.\n"main(){ int x = TWO; PX; x = FOUR; printf(FMT,x); printf("%s\n",MSG); printf("TWO:MSG\n");}

В результате выполнения нашего примера будем иметь:

X равен 2X равен 4Текст 1TWO: MSG

 

Разберем, что произошло. Оператор

int x = TWO;

превращается в

int x = 2;

Затем оператор

PX;

превращается в

printf("X равно %d.\n",x);

поскольку сделана полная замена. Теперь мы видим, что макроопределение может представлять любую строку, даже целое выражение на языке Си. Заметим, что это константная строка. PX напечатает только переменную, названную x.

В следующей строке выполняется следующее:

x = FOUR;

превращается

x = TWO*TWO;

превращается в

x = 2*2;

и на этом все заканчивается. Фактическое умножение имеет место не во время работы препроцессора и не при компиляции, а всегда без исключения при работе программы. Препроцессор не выполняет вычислений. Он только очень точно делает предложенные подстановки. Заметим, что макроопределение может включать другие определения (в примере в FOUR используется TWO). Некоторые компиляторы не поддерживают это свойство вложения.

В следующей строке

printf(FMT,x);

превращается в

printf("X равно %d.\n",x)

когда FMT заменяется соответствующей строкой.

Этот подход может оказаться очень удобным, если есть длинная строка, которую мы используем несколько раз. В следующей строке программы MSG заменяется соответствующей строкой. Кавычки делают замещающую строку константой символьной строки. Поскольку программа получает ее содержимое, эта строка будет запоминаться в массиве, заканчивающемся нуль-символом. Так,

#define HAL 'X' определяет символьную константу, а #define HAR "X" определяет символьную строку X\0

Обычно препроцессор, встречая одно из макроопределений в программе, очень точно заменяет их эквивалентной строкой замещения. Если эта строка также содержит макроопределения, они тоже замещаются. Единственным исключением при замене является макроопределение, находящееся внутри двойных кавычек. Поэтому

printf("TWO: MSG");

печатает буквально TWO: MSG вместо печати следующего текста:

2: "Текст 1.Продолжение текста 1"

Если нам нужно напечатать этот текст, можно использовать оператор

printf("%d: %s\n",TWO,MSG);

потому что здесь макроопределения находятся вне кавычек.

Когда следует использовать символические константы? Вероятно, мы должны применять их для большинства чисел. Если число является константой, используемой в вычислениях, то символическое имя делает яснее ее смысл. Если число - размер массива, то символическое имя упрощает изменение вашей программы при работе с большим массивом. Если число является системным кодом, скажем для символа EOF, то символическое представление делает программу более переносимой. Изменяется только определение EOF. Мнемоническое значение, легкость изменения, переносимость: все это делает символические константы заслуживающими внимания!

Обычно утверждения define печатаются первыми в программе, однако это не обязательно, они могут находиться в любом месте программы.

Негласное правило: символические константы обозначаются заглавными буквами.

<== предыдущая лекция | следующая лекция ==>
Видовые, сигнальные и веществен­ные демаскирующие признаки | Использование аргументов с #define
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 279; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.017 сек.