Язык программирования Си (Ритчи, Керниган) - страница 69

Существует еще один момент, о котором следует предупредить читателя, - определения и объявления совместно используются несколькими файлами. Мы бы хотели, насколько это возможно, централизовать эти объявления и определения так, чтобы для них существовала только одна копия. Тогда программу в процессе ее развития будет легче и исправлять, и поддерживать в нужном состоянии. Для этого общую информацию расположим в заголовочном файле 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 */