Локальные переменные, которые мы применяли до сих пор, попадают в категорию автоматической продолжительности хранения. Например, в следующем коде переменные number и index появляются каждый раз, когда функция bore() вызывается, и исчезают после ее завершения:
void bore(int number)
{
int index;
for (index = 0; index < number; index++) puts("Выполнение привычной работы.\n");
return 0;
}
Тем не менее, переменная может иметь область видимости в пределах блока, но статическую продолжительность хранения. Чтобы создать такую переменную, объявите ее внутри блока и добавьте в объявление ключевое слово static:
void more(int number)
{
int index;
static int ct = 0;
return 0;
}
Здесь переменная ct хранится в статической памяти; она существует с момента загрузки программы в память и вплоть до завершения выполнения программы. Но область видимости ct ограничена блоком функции more(). Только во время выполнения этой функции программа может использовать переменную ct для доступа к объекту, который она обозначает. (Тем не менее, можно разрешить непрямой доступ, позволив функции предоставить адрес хранилища другим функциям, например, с помощью параметра типа указателя или возвращаемого значения.)
Область видимости, связывание и продолжительность хранения используются в С в целях определения нескольких схем хранения для переменных. В этой книге не рассматривается параллельное программирование, поэтому мы не будем касаться данного аспекта. Выделенная продолжительность хранения будет обсуждаться позже в главе. В итоге остаются пять классов хранения: автоматический, регистровый, статический с областью видимости в пределах блока, статический с внешним связыванием и статический с внутренним связыванием. Комбинации представлены в табл. 12.1.
486 Глава 12
Таблица 12.1. Пять классов хранения

Теперь, когда мы раскрыли понятия области хранения, связывания и продолжительности хранения, можно переходить к более детальным исследованиям этих классов хранения.
Автоматические переменные
Переменная, принадлежащая к автоматическому классу хранения, имеет автоматическую продолжительность хранения, область видимости в пределах блока и не имеет связывания. По умолчанию любая переменная, объявленная в блоке или в заголовке функции, относится к автоматическому классу хранения. Однако вы можете совершенно ясно сформулировать свои намерения, явным образом указав ключевое слово auto:
int main(void)
{
auto int plox;
Эго можно делать, скажем, для документирования того факта, что вы намеренно переопределяете внешнюю переменную, или для подчеркивания важности того, что класс хранения переменной не должен изменяться. Ключевое слово auto называется спецификатором класса хранения. В C++ ключевое слово auto предназначено для совер шенно другой цели, поэтому просто не применяйте auto в качестве спецификатора класса хранения, чтобы добиться большей совместимости между С и C++.
Область видимости в пределах блока и отсутствие связывания подразумевает, что доступ к этой переменной по имени может осуществляться только в блоке, где переменная определена. (Конечно, посредством аргументов значение и адрес переменной можно передать в другую функцию, но это будут уже косвенные сведения.) В другой функции может использоваться переменная с тем же самым именем, но это будет независимая переменная, хранящаяся в другой ячейке памяти.
Как вы, возможно, помните, автоматическая продолжительность хранения означает, что переменная начинает свое существование, когда поток управления входит в блок, который содержит объявление этой переменной. После того как поток управления покинет блок, автоматическая переменная исчезнет. Ячейка памяти, которую она занимала, может применяться для чего-то другого, хотя и необязательно.
Классы хранения, связывание и управление памятью 487
Давайте более внимательно посмотрим на вложенные блоки. Переменная известна только в блоке, в котором она объявлена, и в любых блоках, размещенных внутри этого блока:
int loop(int n)
{
int m; // m находится в области видимости
scanf ("%d", &m);
{
int i; // и m, и i находятся в области видимости
for (i = m; i < n; i++)
puts("i is local to a sub-block\n");
}
return m; // m в области видимости, i исчезла
}
В данном коде переменная i является видимой только во внутренних скобках. Если вы попытаетесь воспользоваться этой переменной до или после внутреннего блока, компилятор сообщит об ошибке. Обычно такой прием при проектировании программ не применяется. Тем не менее, временами удобно определять переменную в подблоке, если она не используется в других местах. В этом случае можно документировать назначение переменной близко к месту ее применения.
Читать дальше