Урок 12.5. Другие директивы

Урок 12.5. Другие директивы

12.5. Другие директивы

Другие директивы препроцессора  Си используются значительно реже, чем директивы #define, #include, директивы условной компиляции. К ним относятся директивы #undef, #error, #pragma и пустая директива #. Общая форма записи директивы #undef:

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

Встретив директиву #undef, препроцессор считает <идентификатор> с этого момента неопределенным, то есть не подлежащим замене. Таким образом, препроцессор считает с того момента, как встретилась директива #undef, что для указанного идентификатора не выдавалась директива #define.

Пример:

#define BIG 500
. . .
#undef BIG
#define BIG 700

Если бы не было директивы #undef BIG, препроцессор выдавал бы предупреждение о переопределении константы, но так как директива #undef BIG есть, то в момент выполнения директивы #define BIG 700, BIG считается неопределенным идентификатором и никаких конфликтов не возникает.

Общая форма записи директивы #error:

#error <сообщение об ошибке>

Встретив эту директиву, компилятор прекращает свою работу и выдает следующее сообщение: Error directive:<сообщение об ошибке>

Здесь <сообщение об ошибке> – это то самое сообщение, которое указано в директиве #error.

Например:

#include "opersys.h"
#if OS==UNIX
#include "unix.h"
#else
#if OS==MSDOS
#include "msdos.h"
#else
#error "Неизвестная ОС"
#endif
#endif
. . .

 


Пусть файл opersys.h содержит следующие строки:

#define MSDOS 1
#define UNIX 2
#define CPM 3
#define OS CPM

 


При компиляции будет выдано следующее сообщение об ошибке: Error directive: " Неизвестная ОС"

Общая форма записи директивы #pragma:

#pragma warn +xxx   или
#pragma warn -xxx    или
#pragma warn .xxx

 


Директива #pragma warn +xxx разрешает компилятору выдачу предупреждения с кодовым обозначением xxx. Директива #pragma warn -xxx запрещает компилятору выдачу предупреждения с кодовым обозначением xxx. Директива #pragma warn .xxx работает как переключатель, то есть если предупреждение xxx разрешено, директива #pragma warn .xxx запрещает его, а если запрещено - разрешает.

Например:

void main()
{
int i;
i=10;
}

 


Если мы скомпилируем эту программу, компилятор предупредит нас, что переменной i присваивается значение, но переменная i нигде не используется в функции main(). Если же мы поместим в этом файле директиву препроцессора #pragma warn -aus, этого предупреждения не будет (aus – код предупреждения о том, что переменной присваивается значение, но она не используется).

Для завершенности  Си опознает пустую директиву, состоящую из строки, содержащей просто знак #. Эта директива всегда игнорируется.

Урок 12.1. Определение символических констант

12.1. Определение символических
констант

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

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

Здесь _идентификатор_ - любое имя, записанное в соответствии с
правилами Турбо Си. _строка подстановки_ - строка, на которую замещается любое
вхождение _идентификатора_. Единственное исключение - если _идентификатор_
встречается в строке, заключенной в кавычки. В этом случае _идентификатор_
считается частью символьной строки и подстановка не производится. Определения,
даваемые директивой #define имеют силу от места, где встретилась эта директива
до конца файла.

Пример:

#define STRING1 "Это строка номер
один"

main ()

{

printf ("STRING1: %s\n",STRING1);

}

В результате работы этой программы будет напечатано:

STRING1: Это строка номер один

Как видим, в первом случае STRING1
не было замещено. И произошло это потому, что STRING1 "защищено" кавычками. _строка
подстановки_ должна уместиться физически в одной строке. В противном случае ее
можно перенести на следующую строку с помощью символа \.

Например, записи

#define STRING1 "Это строка \

номер один"

и

#define STRING1 "Это строка номер
один"

совершенно идентичны.

После того, как произведена подстановка, результирующая строка снова
просматривается и если в ней есть имена, определенные с помощью директивы #define, они замещаются соответствующими
подстановками.

Например, вследующемфрагменте:

#define ADDRESS BASE+OFFSET+INDEX

#define BASE 534

#define OFFSET 612

#define INDEX 163

. . .

x=ADDRESS;

после обработки строки x=ADDRESS; препроцессором, она превращается в x=BASE+OFFSET+INDEX; , которая в свою очередь после обработки
препроцессором превращается в x=534+612+163; и в таком виде передается
компилятору,а сложение производится уже при выполнении программы.

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

Например:

int table[100]; /* количество элементов в
таблице */

 

#define NUM_ELEM 100

int table[NUM_ELEM]

Очевидно, что второе описание более наглядно, чем первое.

Урок 12.2. Опредлеление макрофункций

12.2. Опредлеление макрофункций Читать далее

Урок 12.3. Включение файлов

12.3. Включение файлов Читать далее

Урок 12.4. Условная компиляция

12.4. Условная компиляция Читать далее

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов