Выбрать главу

#include <stdio.h>      имя файла в угловых скобках

#include "mystuff.h"        имя файла в двойных кавычках

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

#include <stdio.h>            ищет в системном каталоге

#include "hot.h"             ищет в вашем текущем рабочем каталоге

#include "/usr/biif/p.h"      ищет в каталоге /usr/biff

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

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

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

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

Зачем включают файлы? Потому что они несут нужную вам информацию. Файл stdio.h, например, обычно содержит определения EOF, getchar( ) и putchar( ). Две последние Функции определены как макрофункции.

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

Заголовочные файлы:

Пример:

Предположим, например, что вам правится использовать булевы переменные, т. с. вместо того чтобы иметь 1 как "истину" и 0 как "ложь", хотели бы использовать слова TRUE и FALSE. Можно создать файл, названный, скажем, bool.h, который содержал бы эти определения:

/* файл bool.h */

#define BOOL int;

#define TRUE 1

#define FALSE 0

Вот пример программы, использующей этот заголовок:

/* считает пустые символы */

#include <stdio.h>

#include "bool.h"

main( )

{

int ch;

int count = 0;

BOOL whitesp( );

while((ch = getchar( )) != EOF)

    if(whitesp(ch)) count++;

printf(" Имеется %d пустых символов. \n", count);

}

BOOL whitesp(c)

char c;

if(c == '   ' || с == '\n' || с == '\t')

return(TRUE);

else

return(FALSE);

}

Замечания по программе

1. Если две функции в этой программе ('main( )' и 'whitesp( )') следовало скомпилировать раздельно, то нужно было бы использовать директиву #include "bool.h" с каждой из них.

2. Выражение if(whitesp(ch)) аналогично if(whitesp(ch)) == TRUE, так как сама функция whitesp(ch) имеет значение TRUE или FALSE.

3. Мы не создали новый тип BOOL, так как BOOL уже имеет тип int. Цель наименования функции BOOL - напомнить пользователю, что функция используется для логических вычислений (в противоположность арифметическим).

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

5. Мы могли бы использовать макроопределение вместо функции для задания whitesp( ).

     Многие программисты разрабатывают свои стандартные заголовочные файлы, чтобы использовать их в программах. Некоторые файлы могут создаваться для специальных целей, другие можно использовать почти в каждой программе. Так как включенные файлы могут содержать директивы #include, можно, если хотите, создать сжатый, хорошо огранизованный заголовочный файл. Рассмотрим этот пример:

/*заголовочный файл mystuff.h*/

#include

#include "bool.h"

#include "funct.h"

#define YES 1

#define NO 0

Во-первых, мы хотим напомнить вам, что препроцессор языка Си распознает комментарии, помеченные /* и */, поэтому мы можем включать комментарии в эти файлы.

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

В-третьих, мы определили YES как 1, тогда как в файле bool.h мы определили TRUE как 1. Но здесь нет конфликта, и мы можем использовать слова YES и TRUE в одной и той же программе. Каждое из них будет заменяться на 1. Может возникнуть конфликт, если мы добавим в файл строку

#define TRUE 2

Второе определение вытеснило бы первое, и некоторые препроцессоры предупреждали бы вас, что TRUE переопределено.

Директива #include не ограничивается заголовочными файлами. Если вы записали нужную функцию в файл sort.с, то можно использовать

#include "sort.с"

чтобы скомпилировать его совместно с вашей текущей программой.

     Директивы #include и #define являются наиболее активно используемыми средствами препроцессора языка Си. Рассмотрим более сжато другие его директивы.

ДРУГИЕ ДИРЕКТИВЫ: #undef, #if, #ifdef, #ifndef, #else И #endif

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

     Директива #undef отменяет самое последнее определение поименованного макроопределения.

#define BIG 3

#define HUGE 5

#undef BIG              /* BIG теперь не определен */

#define HUGE 10        /* HUGE переопределен как 10 */

#undef HUGE           /* HUGE снова равен 5*/

#undef HUGE           /* HUGE теперь не определен */

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