Читать «Полный справочник по С++» онлайн - страница 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 позволяет создавать переменные, видимые лишь в пределах функций, не порождая побочных эффектов.