Zmienne globalne pojawiły się w języku C od samego początku jako środek do przechowywania danych dostępnych w każdej funkcji programu. Umożliwiają one organizowanie wymiany informacji między różnymi częściami kodu bez jawnego przekazywania wartości przez parametry funkcji. Takie zmienne są przechowywane w oddzielnym obszarze pamięci i istnieją przez całe życie programu.
Nadmierne i niekontrolowane używanie zmiennych globalnych prowadzi do problemów z utrzymaniem kodu, utrudnia znalezienie błędów oraz zwiększa ryzyko konfliktów nazw. W dużych projektach trudno zrozumieć, gdzie zachodzi zmiana danych dostępnych globalnie, co komplikuje debugowanie. Poza tym, niepoprawna deklaracja zmiennych globalnych w różnych plikach (modułach) może prowadzić do błędów linkera (linker errors) i duplikacji danych.
Optymalną praktyką jest jawna deklaracja zmiennych globalnych w jednym pliku .c oraz wydanie ich prototypów z kluczowym słowem extern w nagłówkowych plikach .h. W ten sposób powstaje jedno miejsce przechowywania, a kompilator zapobiega duplikacji. Aby zminimalizować zmienne globalne, stosuje się zmienne statyczne z zakresem widoczności w obrębie pliku. Nadmiarowe użycie globalnego stanu zastępuje się strukturami danych, które są przekazywane między funkcjami.
Przykład kodu:
// file.h #ifndef FILE_H #define FILE_H extern int global_counter; #endif // file.c #include "file.h" int global_counter = 0; // main.c #include "file.h" #include <stdio.h> int main() { global_counter++; printf("%d\n", global_counter); return 0; }
Kluczowe cechy:
Czy można zadeklarować zmienną globalną jako statyczną? Czym wtedy będzie się różnić od zwykłej zmiennej globalnej?
Tak, zmienna globalna zadeklarowana z kluczowym słowem static będzie widoczna tylko wewnątrz tego pliku, w którym została zadeklarowana. Nadal żyje przez cały czas pracy programu, ale inne kompilacje (inny plik .c) nie będą mogły się do niej odwołać. Jest to stosowane do enkapsulacji danych na poziomie pliku.
Czy koniecznie trzeba używać extern, aby uzyskać dostęp do zmiennej globalnej z innego pliku?
Tak, jeśli chcesz odwołać się do zmiennej globalnej zdefiniowanej w innym module, musisz zadeklarować ją z kluczowym słowem extern (zwykle w pliku nagłówkowym). W przeciwnym razie kompilator uzna, że ponownie definiujesz zmienną.
// a.c int global_var = 1; // b.c extern int global_var;
Czy poniższy kod będzie działał?
// a.c int var; // b.c int var;
Nie, taki kod spowoduje błąd kompilacji, ponieważ zmienna jest zdefiniowana dwukrotnie. Definicja zmiennej globalnej musi być unikalna, aby uzyskać dostęp, należy użyć extern.
Programista umieszcza parametry konfiguracyjne w zmiennych globalnych bez ograniczeń dostępu:
Plusy:
Minusy:
Zmienna globalna jest definiowana tylko w jednym pliku, dostępna przez extern, ściśle dokumentowana. W innych przypadkach stosuje się statyczny zakres pliku lub strukturyzację parametrów:
Plusy:
Minusy: