АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Директива # include, # define, # undef

Читайте также:
  1. ГАРМОНІЗАЦІЯ ЗАКОНОДАВСТВА УКРАЇНИ З ДИРЕКТИВАМИ ЄС
  2. Директива Ставки главного командования № 91/НГШ Военному совету Северного фронта о подготовке обороны на подступах к Ленинграду. 4 июля 1941 г.
  3. Европейская Директива по вопросу об опасности крупных аварий при определенной промышленной деятельности
  4. Структура программ на языке Си. Директива процессора, комментарии.

Теоретические сведения.

 

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

Директива # include, # define, # undef.

 

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

Его команда:

# include “имя файла”

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

Рассмотрим другую директиву препроцессора

# define <идентификатор> <подстановка>

Эта директива вызывает замену в последующем тексте названного идентификатора на текст подстановка.

Если директива имеет вид:

# define идентификатор (идентификатор,…идентификатор)

то это определение макроподстановки с аргументами. Её использование рассматривается ниже на примерах.

Пример 1.

# include<stdio.h>

#include <conio.h>

#include <iostream.h>

# define TWO 2

# define FOOR TWO*TWO

# define PX printf(“x равен %d\n”,x)

#define FNT “x равен % d\n”

main ()

{

int x=TWO;

PX;

printf(FNT,x);

getch();

return 0;

}

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

Х равен 2

Х равен 4

Рассмотрим подробно, что произошло при выполнении программы.

Оператор

int x=TWO; превращается в int x=2;

Т.е. слово TWO заменилось цифрой 2

Оператор

PX; превращается в printf(“x равно %d\n”,x);

Оператор

x=FOOR; превращается в x=TWO*TWO.

а далее в х=2*2;

Оператор

printf(FNT,X);превращается в printf(“x равен %d\n”,x);

Рассмотрим пример директивы # define с аргументами. Работать с такими директивами нужно внимательно, в противном случае можно получить неожиданные результаты.

Покажем это на примере:

Пример 2.

# include<stdio.h>

#include <conio.h>

#include <iostream.h>

# define SQUARE(X) X*X

# define PR(X) printf(“d\n”,X)

# define writeln(A) printf(A)

main ()

{

int x=4;

int z;

z=SQUARE(x);

writeln("z=");

PR(z);

writeln("SQUARE(x)=");

PR(SQUARE(x));

writeln("SQUARE(x+2)=");

PR(SQUARE(x+2));

writeln("100/SQUARE(x)=");

PR(100/SQUARE(x));

getch();

return 0;

}

Всюду, где в программе SQUARE(x) оно заменяется на x*x.

Результат работы программы:

z равно 16

Z равно 4

SQUARE (x+2) равно 14

100/SQUARE (2) равно 100

Первые две строки предсказуемы. Заметим, что даже внутри кавычек в определении PR переменная замещается соответствующим аргументом.

Строка

PR(SQUARE (x));

замещается на следующую

printf(“%d\n”,SQUARE (x));

после первого этапа макрорасширения. Второе SQUARE (х) превращается в Х*Х, а первое остаётся без изменении, потому что теперь находится внутри кавычек в операторе программы и защищено от дальнейшего расширения. Окончательно строка программы содержит printf(“%d\n”,X*X); и выводит на экран.

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

Вспомним, что Х имеет значение 4. Это позволяет предположить, что SQUARE (Х+2) будет равно 6*6 или 36. Но напечатанный результат говорит, что получается 14. Причина этого несоответствия состоит в том, что препроцессор не делает вычислении, он только замещает сторону, таким образом, везде вместо Х будет подставлено Х+2. Значит Х*Х ставится Х+2*Х+2. Если Х равен 4, то 4+2*4+2=14

Если всё-таки требуется, чтобы SQUARE (х+2) было равно 36, то необходимо записать так:

# define SQUARE(X) (X)*(X)

Тогда SQUARE (Х+2) становится (Х+2)*(Х+2), и мы получим желаемый результат.

Рассмотрим следующий результат. Выражение 100/SQUARE (Х) превращается в 100/2*2, т.е. равно 100.

Эту путаницу можно исправить, определив SQUARE (Х) следующим образом

# define SQUARE (X) (X)*(X)

это даёт 100/(2*2)

Чтобы выполнить два последующих примера, нам необходимо определение

# define SQUARE (Х) (Х)*(Х)

Пример 3. В приведённой программе открывающая и закрывающая фигурные скобки заменены словами begin и end. Определены также другие названия для функции ввода-вывода. В результате получилось что-то среднее между программой на Паскале и СИ. Таким образом, пользователь, работающий с другим языком может строить привычные для себя конструкции.

# include <stdio.h>

# define write(valw) printf(“%d”,valw) /*выполняется замена строки write(valw) на строку printf(“%d”,valw)*/

# define read(valr) scanf (“%d”,&valr) /* выполняется замена строки read(valr) на строку scanf(“%d”,&valr)*/

# define begin { /* выполняется замена слова begin на скобку {*/

# define end } /* выполняется замена слова end на скобку }*/

main ()

begin

int i;

read (i); /*вводится с клавиатуры значение переменной i */

write (i); /*выводится на экран значение i */

end

 

Директива #undef отменяет самое последнее определение поименованного макроопределения. Она имеет следующий вид:

#undef идентификатор

где идентификатор –идентификатор, раннее определённый в директиве #define. Например:

#undef ESCAPE

после выполнения этой процедуры идентификатор ESCAPE становится неопределённым.

 


Поиск по сайту:



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