Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Си массивы функции препроцессор.docx
Скачиваний:
0
Добавлен:
11.01.2020
Размер:
38.42 Кб
Скачать

5.1. Директива # define.

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

Пример .

# define TWO 2 /* определена числовая константа, равная 2*/

# define FOUR TWO*TWO

# define MSG “ это директива препроцессора ”

# define PRIN_1 cout<< “a=” << a

# define CONST1 “ a равно ”

# include <iostream.h>

/* Рассмотрим программу, использующую перечисленные директивы*/

void main ( ) Результат выполнения

{ int a=TWO;

cout << MSG; это директивы препроцессора

PRIN_1; а=2

a=FOUR;

cout << CONST1<< a; а равно 4

}

Рассмотрим формат директивы # define. Каждая строка состоит из трех частей:

1 часть- наименование директивы,

2 часть- макроопределение,

3 часть- << строка замещения >>.

# define MSG “это директива препроцессора ”

директива макроопределение срока замещения

# define TWO 2

директива макроопределение строка замещения

# define PRIN_1 cout<< “a=” << a макроопределение строка замещения

Процесс прохождения от макроопределения до заключительной строки замещения называется «макрорасширением».

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

Рассмотрим, например, две директивы

# define TWO 2;

# define FOUR TWO*TWO;

Во время выполнения программы оператор

int a= TWO превращается в оператор int a= 2;оператор a= FOUR заменяется на оператор a= TWO*TWO и затем в оператор а=2*2. Фактическое умножение произошло при работе программы.

Рассмотрим директиву # define PRIN_1 cout<< “a=” << a.

Оператор PRIN_1 превращается в строку cout<< “a=” << a и при выполнении программы на экран выводится текст и значение переменной а. Необходимо заметить, что PRIN_1 напечатает только переменную, названную а.

5.2. Использование макроопределений с аргументами.

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

Рассмотрим конкретный пример. Определим макрофункцию, вычисляющую квадрат некоторого числа.

# define SQR (x) x*x

# define PRIN (x) cout << “ x в квадрате равен ” << x

# include <iostream.h>

void main ( )

{ int x=4;

int y;

y=SQR (x); // y=x*x

PRIN (y); // cout <<“x в квадрате равен”<<y

PRIN (SQR(x)); //cout <<“x в квадрате равен”<<x*x

// Рассмотрим некоторые специфические ситуации. Результат вычисления

х=4;

PRIN (SQR(x+2)) замещение строк после компиляции 14

cout <<“x в квадрате равен”<< x+2*х+2

PRIN (100/SQR(2)) cout <<”x в квадрате равен”<<100/2*2 100

PRIN (SQR(++x) cout <<”x в квадрате равен”<<++x*++x 30

Рассмотрим каждый случай отдельно и определим причину получения «неожиданных» результатов. Для того, чтобы полученные результаты объяснить, необходимо вспомнить, что препроцессор не выполняет никаких вычислений, он только замещает строку.

Случай 1.

PRIN (SQR(x+2)); так как после компиляции получено выражение х+2*х+2, то расставив порядок действий можно понять, почему на экран выводится число 14. При х=4 получаем 4+2*4+2=14. Этот пример очень характерен, он показывает существенное отличие функции от макрофункции.

При вызове функции передается значение аргумента в программу, макровызовов передает строку аргументов в программу на первом шаге компиляции.

Для получения правильного ответа макроопределение должно быть записано следующим образом:

# define SQR (x) (x)*(x)

Случай 2.

PRIN (100/SQR(2)); Строка замещается следующей строкой cout <<”x в квадрате равен”<<100/2*2. Вычисления ведутся слева на право: 100/2=50; 50*2=100. В таком случае макроопределение необходимо записать так: # define SQR (x) (x*x).

Для получения правильного ответа для этих двух примеров, необходимо записать:

# define SQR (x) ((x)*(x)).

Случай 3.

SQR (++x) превращается в строку ++х*++х и при х=4, получаем 5*6. Операции инкремента и декремента не рекомендуется использовать при записи аргумента в макрофункции.

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

в макроопределении нет пробелов, но они могут появиться в замещающей строке, препроцессор полагает, что макроопределение заканчивается на первом пробеле, поэтому все, что стоит после пробела, остается в замещающей строке;

— использование круглых скобок для каждого аргумента и всего определения, это является гарантией того, что аргументы будут сгруппированы нужным образом;

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