Открыть сервис

Статическая переменная

Статическая переменная — это переменная, которая создаётся один раз при первом обращении к ней и сохраняет своё значение на протяжении всего времени выполнения программы (или времени жизни модуля/класса), в отличие от локальных переменных, которые создаются и уничтожаются при каждом входе и выходе из блока кода. Статические переменные относятся к классу переменных с расширенным временем жизни и, в зависимости от контекста объявления, могут иметь различную область видимости.

Общая характеристика

Основное свойство статической переменной — её постоянство в памяти. Память под неё выделяется один раз, инициализация происходит однократно (обычно при первом вызове функции или при загрузке модуля), а значение сохраняется между вызовами функций или между созданиями объектов класса. Это отличает её от автоматических (локальных) переменных, которые размещаются в стеке и существуют только во время выполнения своего блока.

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

История

Понятие статической переменной восходит к ранним языкам программирования, в частности к языку ALGOL 60, где впервые была введена концепция «собственных» (own) переменных. В языке C, разработанном в начале 1970-х годов, ключевое слово static получило два основных значения: для переменных внутри функций оно означало сохранение значения между вызовами, а для глобальных переменных и функций — ограничение области видимости текущим файлом компиляции. В языке C++ статические переменные были расширены на члены классов, что позволило создавать переменные, общие для всех экземпляров класса. В более поздних языках, таких как Java и C#, статические поля и методы стали неотъемлемой частью объектно-ориентированной парадигмы.

Виды статических переменных

Статические переменные внутри функций

В языках C, C++, а также в некоторых других (например, в PHP), статическая переменная, объявленная внутри функции, инициализируется один раз при первом вызове функции и сохраняет своё значение между последующими вызовами. Область видимости такой переменной ограничена телом функции, но время жизни — вся программа.

Пример на C: ``c void counter() { static int count = 0; // инициализируется один раз count++; printf("%d\n", count); } ` При каждом вызове counter() значение count` будет увеличиваться на 1, начиная с 1.

Статические глобальные переменные и функции

В языках C и C++ ключевое слово static, применённое к глобальной переменной или функции (вне какого-либо блока), изменяет их связывание (linkage) с внешнего на внутреннее. Это означает, что переменная или функция становится видимой только в пределах того файла (единицы трансляции), в котором она объявлена. Это позволяет скрывать детали реализации от других модулей программы.

Статические члены классов

В объектно-ориентированных языках (C++, Java, C#, PHP, Swift и др.) статические поля и методы принадлежат не конкретному экземпляру класса, а самому классу. Существует только одна копия статического поля для всех объектов класса, и она доступна без создания экземпляра.

Пример на Java: ``java public class MyClass { static int instanceCount = 0; // статическое поле public MyClass() { instanceCount++; } public static int getInstanceCount() { return instanceCount; } } ``

Статические переменные в модулях и пакетах

В некоторых языках (например, в Python, где нет ключевого слова static в классическом смысле) аналогом статических переменных могут служить атрибуты функций или атрибуты модулей. В Python переменная, объявленная вне функций на уровне модуля, является глобальной для этого модуля, а атрибуты функции (например, func.counter = 0) ведут себя как статические переменные внутри функции.

Инициализация

Статические переменные инициализируются только один раз. В языках C и C++ статические переменные могут быть инициализированы константными выражениями на этапе компиляции. Если явная инициализация не указана, они обнуляются (для числовых типов — 0, для указателей — NULL). В C++ статические локальные переменные инициализируются при первом проходе выполнения через их объявление, и эта инициализация потокобезопасна (начиная с C++11). В Java и C# статические поля инициализируются при загрузке класса, до создания первого экземпляра или обращения к статическому члену.

Область видимости и время жизни

Применение

Статические переменные находят широкое применение в различных областях программирования:

  1. Счётчики и накопители: подсчёт количества вызовов функции, числа созданных экземпляров класса, времени работы.
  2. Кэширование и мемоизация: хранение результатов дорогостоящих вычислений для повторного использования.
  3. Реализация синглтонов (одиночек): статическая переменная, хранящая единственный экземпляр класса.
  4. Управление состоянием: хранение конфигурационных параметров, флагов, глобальных настроек в рамках модуля.
  5. Реализация пулов ресурсов: статические коллекции для повторного использования объектов (например, пулы соединений с базой данных).
  6. Служебные функции: статические методы-утилиты, не требующие создания объекта (например, Math.sqrt() в Java).

Критика и ограничения

Использование статических переменных может приводить к ряду проблем:

Примеры в различных языках программирования

ЯзыкСинтаксисПримечание
Cstatic int x = 0; внутри функции или на уровне файлаВнутри функции — сохраняет значение, на уровне файла — ограничивает видимость
C++static int x; внутри функции, класса или на уровне файлаАналогично C, плюс статические члены класса
Javastatic int x; внутри классаПринадлежит классу, а не экземпляру
C#static int x; внутри классаАналогично Java
PHPstatic $x = 0; внутри функции или классаВнутри функции — сохраняет значение, в классе — принадлежит классу
Pythonfunc.counter = 0 или class MyClass: x = 0Атрибуты функции или класса ведут себя как статические
JavaScript (ES6)static x = 0; внутри классаСтатическое поле класса
Swiftstatic var x = 0 внутри типаСтатическое свойство типа

Источники

  1. Керниган Б. У., Ритчи Д. М. — «Язык программирования C». 2-е издание.
  2. Страуструп Б. — «Язык программирования C++. Специальное издание».
  3. Гослинг Дж., Джой Б., Стил Г., Брача Г. — «Язык программирования Java».
  4. Рихтер Дж. — «CLR via C#». 4-е издание.
  5. Эккель Б. — «Философия Java». 4-е издание.
  6. Спецификация языка Python (Python Language Reference) — раздел «Naming and binding».
  7. ISO/IEC 9899:2018 — «Programming languages — C».
  8. ISO/IEC 14882:2020 — «Programming languages — C++».

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →