Читать «Полный справочник по С++» онлайн - страница 23

Герберт Шилдт

int series(void)

{

static int series_num;

series_num = series_num+23;

return series_num;

}

В этом примере переменная series_num продолжает существовать между вызовами функции, а локальная переменная каждый раз создавалась бы при входе и уничтожалась при выходе из функции. Таким образом, каждый вызов функции series () порождает новый элемент ряда, используя предыдущее значение и не прибегая к глобальной переменной.

Локальную статическую переменную можно инициализировать. Начальное значение присваивается лишь один раз, а не при каждом входе в блок, как это происходит с локальными переменными. Например, в приведенной ниже версии функции series () переменная series_num инициализируется числом 100.

int series(void)

{

static int series_num = 100;

series_num = series_num+23; return series_num;

}

Теперь ряд будет всегда начинаться с числа 123. Хотя во многих приложениях это вполне приемлемо, обычно генераторы чисел предоставляют пользователю право выбора начального значения. Для этого можно сделать переменную series_num глобальной. Однако именно для того, чтобы избежать этого, и были созданы статические переменные. Это приводит ко второму способу использования статических переменных.

Глобальные статические переменные

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

Чтобы проиллюстрировать применение глобальной статической переменной, перепишем генератор чисел из предыдущего раздела таким образом, чтобы начальное значение задавалось при вызове функции series_start(). Весь файл, содержащий функции seriesO, series_start () И series_num(), показан ниже.

/* Все функции должны находиться в одном и том же файле. */

static int series_num; void series_start(int seed); int series(void);

int series(void)

{

series_num = series_num+23; return series_num;

}

/* Инициализация переменной series_num */ void series_start(int seed)

{

series_num = seed;

>

Вызов функции series_start () инициализирует генератор чисел. После этого следующий элемент ряда порождается новым вызовом функции seriesO.

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