Читайте также:
|
|
Класс памяти – это механизм, который позволяет определить время жизни и область видимости объявляемого объекта. Ниже в таблице приведены классы памяти языка C, время жизни и область видимости объектов данных классов.
Класс памяти | Ключевое слово | Время жизни | Область видимости |
Автоматический | auto | временно | блок |
Регистровый | register | временно | блок |
Статический локальный | static | постоянно | блок |
Статический глобальный | static | постоянно | файл |
Внешний | extern | постоянно | файлы программы |
Автоматический объект может быть объявлен внутри блока, он имеет локальную область видимости, он видим только внутри блока, в котором объявлен, с момента объявления. Время жизни локального объекта – время выполнения блока, в котором объявлен объект. В другом блоке может использоваться тот же идентификатор для объекта, но это уже совершенно другой объект. Автоматический объект создаётся при входе в блок, при этом никакая инициализация объекта по умолчанию не производится, при выходе из блока он уничтожается, а область памяти, в которой он находился, считается свободной. Автоматические объекты хранятся в стеке. Все локальные объекты по умолчанию имеют класс памяти auto, поэтому данное слово практически никогда не используется. Автоматическим может быть объект любого типа.
Регистровый объект хранится в регистре процессора (если это возможно, если нет, то объект становится автоматическим), что уменьшает время доступа к этому объекту. Регистровым может быть не любой объект, а только такой, который может быть записан в регистры процессора (как правило, переменные типа char, int или ближний указатель). В остальном они аналогичны автоматическим объектам.
Внешний объект может быть объявлен с ключевым словом extern как на внешнем, так и на внутренним уровне, либо без ключевого слова extern на внешнем уровне. Если объект объявляется на внешнем уровне без ключевого слова extern, то это его объявление, область видимости данного объекта – весь файл, в котором он объявлен, начиная с момента объявления (он также может быть виден в других файлах, если там есть на него ссылки). Если объект объявляется с ключевым словом extern на внешнем уровне, то это ссылка на внешний объект, объявленный в другом файле программы (это сообщает компилятору, что такой объект уже существует и его создавать не надо), область видимости данного объекта – весь файл, в котором объявлена ссылка, начиная с момента объявления ссылки (а также и модуль, в котором определён объект). Если объект объявляется с ключевым словом extern на внутреннем уровне, то это ссылка на внешний объект, объявленный в другом файле программы или в этом же файле программы ниже, и область видимости данного объекта для первого случая – блок, в котором объявлена ссылка, и файл, в котором объявлен объект, а для второго случая – блок, в котором объявлена ссылка, и текущий файл начиная с момента объявления объекта. Место в памяти под внешние объекты выделяется в начале работы программы в разделе глобальных и статических объектов, их время жизни – постоянно. Внешний объект становится видимым с момента своего объявления или с момента объявления ссылки на него. Внешние объекты инициализируются явно константным выражением или нулём по умолчанию и только в одном месте программы. Внешним может быть объект любого типа.
Статический объект может быть объявлен как на внешнем, так и на внутреннем уровне. Место в памяти под статические объекты выделяется в начале работы программы в разделе глобальных и статических объектов, их время жизни – постоянно. Область видимости статических объектов, объявленных на внутреннем уровне, такая же, как и у автоматических. Отличие заключается в том, что после выхода из блока, в котором объявлен объект, он не уничтожается, и его значение продолжает храниться в памяти компьютера. Статическим может быть объект любого типа. Можно описать статический объект на внешнем уровне. Его отличие от обычного внешнего объекта состоит в том, что его область действия – только тот файл, в котором он объявлен, и он не может быть видимым в другом файле программы. Любые статические объекты инициализируются явно константным выражением или нулём по умолчанию и только в одном месте программы.
Локальное переобъявление.
Если в некотором блоке2 объявляется объект2, имя которого совпадает с именем объекта1, видимого в данном блоке2 и объявленного на внешнем уровне или на внутреннем уровне блока1, в который вложен блок2, то в пределах блока2 и всех вложенных в него блоков видим объект2, а объект1 невидим начиная с точки объявления объекта2. Обычно локальные объекты переобъявляют глобальные.
Классы памяти функций.
Определение функции всегда выполняется глобально. Функция видима в модуле начиная с момента своего определения. Объявление функции может выполняться либо глобально, либо локально. Если функция объявлена глобально, то она видима в пределах данного модуля начиная с точки объявления. Если функция объявлена локально в блоке, то она видима в данном блоке начиная с точки объявления. При этом определение функции может находиться в этом же или в другом модуле программы.
Функции могут быть объявлены и определены с классом памяти static или extern.
Функция, объявленная или определенная с классом памяти static, видима в пределах того модуля, в котором она определена. Каждая функция может вызвать другую функцию с классом памяти static из своего модуля, но не может вызвать функцию, определенную с классом static в другом модуле. Разные функции с классом памяти static имеющие одинаковые имена могут быть определены в разных модулях, и это не ведёт к конфликту. Если ключевое слово static используется только в объявлении или определении функции, то все равно считается, что класс функции – static.
Функция, объявленная или определенная, с классом памяти extern, видима в пределах данного модуля начиная с точки объявления или определения (в общем случае объявление и определение функции могут находиться в разных модулях). Если в объявлении или определении функции отсутствует спецификатор класса памяти, то по умолчанию принимается класс extern.
Все объекты с классом памяти extern компилятор помещает в объектном файле в специальную таблицу внешних ссылок, которая используется редактором связей для разрешения внешних ссылок. Часть внешних ссылок порождается компилятором при обращениях к библиотечным функциям языка C, поэтому для разрешения этих ссылок должны быть доступны соответствующие библиотеки функций.
Пример 1
Файл 1.cpp
void func1(void);
void func2(void);
extern void func3(void); // объявление функции, описанной в другом файле
int i1; //объявление внешней переменной i1
static int j; // объявление статической внешней переменной j
void main(void)
{
i1++; // изменение внешней переменной i1
extern int i2; //ссылка на внешнюю переменную i2, объявленную ниже
printf("\n%d ",++i2);
func1();
for(register int j=0;j<2;j++) /*пример регистровой переменной, закрывающей внешнюю
статическую переменную j */
{
printf("%d ",j); // печать регистровой переменной j
func2();
}
func3();
printf("%d ",i2); //печать внешней переменной i2
}
int i2; // объявление внешней переменной i2
void func1(void)
{
printf("%d ",i1);
for(auto int i1=0;i1<2;i1++) /*пример автоматической переменной, закрывающей
внешнюю переменную i1 */
{
printf("%d ",i1); // печать автоматической переменной i1
for(int i1=5;i1<7;i1++) /*пример новой автоматической переменной, закрывающей
объявленную ранее автоматическую переменную i1 */
printf("%d ",i1); // печать новой автоматической переменной i1
}
}
void func2(void)
{
static int i1=3; /*объявление статической локальной переменной, хранящей значения
между вызовами функции, которая закрывает внешнюю переменную */
printf("%d %d ",i1,++j); // печать локальной и глобальной статических переменных
i1++; // изменение значения статической локальной переменной
}
Файл 2.cpp
extern int i1; // ссылка на внешнюю переменную, объявленную в файле 1.cpp
void func3(void)
{
printf("%d ",i1); // печать внешней переменной, объявленной в файле 1.cpp
}
На экране будет напечатано: 1 1 0 5 6 1 5 6 0 3 1 1 4 2 1 1
Файлы 1.cpp и 2.cpp должны быть связаны в проекте.
Дата добавления: 2014-12-18; просмотров: 82 | Поможем написать вашу работу | Нарушение авторских прав |