Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Программирование -> C / C++ -> Книга по Си


Препроцессор языка Си

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

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

  Замена лексических единиц. Командная строка вида #define name text вызывает в оставшейся части программы замену всех вхождений идентификатора name на строку text. Например, определение #define p1 3.14159265 позволяет использовать в программе имя p1 вместо константы 3.14159265. Обратите внимание, что это определение не завершается точкой с запятой. Замещающий текст обычно представляет собою остаток строки. Длинное определение можно продолжить, если в конце продолжаемой строки поставить \. Внутри строк, заключенных в кавычки, подстановка не производится, так что, например, для определенного выше имени P1 в printf("P1"); подстановки не будет. Имена могут переопределяться и новые определения могут использовать ранее введенные определения.

   Так как препроцессор не является частью компилятора языка Си, а представляет относительно простой макрогенератор, имеется возможность переопределять различные синтаксические единицы языка-лексемы (т.е. идентификаторы, ключевые слова, константы, цепочки литер, знаки операций и знаки пунктуаций). В приведенной (на примере 6.2) программе, предназначенной для выявления всех пар целых чисел из интервала [-n,n], являющихся решениями уравнения 2*y-x*x =4 , используются привычные для таких языков как Алгол, Паскаль, операторные скобки begin-end вместо пары {}, ключевое слово then . Это стало возможным благодаря предварительно определенным лексическим заменам.

Пример 6.2

#include <stdio.h>
#define then
#define begin {
#define end }
main()
begin
int n,x,y,k=0;
printf("введи n\n");scanf("%d",&n);
for(x=-n;x<=n;x++)
for(y=-n;y<=n;y++)
  if(2*y-x*x==4)then
   begin
    k=k+1;
    printf(x=%d, y=%d\n",x,y);
   end
if(k==0) then
printf("корней нет\n ");
end

Приведенная выше технология замены лесксем относится к макросредствам языка. Строка #define  name text называется макроопределением, name называется макрошаблоном, а text - макрорасширением. Каждое появление имени name в теле программы называется макровызовом. Командная строка

            #define name (p1,p2, ..,pk) text

является макроопределением с аргументами. За именем name в круглых скобках (после name не должно быть пробела!) следует разделенные запятыми формальные параметры p1, p2 .., pk, также являющиеся идентификаторами. Каждый раз, когда в тексте программы встречается имя макроопределения с фактичкскими аргументами, они подставляются вместо формальных, так что заменяющий текст будет зависеть от вида макровызова. Определим в качестве примера такую макроподстановку:

  #define MAX(X,Y) ((X)>(Y)?(X):(Y))

Как и в определении функции, переменные X и Y в макроопределении являются формальными параметрами. После этого строка в программе:

       m=MAX(a+b, a-b);

будет заменена на строку

m=((a+b)>(a-b)?(a+b):(a-b);

Текст макроопределения берут в скобки для обеспечения большей надежности программы. Пренебрежение скобками может привести к серьезным ошибкам, что иллюстрирует следующий пример 6.3. делит число 16 на квадрат числа 2 и дает правильный результат. Во второй программе (пример 6.4), где скобки в макроопределении опущены, результат ошибочный, так как макроподстановка породила текст:

       printf("%d\n",16/2*2);

что конечно, не равносильно задуманному.

     Пример 6.3

  #include <stdio.h>
#define SQR(n) (n*n)
main()
{
printf("%d\n",16/SQR(2));
}

Пример 6.4

#include <stdio.h>
#define SQR(n) n*n
main()
{
printf("%d\n",16/SQR(2));
}

      Макроопределения иногда используются вместо определений функций, обычно из сображений эффективности. Но следует помнить, что препроцесор может лишь тупо и бездумно заменять одну строку на другую, не разбираясь, зачем это нужно. В отличае от параметра функции, параметр макроопределения вычисляется при каждом вхождении в макроопределение. Поэтому иакровызов MAX(i++, j++)  для приведенного выше макроопределения к увеличению i и j на 2.

< Дальше >

 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.