Лекция: Общее знакомство

Вид материалаЛекция

Содержание


Включение файла: #include
Командная строка
Условная компиляция
Вспомогательные директивы
Реакция на ошибки
Пустая директива # Использование этой директивы не вызывает никаких действий. Прагмы
Подобный материал:
1   ...   19   20   21   22   23   24   25   26   ...   33
^

Включение файла: #include


Перечень обозначений заголовочных файлов для работы с библиотеками компиляторов утвержден стандартом языка. Ниже приведены названия этих файлов, а также краткие сведения о тех описаниях и определениях, которые в них включены. Большинство описаний - прототипы стандартных функций, а определены в основном константы, например EOF, необходимые для работы с библиотечными функциями.

assert.h - диагностика программ

ctype.h - преобразование и проверка символов

errno.h - проверка ошибок

float.h - работа с вещественными данными

limits.h - предельные значения целочисленных данных

locate.h - поддержка национальной среды

math.h - математические вычисления

setjump.h - возможности нелокальных переходов

signal.h - обработка исключительных ситуаций

stdarg.h - поддержка переменного числа параметров

stddef.h - дополнительные определения

stdio.h - средства ввода-вывода

stdlib.h - функции общего назначения (работа с памятью)

string.h - работа со строками символов

time.h - определение дат и времени

В конкретных реализациях количество и наименование заголовочных файлов могут быть и другими. Например, в компиляторах для MS-DOS активно используются заголовочные файлы mem.h, alloc.h, conio.h, dos.h и другие. В компиляторах Turbo C, Borland C++ для связи с графической библиотекой применяется заголовочный файл graphics.h.

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

#include <имя_файла>

Пример:

#include

Процессор заменяет эту строку содержимым файла math.h. Угловые скобки означают, что файл math.h будет взят из некоторого стандартного каталога (обычно это /usr/include). Текущий каталог не просматривается:

#include "имя_файла"

Пример:

#include "ABC"

Препроцессор заменяет эту строку содержимым файла ABC. Так как имя файла заключено в кавычки, то поиск производится в текущем каталоге (в котором содержится основной файл исходного текста). Если в текущем каталоге данного файла нет, то поиск производится в каталогах, определенных именем пути в опции -1 препроцессора. Если и там нет файла, то просматривается стандартный каталог.

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

В конкретных реализациях количество и наименования заголовочных файлов могут быть разными:

#include ищет в системном каталоге

#include "my.h" ищет в текущем рабочем

каталоге

#include "/user/1/my.h" ищет в каталоге /user/1

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

#include "stdio.h" ищет на стандартном диске

#include ищет на стандартном диске

#include "a:stdio.h" ищет на диске а

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

Некоторые файлы включены в систему, например, stdio.h, но можно создать и свой файл.

Многие программисты разрабатывают свои стандартные заголовочные файлы, чтобы использовать их в программах.
^

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


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

#if константное_выражение

Пример:

#if ABC + 3

Истина, если константное выражение ABC + 3 не равно нулю.

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

Пример:

#ifdef ABC

истина, если идентификатор ABC определен ранее командой #define.

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

Пример:

#ifndef ABC

истина, если идентификатор ABC не определен в настоящий момент.

#else

. . .

#endif

Если предшествующие проверки #if, #ifdef или #ifndef дают значение "Истина", то строки от #else до #endif игнорируются при компиляции.

Если эти проверки дают значение "Ложь", то строчки от проверки до #else (а при отсутствии #else - до #endif) игнорируются.

Команда #endif обозначает конец условной компиляции.

Пример:

#ifdef DEBUG

fprintf (stderr, "location: x = %d\n", x);

#endif
^

Вспомогательные директивы

Номер строки и имя файла


#line целая_константа "имя_файла"

Пример:

#line 20 "ABC"

Препроцессор изменяет номер текущей строки и имя компилируемого файла. Имя файла может быть опущено.

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

Пример:

#define N 3/*определение константы */

void main( )

{

#line 55 "file.c"

double x[3*N];

}
^

Реакция на ошибки


#error последовательность лексем

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

Пример:

#define NAME 15

В дальнейшем можно проверить ее значение и выдать сообщение, если у NAME окажется другое значение:

#if (NAME !=15)

#error NAME должно быть равно 15!

Сообщение будет выглядеть так:

error <имя_файла><номер_строки >;

error directive: NAME должно быть равно 15!
^

Пустая директива


#

Использование этой директивы не вызывает никаких действий.

Прагмы


#pragma

Эта директива определяет действия, зависящие от конкретной реализации компилятора. Например в некоторые компиляторы входит вариант этой директивы для извещения компилятора о наличии в тексте программы команд на языке Ассемблер. Возможности команды #pragma могут быть разнообазными. Стандарта для них не существует. Если конкретный препроцессор встречает прагму, которая ему неизвестна, он ее просто игнорирует как пустую директиву. В некоторых реализациях включена прагма.

#pragma pack(n), где n= 1,2,4. Прагма pack позволяет влиять на упаковку смежных элементов в структурах и объединениях (см. лекцию 14).

Соглашение может быть таким:

pack(1) - выравнивание элементов по границам байтов;

pack(2) - выравнивание элементов по границам слов;

pack(4) - выравнивание элементов по границам двойных слов;

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