programowanieProgramista C

Jak działają statyczne zmienne lokalne w funkcjach w języku C? Jaka jest ich różnica w porównaniu do zwykłych zmiennych lokalnych? Podaj przykłady zastosowania i potencjalnych błędów.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Statyczna zmienna lokalna jest definiowana za pomocą słowa kluczowego static wewnątrz funkcji. W przeciwieństwie do zwykłych zmiennych lokalnych, zachowuje swoją wartość między wywołaniami funkcji i jest inicjowana tylko raz. Taka zmienna istnieje przez całe życie programu, ale jest widoczna tylko w swojej funkcji.

Zwykła zmienna lokalna:

void func() { int count = 0; // każda inicjalizacja na nowo count++; printf("%d\n", count); }

Za każdym razem na wyjściu — 1.

Statyczna zmienna lokalna:

void func() { static int count = 0; // inicjalizowana tylko raz count++; printf("%d\n", count); }

Przy kolejnych wywołaniach otrzymamy wyniki: 1, 2, 3, ...

Zastosowanie: wygodne do zliczania liczby wywołań funkcji, buforowania prostych wartości.

Pytanie podchwytliwe

"Czy statyczna zmienna lokalna zostanie zniszczona po wyjściu z funkcji i co się stanie z jej wartością przy kolejnym wywołaniu funkcji?"

Często odpowiadają, że jest niszczona, ale to nieprawda.

Prawidłowa odpowiedź: Statyczna zmienna lokalna istnieje przez całe życie programu. Zachowuje swoją wartość między wywołaniami funkcji i jest inicjowana tylko raz (przy pierwszym wejściu do funkcji lub przed main).

Przykłady rzeczywistych błędów z powodu braku znajomości niuansów tematu


Historia 1

W projekcie mierzyliśmy czasy wejścia do modułu poprzez funkcję, która miała zliczać każde wejście. Pomyliśmy int counter = 0; z static int counter = 0; — funkcja zawsze zwracała 1, statystyka okazała się bezużyteczna.


Historia 2

W jednym serwisie, który nie był bezpieczny wielowątkowo, użyto statycznej zmiennej w funkcji, która była wywoływana z różnych wątków. Doprowadziło to do warunków wyścigu i przypadkowych, błędnych wyników. Nie uwzględniono, że współdzielona pamięć nie była chroniona.


Historia 3

Przechowywaliśmy wskaźnik do dynamicznie przydzielonej pamięci w zmiennej statycznej w celu buforowania. Przy ponownym wywołaniu funkcji nie zwolniono starej pamięci: wystąpił wyciek pamięci przy każdym wywołaniu.