обычно только некоторые из них
В файле, содержащем десятки глобальных переменных и определений подпрограмм, обычно только некоторые из них должны быть доступны вне файла. Каждому определению, которое не используется внешним образом, должен предшествовать спецификатор static (статический), который указывает компилятору, что объявленная переменная или подпрограмма известна только внутри файла:
static int g 1; /* Глобальная переменная только в этом файле */
int g2; /* Глобальная переменная для всех файлов */
static int f1 (int i) {...}; /* Глобальная функция только в этом файле */
intf2(int i) {...}; /* Глобальная функция для всех файлов */
Здесь уместно говорить об области действия файла (file scope), которая выступает в роли области действия модуля (module scope), используемой в других языках. Было бы, конечно, лучше, если бы по умолчанию принимался спецификатор static, а не extern; однако нетрудно привыкнуть приписывать к каждому глобальному объявлению static.
Источником недоразумений в языке С является тот факт, что static имеет другое значение, а именно он определяет, что время жизни переменной является всем временем выполнения программы. Как мы обсуждали в разделе 7.4, локальные переменные внутри процедуры имеют время жизни, ограниченное одним вызовом процедуры. Глобальные переменные, однако, имеют статическое время жизни, то есть они распределяются, когда программа начинается, и не освобождаются, пока программа не завершится. Статическое время жизни — нормальный режим для глобальных переменных; на самом деле, глобальные переменные, объявленные с extern, также имеют статическое время жизни!
Спецификатор static также можно использовать для локальных переменных, чтобы задать статическое время жизни:
void proc(void)
{
static bool first_time = true;
if (first_time) {
/* Операторы, выполняемые при первом вызове proc */