ПрограммированиеC разработчик

Как работают статические локальные переменные в функциях на языке C? В чем их отличие от обычных локальных переменных? Приведите примеры применения и потенциальных ошибок.

Проходите собеседования с ИИ помощником Hintsage

Ответ

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

Обычная локальная переменная:

void func() { int count = 0; // каждый раз инициализируется count++; printf("%d ", count); }

Каждый раз на выходе — 1.

Статическая локальная переменная:

void func() { static int count = 0; // инициализируется только один раз count++; printf("%d ", count); }

При последовательных вызовах получим вывод: 1, 2, 3, ...

Использование: удобно для подсчёта количества вызовов функции, кэширования простых значений.

Вопрос с подвохом

"Будет ли статическая локальная переменная уничтожена после выхода из функции и что произойдет с её значением при следующем вызове функции?"

Часто отвечают, что уничтожается, но это не так.

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

Примеры реальных ошибок из-за незнания тонкостей темы


История 1

В проекте измерялись показатели времени входа в модуль через функцию, которая должна была считать каждый вход. Перепутали int counter = 0; с static int counter = 0; — функция всегда возвращала 1, статистика оказалась бесполезной.


История 2

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


История 3

Хранили указатель на динамически выделенную память в статической переменной для кэширования. При перезапуске функции не освобождали старую память: возникла утечка памяти при каждом вызове.