КЛАССЫ ПАМЯТИ И ОБЛАСТЬ ДЕЙСТВИЯ
Мы уже упоминали раньше, что локальные переменные известны только функциям, содержащим их. В языке Си предполагается также, что о глобальных переменных "знают" сразу несколько функций. Предположим, например, что и main( ), и critic( )имеют доступ к переменной units. Это будет иметь место, если отнести unitsк "внешнему" классу памяти, как показано ниже:
/* глобальная переменная units */
int units; /* внешняя переменная */
main( )
{
extern int units;
printf (" Сколько фунтов масла находится в бочонке?\n");
scanf (" %d" , &units);
while (units != 56) critic( );
printf(" Вы должны поискать в справочнике !\n");
} critic( )
{
extern int units;
printf (" He повезло, дружок. Попытайся снова.\n");
scanf (" %d" , &units);
}
Вот полученный результат:
Сколько фунтов масла находится в бочонке?
14
Не повезло, дружок. Попытайся снова.
56
Вы должны поискать в справочнике!
(Мы сделали это.)
Обратите внимание, что второе значение units было прочитано функцией critic( ), однако main()также "узнала" это новое значение, когда оно вышло из цикла while.
Мы сделали переменную unitsвнешней, описав ее вне любого определения функции. Далее, внутри функций, использующих эту переменную, мы объявляем ее внешней при помощи ключевого слова extern, предшествующего спецификации типа переменной. Слово extern предлагает компьютеру искать определение этой переменной вне функции. Если бы мы опустили ключевое слово extern в функции critic( ), то компилятор создал бы в функции criticновую переменную и тоже назвал бы ее units. Тогда другая переменная units()[которая находится в main()] никогда не получила бы нового значения.
Каждая переменная, как мы знаем, имеет тип. Кроме того, каждая переменная принадлежит к некоторому классу памяти. Есть четыре ключевых слова, используемые для описания классов памяти: extern(для внешнего), auto(для автоматического), staticи register. До сих пор мы не обращали внимание на классы памяти, так как переменные, описанные внутри функции, считались относящимися к классу auto, если они не описывались иначе (по умолчанию они относились к классу auto).
Определение класса памяти переменной зависит oт того, где переменная описана и какое ключевое слово (если оно есть) используется.
Класс памяти позволяет установить два факта. Во-первых, определить, какие функции имеют доступ к переменной. (Пределы, до которых переменная доступна, характеризуют ее "область действия".) Во-вторых, определить, как долго переменная находится в памяти. Теперь перейдем к свойствам каждого типа.
Автоматические переменные
По умолчанию переменные, описанные внутри функции, являются автоматическими. Можно, однако, это подчеркнуть явно с помощью ключевого слова auto:
main( )
{
auto int plox;
Так поступают, если хотят, например, показать, что определение переменной не нужно искать вне функции.
Автоматические переменные имеют локальную область действия. Только функция, в которой переменная определена, "знает" ее. (Конечно, можно использовать аргументы для связи значения и адреса переменной с другой функцией, однако это частичное и косвенное "знание".) Другие функции могут использовать переменные с тем же самым именем, но это должны быть независимые переменные, находящиеся в разных ячейках памяти.
Автоматическая переменная начинает существовать при вызове функции, содержащей ее. Когда функция завершает свою работу и возвращает управление туда, откуда ее вызвали, автоматическая переменная исчезает. Ячейка памяти может снова использоваться для чего-нибудь другого.
Следует еще сказать об области действия автоматической переменной: область действия ограничена блоком ({ }), в котором переменная описана. Мы всегда должны описывать наши переменные в начале тела функции (блока), так что областью действия их является вся функция. Однако в принципе можно было бы описать переменную внутри подблока. Тогда переменная будет известна только в этой части функции. Обычно при создании программы, программисты редко принимают во внимание упомянутое свойство. Но иногда торопливые программисты пользуются такой возможностью, особенно когда пытаются быстрее внести коррективы.
Переменная, описанная вне функции, является внешней. Внешнюю переменную можно также описать в функции, которая использует ее, при помощи ключевого слова extern. Описания могут выглядеть примерно так:
Читать дальше