Существует еще один момент, о котором следует предупредить читателя, - определения и объявления совместно используются несколькими файлами. Мы бы хотели, насколько это возможно, централизовать эти объявления и определения так, чтобы для них существовала только одна копия. Тогда программу в процессе ее развития будет легче и исправлять, и поддерживать в нужном состоянии. Для этого общую информацию расположим в заголовочном файле calc.h, который будем по мере необходимости включать в другие файлы. (Строка #include описывается в параграфе 4.11) В результате получим программу, файловая структура которой показана ниже:
>main.с:
>#include ‹stdio.h›
>#include ‹stdlib.h›
>#include "calc.h"
>#define MAXOP 100
>main() {
> …
>}
>calc.h:
>#define NUMBER '0'
>void push(double);
>double pop(void);
>int getop(char[]);
>int getch(void);
>void ungetch(int);
>getop.c:
>#include ‹stdio.h›
>#include ‹ctype.h›
>#include "calc.h"
>getop (){
> …
>}
>getch.c:
>#include ‹stdio.h›
>#define BUFSIZE 100
>char buf[BUFSIZE];
>intbufp = 0;
>int getch(void) {
> …
>}
>void ungetch(int) {
> …
>}
>stack.с:
>#include ‹stdio.h›
>#include "calc.h"
>#define MAXVAL 100
>int sp = 0;
>double val[MAXVAL];
>void push(double) {
> …
>}
>double pop(void) {
> …
>}
Неизбежен компромисс между стремлением, чтобы каждый файл владел только той информацией, которая ему необходима для работы, и тем, что на практике иметь дело с большим количеством заголовочных файлов довольно трудно. Для программ, не превышающих некоторого среднего размера, вероятно, лучше всего иметь один заголовочный файл, в котором собраны вместе все объекты, каждый из которых используется в двух различных файлах; так мы здесь и поступили. Для программ больших размеров потребуется более сложная организация с большим числом заголовочных файлов.
4.6 Статические переменные
Переменные sp и val в файле stack.с, а также buf и bufp в getch.с находятся в личном пользовании функций этих файлов, и нет смысла открывать к ним доступ кому-либо еще. Указание static, примененное к внешней переменной или функции, ограничивает область видимости соответствующего объекта концом файла. Это способ скрыть имена. Так, переменные buf и bufp должны быть внешними, поскольку их совместно используют функции getch и ungetch, но их следует сделать невидимыми для "пользователей" функций getch и ungetch.
Статическая память специфицируется словом static, которое помещается перед обычным объявлением. Если рассматриваемые нами две функции и две переменные компилируются в одном файле, как в показанном ниже примере:
>static char buf[BUFSIZE]; /* буфер для ungetch */
>static int bufp = 0; /* след. свободная позиция в buf */