Выбрать главу

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

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

Рассмотрим пример использования static-переменной. Она служит для хранения текущего среднего значения от чисел, вводимых пользователем.

/* Вычисляем текущее среднее значение от чисел, вводимых пользователем.

*/

#include <iostream>

using namespace std;

int r_avg(int i);

int main()

{

 int num;

 do {

  cout << "Введите числа (-1 означает выход): ";

   cin >> num;

  if(num != -1)

   cout << "Текущее среднее равно: " << r_avg(num);

  cout << '\n';

 }while(num > -1);

 return 0;

}

// Вычисляем текущее среднее.

int r_avg(int i)

{

 static int sum=0, count=0;

 sum = sum + i;

 count++;

 return sum / count;

}

Здесь обе локальные переменные sum и count объявлены статическими и инициализированы значением 0. Помните, что для статических переменных инициализация выполняется только один раз (при первом выполнении функции), а не при каждом входе в функцию. В этой программе функция r_avg() используется для вычисления текущего среднего значения от чисел, вводимых пользователем. Поскольку обе переменные sum и count являются статическими, они поддерживают свои значения между вызовами функции r_avg(), что позволяет нам получить правильный результат вычислений. Чтобы убедиться в необходимости модификатора static, попробуйте удалить его из программы. После этого программа не будет работать корректно, поскольку промежуточная сумма будет теряться при каждом выходе из функции r_avg().

Глобальные static-переменные

Глобальная static-переменная известна только для файла, в котором она объявлена.

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

Рассмотрим пример, который представляет собой переработанную версию программы (из предыдущего раздела), вычисляющей текущее среднее значение. Эта версия состоит из двух файлов и использует глобальные static-переменные для хранения значений промежуточной суммы и счетчика вводимых чисел.

//---------------------Первый файл---------------------

#include <iostream>

using namespace std;

int r_avg(int i);

void reset();

int main()

{

 int num;

 do {

  cout <<"Введите числа (-1 для выхода, -2 для сброса): ";

   cin >> num;

  if(num==-2) {

   reset();

   continue;

  }

  if(num != -1)

   cout << "Среднее значение равно: " << r_avg(num);

  cout << '\n';

 }while(num != -1);