Язык Си - руководство для начинающих
Шрифт:
Заголовочные файлы:
Пример:
Предположим, например, что вам правится использовать булевы переменные, т. с. вместо того чтобы иметь 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, можно, если хотите, создать сжатый, хорошо огранизованный заголовочный файл. Рассмотрим этот пример:
/*заголовочный
#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.