Zmienna (informatyka)

Zmienna – konstrukcja programistyczna posiadająca trzy podstawowe atrybuty: symboliczną nazwę, miejsce przechowywania i wartość. W kodzie źródłowym za pomocą nazwy zmiennej można się odwoływać do jej wartości lub miejsca przechowywania. Nazwa służy do identyfikowania zmiennej, w związku z tym często nazywana jest identyfikatorem. Miejsce przechowywania przeważnie znajduje się w pamięci komputera i określane jest przez adres i długość danych. Wartość to zawartość miejsca przechowywania. Zmienna zazwyczaj posiada również czwarty atrybut: typ, określający rodzaj danych przechowywanych w zmiennej i co za tym idzie sposób reprezentacji wartości w miejscu przechowywania. W programie wartość zmiennej może być odczytywana lub zastępowana nową wartością. Zatem wartość zmiennej może zmieniać się w trakcie wykonywania programu, natomiast dwa pierwsze atrybuty (nazwa i miejsce przechowywania) nie zmieniają się w trakcie istnienia zmiennej[1]. W zależności od rodzaju języka programowania typ może być stały lub zmienny. Konstrukcją podobną lecz nie pozwalającą na modyfikowanie wartości jest stała.

Inaczej traktuje się zmienną w programowaniu funkcyjnym (gdzie idea zmiennej jest zbliżona do zmiennej matematycznej). Podczas wchodzenia obliczeń do kontekstu z którym zmienna jest związana, nadawana jest jej wartość, która nie zmienia się aż do opuszczenia kontekstu. Jednak przy ponownym wejściu w ten kontekst, zmiennej może być przypisana inna wartość niż poprzednio.

Programowanie imperatywne polega w dużej mierze na modyfikowaniu wartości zmiennych (także na podstawie ich wcześniejszych wartości, chociaż nie musi to być regułą).

Typ zmiennej

W językach ze statycznym typowaniem zmienna ma określony typ danych, jakie może przechowywać. Jest on wykorzystywany do określenia reprezentacji wartości w pamięci, kontrolowania poprawności operacji wykonywanych na zmiennej (kontrola typów) oraz konwersji danych jednego typu na inny.

W językach z typowaniem dynamicznym typ nie jest atrybutem zmiennej lecz wartości w niej przechowywanej. Zmienna może wtedy w różnych momentach pracy programu przechowywać dane innego typu.

Deklaracja i definicja

Deklaracja zmiennej to stwierdzenie, że dany identyfikator jest zmienną i przeważnie też określa typ zmiennej. W zależności od języka programowania deklaracja może być obligatoryjna, opcjonalna lub nie występować wcale. Definicja oprócz tego, że deklaruje zmienną to przydziela jej także pamięć do jej przechowywania. Podczas definiowania lub deklarowania zmiennej można określić jej dodatkowe atrybuty wpływające na sposób i miejsce alokacji, czas życia, zasięg i inne.

Zasięg, czas życia, widoczność

Zasięg zmiennej określa, gdzie w treści programu zmienna może być wykorzystana, natomiast czas życia zmiennej to okresy w trakcie wykonywania programu, gdy zmienna ma przydzieloną pamięć i posiada (niekoniecznie określoną) wartość. Precyzyjnie zasięg odnosi się do nazwy zmiennej i przeważnie jest aspektem leksykalnym, natomiast czas życia odnosi się do zmiennej samej w sobie i związany jest z wykonywaniem programu.

Ze względu na zasięg można wyróżnić podstawowe kategorie zmiennych:

  • globalne – obejmujące zasięgiem cały program,
  • lokalne – o zasięgu obejmującym pewien blok, podprogram. W językach obsługujących rekurencję zazwyczaj są to zmienne automatyczne, natomiast w językach bez rekurencji mogą być statyczne.

Zmienne zadeklarowane w module mogą być zmiennymi prywatnymi modułu – dostępnymi wyłącznie z jego wnętrza – lub zmiennymi publicznymi (eksportowanymi) – dostępnymi tam, gdzie moduł jest wykorzystywany. Podobnie jest ze zmiennymi w klasie – mogą być dostępne:

  • tylko dla danej klasy (zmienna prywatna),
  • dla danej klasy i jej potomków (zmienna chroniona),
  • w całym programie (zmienna publiczna),
  • inne ograniczenia w zależności od języka (np. friend czy internal w .NET).

Zmienne mogą zmieniać swój pierwotny zasięg np. poprzez importowanie/włączanie do zasięgu globalnego modułów, pakietów czy przestrzeni nazw.

Ze względu na czas życia i sposób alokacji zmienna może być:

  • statyczna – gdy pamięć dla niej rezerwowana jest w momencie ładowania programu. Takimi zmiennymi są zmienne globalne, zmienne statyczne w klasie (współdzielone przez wszystkie obiekty klasy, a nawet dostępne spoza klasy), statyczne zmienne lokalne funkcji (współdzielone pomiędzy poszczególnymi wywołaniami funkcji i zachowujące wartość po zakończeniu).
  • automatyczna – gdy pamięć przydzielana jest w trakcie działania programu ale automatycznie. Są to przeważnie zmienne lokalne podprogramów i ich parametry formalne. Są one alokowane przeważnie na stosie w rekordzie aktywacji i znikają po zakończeniu podprogramu.
  • dynamiczna – alokowanie ręcznie w trakcie wykonywania programu przy pomocy specjalnych konstrukcji lub funkcji (malloc, new). W zależności od języka programowania zwalnianie pamięci może być ręczne lub automatyczne. Zazwyczaj nie posiada własnej nazwy, lecz trzeba się do niej odwoływać przy pomocy wskaźnika, referencji lub zmiennej o semantyce referencyjnej.

W większości współczesnych języków programowania zasięg zmiennych jest statyczny (leksykalny). Oznacza to, że podprogram ma dostęp do zmiennych lokalnych bloków w których jest zdeklarowany. Przykładowo:

int f() {
    int a;
    int g() {
        print(a);
    }
    ...
}

Funkcja g jest zadeklarowana wewnątrz funkcji f, w związku z tym ma dostęp do zmiennej lokalnej zadeklarowanej w funkcji f, czyli: a.

W niektórych językach (np. pierwsze implementacje LISP'u) zasięg był dynamiczny, czyli nie było ważne gdzie funkcja jest zadeklarowana, tylko jaka funkcja ją wywołała. W poniższym przykładzie funkcja g wydrukuje zawartość zmiennej a z funkcji f.

int g() {
    print(a);
}

int f() {
    int a;
    g();
}

Inne rodzaje zmiennych

Zobacz też

Przypisy

Bibliografia

  • Mordechai Ben-Ari: Understanding Programming Languages. Chichester: John Wiley & Sons, 1996.
  • Tomasz Wierzbicki: Języki programowania. 2001.