4 FUNKCJE I STRUKTURA PROGRAMU
gdyż słowo register w deklaracjach nadliczbowych czy też niepoprawnych jest ignorowane. Nie ma także możliwości uzyskania adresu zmiennej rejestrowej (zagadnienie omawiane w rozdz. 5) niezależnie od tego, czy zmienną rzeczywiście umieszczono w rejestrze, czy nie. Szczegółowe ograniczenia dotyczące liczby i typów zmiennych rejestrowych zależą od maszyny.
Język C nie ma struktury blokowej w sensie Pascala czy jemu podobnych języków, gdyż nie można definiować funkcji wewnątrz innych funkcji. Z drugiej strony, zmienne mogą być definiowane według zasad struktury blokowej wewnątrz funkcji. Deklaracje zmiennych (łącznie z ich inicjowaniem) można umieścić po otwierającym nawiasie klamrowym dowolnej instrukcji złożonej, a nie tylko po tym, który rozpoczyna funkcję. Tak zadeklarowane zmienne zasłaniają identycznie nazwane zmienne z bloków zewnętrznych i istnieją do napotkania odpowiedniego zamykającego nawiasu klamrowego. W przykładzie
if (n > 0) {
int i; /* definicja nowego i */
for (i = 0; i < n; i++)
• • ■
zasięgiem zmiennej i jest gałąź „prawdy” instrukcji if; ta zmienna i nie jest związana z żadną inną zmienną i występującą poza tym blokiem. Zmienna automatyczna deklarowana i inicjowana wewnątrz bloku otrzymuje swoją wartość początkową za każdym razem od nowa, przy każdym wejściu do bloku. Zmienna static jest inicjowana tylko raz, przy pierwszym wejściu do bloku, w którym ją zadeklarowano.
Zmienne automatyczne, łącznie z parametrami funkcji, zasłaniają także zmienne zewnętrzne i funkcje o tych samych nazwach, np. po deklaracjach
int x;
int y;
f(double x)
double y;
• • •
>
4.9 INICJOWANIE
pojawienie się X wewnątrz funkcji f jest odwołaniem do parametru funl typu double; poza funkcją f takie odwołania dotyczą zmiennej zewnętrznej x o typie int. Ta sama zasada obowiązuje dla zmiennej y.
Jest to kwestia stylu, ale lepiej unikać nazw zmiennych zasłaniających nazwy występujące w otoczeniu; niebezpieczeństwo wprowadzenia bałaganu i wystąpienia błędu jest zbyt duże.
Dotychczas temat nadawania wartości początkowych był poruszany wielokrotnie, zawsze jednak jako drugorzędny w stosunku do innych zagadnień. Po omówieniu różnych klas pamięci możemy wreszcie sformułować kilka zasad inicjowania zmiennych.
Jeśli nie podano jawnie wartości początkowych, to zmienne zewnętrzne i statyczne zawsze będą inicjowane zerami, natomiast wartości początkowe zmiennych automatycznych i rejestrowych będą nieokreślone (tj. przypadkowe).
Zmienne jednowymiarowe można inicjować przy ich definicji, umieszczając po nazwie zmiennej znak równości i pewne wyrażenie:
Wartością początkową zmiennych zewnętrznych i statycznych musi być wyrażenie stałe; inicjowanie odbywa się tylko raz, ogólnie mówiąc - zanim pogram rozpocznie działanie. Zmienne automatyczne i rejestrowe są inicjowane przy każdym wejściu do funkcji lub bloku.
Wartością początkową zmiennej automatycznej i rejestrowej nie musi być stała: może nią być dowolne wyrażenie zawierające uprzednio zdefiniowane wartości a nawet wywołania funkcji. Na przykład, w programie wyszukiwania metodą bisekcji z p. 3.3 inicjowanie zmiennych można zapisać tak:
121