622_____________________________________________Глава 11

Если предполагается, что какие-то из описанных в модуле функций могут ис-
пользоваться в других модулях, прототипы этих функций следует включать в за-
головочный файл. Тогда в модулях, использующих данные функции, достаточно
будет написать директиву #include (см. раздел 11.2.1), включающую данный заго-
ловочный файл, и не надо будет повторять прототипы функций.

Хороший стиль программирования

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

Обычно функции принимают указанное в прототипе число параметров указан-
ных типов. Однако, могут быть функции, принимающие различное число парамет-
ров (например, библиотечная функция printf) или параметры неопределенных за-
ранее типов. В этом случае в прототипе вместо неизвестного числ апараметров или
вместо параметров неизвестного типа ставится многоточие <»...». Многоточие мо-
жет помещаться только в конце списка параметров после известного числа пара-
метров известного типа или полностью заменять список параметров. Например:

int prf(char *format, ...);

Функция с подобным прототипом принимает один параметр format типа char
* (например, строку форматирования) и произвольное число параметров произво-
льного типа. Функция с прототипом

void Fp(...);

может принимать произвольное число параметров произвольного типа.

Если в прототипе встречается многоточие, то типы соответствующих парамет-
ров и их количество компилятором не проверяются.

Объявлению функции могут предшествовать спецификаторы класса памяти
extern или static. Спецификатор extern предполагается по умолчанию, так что за-
писывать его не имеет смысла. К функциям, объявленным как extern, можно по-
лучить доступ из других модулей программы (см. заключительную часть раздела
11.6.1 и раздел 1.6.5.4 в главе 1). Если же объявить функцию со спецификатором
static, например

static void F(void);

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

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

Надо иметь в виду, что все объявления в теле функции носят локальный ха-
рактер. Объявленные переменные доступны только внутри данной функции. Если
их идентификаторы совпадают с идентификаторами каких-то глобальных пере-
менных модуля, то эти внешние переменные становятся невидимыми и недоступ-
ными. В этих случаях получить доступ к глобальной переменной можно, поставка
перед ее именем два двоеточия «::», т.е. применив унарную операцию разрешения
области действия.

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