Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР7.doc
Скачиваний:
1
Добавлен:
13.11.2018
Размер:
71.17 Кб
Скачать

2.3 Классы памяти

2.3.1. Классы памяти функций

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

doublegamma(); // внешняя функция по умолчанию

static double beta();

extern double delta();

Функция gamma() и delta() могут использоваться функциями из других файлов, которые являются частью программы, тогда как beta() – нет. В силу этого применение функции beta() ограничено одним файлом, поэтому в других файлах можно использовать функции с тем же именем. Одна из причин использования класса статической памяти заключается в необходимости создания функций, приватных для конкретных модулей, благодаря чему во многих случаях удается избежать конфликта имен.

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

2.3.2. Классы памяти переменных

Рассмотрим различные классы памяти, соответствующие различным переменным в программе на С.

2.3.2.1. Класс памяти auto: локальные переменные

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

void f(void)

{

int a;

....

}

void f(void)

{

autoint a;

....

}

Если переменной не присвоено значение при определении (как в примере выше), её значение будет не определено (в ней будет содержаться «мусор» из памяти).

Автоматические переменные теряют своё значение при выходе из блока, в котором они были определены.

2.3.2.2. Локальные переменные с модификатором static

Если локальная переменная (переменная внутри функции) определена с модификатором static( например, staticinta;), то она будет сохранять своё значение между вызовами функции. Инициализация такой переменной сработает только при первом вызове функции, а если переменной не присвоено значение при её определении, её значением будет ноль.

В следующем примере counter считает, сколько раз была вызвана функция f:

void f(void)

{

staticint counter;

counter++;

}

2.3.2.3. Глобальные переменные

Глобальные переменные определяются вне функций. Они существуют в памяти на протяжении всей работы программы. Если глобальной переменной не присвоено значение при её определении, она будет равна нулю. Чтобы глобальная переменная была «видна» из другого файла (другой единицы компиляции), в другом файле она должна быть объявлена как extern.

2.3.2.4. Глобальные переменные с модификатором static

Если глобальная переменная (переменная вне функций) определена с модификатором static, она будет доступна только из того файла, в котором она определена. Из других файлов получить доступ к ней не получится даже с использованием extern.

Такие переменные удобно использовать для хранения данных, общих для функций из одного файла, но не предназначенных для использования другими функциями. Например, реализация стека на связном списке (функции push, pop, empty) могут обращаться к первому элементу списка (head), но тем, кто использует стек, эта переменная не нужна, следовательно, её можно определить с модификатором static.

Модификатор static так же можно использовать при определении функций; такие функции тоже будут доступны только из того файла, в котором они были определены.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]