1 ELEMENTARZ
dopiero w chwili wywołania funkcji i znika po zakończeniu jej działania. Z tego powodu zmienne takie są zwykle znane jako automatyczne (stosując terminologię innych języków programowania). Odtąd będziemy używać określenia automatyczna w odniesieniu do tych zmiennych lokalnych. (W rozdziale 4 omówimy klasę pamięci static, dzięki której zmienne lokalne funkcji zachowują swoje wartości między jej wywołaniami.)
Zmienne automatyczne pojawiają się i znikają razem z wywołaniem funkcji, nie zachowują więc swoich wartości z jednego wykonania do następnego i muszą być jawnie określane od nowa przy każdym wejściu do funkcji. Jeśli ich wartości początkowe nie zostaną określone, to zmienne będą zawierać śmiecie.
Przeciwieństwem zmiennych automatycznych są zmienne zewnętrzne w stosunku do wszystkich funkcji. Są to zmienne globalne, dostępne przez nazwę w dowolnej funkcji programu. (Ten mechanizm jest podobny do COMMON w Fortranie lub do deklarowania zmiennych w najbardziej zewnętrznym bloku w Pascalu.) Ze względu na to, że zmienne zewnętrzne są ogólnie dostępne, mogą być stosowane zamiast list argumentów przy przekazywaniu danych między funkcjami. Co więcej, ponieważ zmienne zewnętrzne istnieją stale, a nie pojawiają się i znikają razem z wywołaniem i zakończeniem funkcji, zachowują więc swoje wartości nawet po zakończeniu działania tych funkcji, które nadały im wartości.
Zmienna zewnętrzna musi być zdefiniowana - dokładnie jeden raz - na zewnątrz wszystkich funkcji; definicja przydziela jej rzeczywistą pamięć. Taka zmienna musi być także zadeklarowana w każdej funkcji, która chce mieć do niej dostęp; deklaracja ustala typ zmiennej. Można to zrobić albo przez jawną deklarację extern, albo niejawnie przez kontekst. Aby dyskusja stała się rzeczowa, napiszmy od nowa program wypisujący najdłuższy wiersz ze zmiennymi linę, longest i max jako zmiennymi zewnętrznymi. Wymaga to zmiany wywołań, deklaracji i treści wszystkich trzech funkcji. ;
#define MAXLINE 1000 /* maksymalny rozmiar wiersza */ i
int max; /* poprzednia maks. długość */ j
char line[MAXLINE]; /* bieżący wiersz z wejścia */ *
char longest[MAXLINE]; /* przechowywany maks. wiersz */ f
int getline(void);
.10 ZMIENNE ZEWNĘTRZNE I ZASIĘG ZMIENNYCH
1
/* wypisz najdłuższy wiersz; wersja specjalna */ main()
int len; /* długość bieżącego wiersza */
extern int max; extern char longestfj;
max = 0;
while ((len = getline()) > 0) if (len > max) { max = len; copy();
if (max > 0) /* znaleziono wiersz */ printf(”%s”, longest); return 0;
/* getline: wersja specjalna */ int getline(void)
int c, i;
extern char line[ ];
for (i = 0; i < MAXLINE-1
&& (c=getchar()) != EOF && c l= ’\n’; ++i) linefij = c; if (c == ’\n’) { line[i] - c;
-Hf;
iine[i] = '\0’; return i;
I* copy: wersja specjalna */ v°id copy(void)
int i;
extern char line[J, longest[ ];
i = 0;
while ((longest[ij = linefij) != ’\0’) ++i;