[ Pobierz całość w formacie PDF ]

przykład pętla:
$ awk 'BEGIN { for (x = 0; x
...
0.85
0.9
0.95
wcale nie wyświetli w ostatnim przebiegu wartości 1, bo wielokrotne dodawanie
nieprecyzyjnie reprezentowanej wartości 0,05 daje ostatecznie wartość x nieznacznie
większą od 1 (a warunek wykonania pętli dopuszcza najwyżej równość x z 1).
Programiści języka C powinni zapamiętać, że w awk nie ma operatora przecinka, więc w wy-
rażeniach pętli for nie wolno stosować list wyrażeń.
Druga postać pętli for służy do iteracyjnego przeglądania elementów tablic asocjacyjnych
o nieznanej z góry liczbie elementów albo takich, których sekwencji indeksowania nie da się
wyrazić szeregiem całkowitych wartości liczbowych. Elementy tablicy do przetwarzania w ko-
lejnych iteracjach są wybierane w bliżej nieokreślonej kolejności, więc poniższy kod:
for (name in telephone)
print name "\t" telephone[name]
raczej nie spowoduje wypisania elementów tablicy telephone w jakiejkolwiek oczekiwanej
kolejności. Problem ten można rozwiązać metodami prezentowanymi w punkcie 9.7.7. Tablice
 wielowymiarowe , indeksowane wieloma indeksami, można uprzednio przetworzyć funkcją
split(), opisywaną w punkcie 9.9.6.
Do przerywania pętli służy (tak, jak w języku programowania powłoki) instrukcja break:
for (name in telephone)
if (telephone[name] == "123-0123")
break
print "Numer telefonu" name "to 123-0123"
W awk brakuje jednak znanej z powłoki możliwości jednorazowego przerywania dowolnej
liczby zagnieżdżonych pętli instrukcją break n.
Instrukcja continue pozwala wymusić (również podobnie, jak w powłoce) przeskok na ko-
niec ciała pętli i przejście do następnej iteracji. Język awk nie obsługuje przy tym wersji wie-
lopoziomowej tego polecenia, znanej z powłoki continue n. Ilustrację działania instrukcji
continue w awk stanowi listing 9.1; ów implementuje siłową metodę (przez sprawdzanie ko-
lejnych podzielników) sprawdzania, czy dana liczba jest liczbą pierwszą (dla przypomnienia,
liczba pierwsza to każda całkowita liczba pierwsza, która dzieli się bez reszty tylko przez 1
i przez samą siebie). Pogram wypisuje też wytypowany dla liczby podział na czynniki pierwsze.
Listing 9.1. Czynniki pierwsze liczb całkowitych
# Wyznacza czynniki pierwsze liczb całkowitych podawanych na wejście
# (po jednej w wierszu)
#
# Stosowanie:
# awk -f factorize.awk
{
n = int($1)
m = n = (n >= 2) ? n : 2
266 | Rozdział 9. Nieuzbrojony a niebezpieczny  awk
factors = ""
for (k = 2; (m > 1) && (k^2
{
if (int(m % k) != 0)
{
k++
continue
}
m /= k
factors = (factors == "") ? ("" k) : (factors " * " k)
}
if ((1
factors = factors " * " m
print n, (factors == "") ? " to liczba pierwsza" : ("= " factors)
}
Zauważmy, że po zwiększeniu licznika pętli k następuje przejście do następnej iteracji (in-
strukcja continue), ale całość odbywa się tylko wtedy, kiedy k nie jest całkowitym podzielni-
kiem m, stąd puste wyrażenie w miejsce trzeciego wyrażenia pętli for.
Gdyby uruchomić program dla próbki danych testowych, otrzymalibyśmy następujące wyniki:
$ awk -f factorize.awk test.dat
2147483540 = 2 * 2 * 5 * 107374177
2147483541 = 3 * 7 * 102261121
2147483542 = 2 * 3137 * 342283
2147483543 to liczba pierwsza
2147483544 = 2 * 2 * 2 * 3 * 79 * 1132639
2147483545 = 5 * 429496709
2147483546 = 2 * 13 * 8969 * 9209
2147483547 = 3 * 3 * 11 * 21691753
2147483548 = 2 * 2 * 7 * 76695841
2147483549 to liczba pierwsza
2147483550 = 2 * 3 * 5 * 5 * 19 * 23 * 181 * 181
9.7.4. Sprawdzanie przynależności do tablicy
Test przynależności klucza do tablicy  w postaci klucz in tablica  to wyrażenie
przyjmujące wartość 1 ( prawda ), jeśli klucz jest indeksem istniejącego elementu tablicy.
Wynik testu można odwrócić operatorem negacji: !(klucz in tablica) zwraca 1 ( prawda ),
kiedy klucz nie jest poprawnym indeksem tablicy. Ujęcie negowanego testu w nawiasy jest
konieczne.
W przypadku tablic o wielokrotnych indeksach można w miejsce klucza zastosować ujętą
w nawiasy listę indeksów: (i, j, ..., n) in tablica.
Test przynależności w żadnym razie nie prowokuje wstawienia elementu do tablicy; to ważne,
bo każde zwykłe odwołanie do nieistniejącego elementu tablicy tworzy taki element. Stąd,
zamiast:
if (telephone["dorotka"] != "")
print "Mamy telefon Dorotki w katalogu"
należałoby raczej pisać:
if ("dorotka" in telephone)
print "Mamy telefon Dorotki w katalogu"
Pierwsza z tych wersji spowoduje wszak wstawienie do tablicy elementu z pustym numerem
telefonu.
9.7. Instrukcje awk | 267
Trzeba też rozróżniać wyszukiwanie indeksu od wyszukiwania konkretnej wartości elementu.
Otóż test przynależności indeksu elementu jest realizowany w stałym, niezależnym od ilości
elementów tablicy, czasie. Tymczasem wyszukiwanie wartości odbywa się w czasie propor-
cjonalnym do liczby elementów, co ilustruje przykład demonstrujący stosowanie instrukcji
break w pętli for. Jeśli w programie przewiduje się częste wyszukiwanie kluczy i wartości,
warto rozważyć utworzenie drugiej tablicy  odwracającej skojarzenie indeks-wartość:
for (name in telephone)
name_by_telephone[telephone[name]] = name [ Pobierz całość w formacie PDF ]