Классы памяти (для управления механизмом использования памяти)

Каждая переменная принадлежит к одному из четырех классов памяти, которые описываются следующими ключевыми словами:

1. auto – автоматическая;

2. register – регистровая;

3. extern – внешняя;

4. static – статическая.

Тип памяти указывается модификатором – ключевым словом, стоящим перед спецификацией типа переменной.

Пример:

register int plus;

static int sum;

Если ключевого слова перед спецификацией типа локальной переменной при ее объявлении нет, то по умолчанию она принадлежит классу auto. (Поэтому практически никогда это ключевое слово не используется).

Автоматическая переменная имеет локальную область действия. Они известны только внутри блока, в котором они определены. При выходе из блока автоматические переменные пропадают, эта область памяти освобождается. Автоматические переменные хранятся в оперативной памяти.

Регистровые переменные хранятся в регистрах процессора. Доступ к переменным, хранящимся в регистровой памяти, гораздо быстрее, чем к тем, которые хранятся в оперативной памяти. Во всем остальном регистровые переменные аналогичны автоматическим переменным. Если доступных регистров нет, то переменная становится просто автоматической переменной.

В языке Си при компоновке программы (редактировании связей) к переменной может применяться одно из трех связываний: внутренне, внешнее или не относящееся ни к одному из этих типов (то есть редактирование связей к ней не применяется). В общем случае к именам функций и глобальных переменных применяется внешнее связывание. Это означает, что после компоновки они будут доступны во всех файлах, составляющих программу. К объектам, объявленным со спецификатором static и видимым на уровне файла, применяется внутреннее связывание. После компоновки они будут доступны только внутри файла, в котором они объявлены. К локальным переменным связывание не применяется и они доступны только внутри своих блоков.

Спецификатор extern указывает на то, что к объекту применяется внешнее связывание, поэтому он буде доступен во всей программе. Один и тот же объект может быть объявлен неоднократно вразных местах, но определен может быть только один раз.

Внешняя переменная extern относится к глобальным переменным. Она может быть объявлена как вне, так и внутри тела функции.

Пример:

void f()

{

extern int j; /* объявление внешней переменной внутри функции */

}

Появление ключевого слова extern связано с модульностью языка Си, то есть возможностью составлять многофайловую программу с возможностью раздельной компиляции каждого файла.

Когда в одном из файлов опишем вне тела функции глобальную переменную

float global;

то для нее выделяется место в памяти в разделе глобальных переменных и констант. Если мы используем эту глобальную переменную в другом файле, то при раздельной компиляции без дополнительного объявления переменной компилятор не будет знать, что это за переменная. Использование объявления

extern float global;

сообщает, что такая переменная будет описана в другом файле.

Пример: /* Использование спецификатора extern */

#include<stdio.h>

int main(void)

{

extern int a, b;

printf("a=%d\tb=%d\n",a,b);

return 0;

}

// описание глобальных переменных a и b

int a=10, b=20;

Отметим, что глобальные переменные a и b объявлены после main().

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

Пример: /* описание с инициализацией */

static int count=10;

Можно описать глобальную (внешнюю) статическую переменную, то есть описать переменную типа static вне любой функции.

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

Все глобальные переменные, и статические и нестатические, инициализируются нулем, если не предусмотрено другой инициализации. Локальные переменные, если нет явной инициализации, инициализируются произвольным числом.

Рассмотрим таблицу, в которой приведены область действия и продолжительность существования переменных разных классов памяти.

Класс памяти Ключевое слово Время существования Область действия
Автоматический auto временно блок
Регистровый register временно блок
Статический локальный static постоянно блок
Статический глобальный static постоянно файл
Внешний extern постоянно программа

Замечание: В программе может быть описано несколько переменных с одним и тем же именем, но в разных блоках.

Замечание: Инициализация статических переменных происходит один раз, во время первого вызова функции. При последующих вызовах повторной инициализации не происходит.

Пример: /*использование статических переменных*/

#include<stdio.h>

#include<windows.h>

float sr(float);

void main()

{

float x=1.;

char sStr[]="Введите значение x";

CharToOem(sStr,sStr);

while(x!=0)

{

printf("%s\n",sStr);

scanf("%f",&x);

if(x!=0)

printf("res=%f\n",sr(x));

}

}

float sr(float y)

{

static float res=0.0;

static int count=0;

count++;

res+=y;

return res/(float)count;

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: