3 STEROWANIE
instrukcją break dla uniknięcia takiego przejścia. Słabą stroną przechodzenia z jednego przypadku do następnego jest podatność na rozsypanie się całej konstrukcji switch podczas modyfikacji programu. Z wyjątkiem wielu etykiet dla jednej akcj przechodzenie przez przypadki powinno być stosowane oszczędnie i zawsze opatrzc ne komentarzem.
Do dobrego stylu programowania należy wstawianie break po ostatniej instrukcji ostatniego przypadku (jak po default w naszym przykładzie), mimo że nie jest to k< nieczne. Pewnego dnia, gdy dopiszesz na końcu jakiś inny przypadek, ta odrobina zapobiegliwości może Cię uratować.
Ćwiczenie 3.2. Napisz funkcję escape(s,t), która przepisując tekst z argumentu t do s, zamienia takie znaki, jak znak nowego wiersza czy tabulacji, na czytelne sekwencje specjalne, np. \n i \t. Zastosuj instrukcję switch. Napisz także funkcję działającą w odwrotnym kierunku, tzn. przy kopiowaniu zamieniającą sekwencje specjalne na rzeczywiste znaki.
Z pętlami while i for już się spotkaliśmy. W pętli
while (wyrażenie) instrukcja
najpierw oblicza się wyrażenie. Jeśli jego wartość jest różna od zera, to wykonuje sic instrukcję, a następnie ponownie oblicza wyrażenie. Ten cykl powtarza się do chwili, w której wartość wyrażenia stanie się zerem. Wówczas sterowanie przechodzi do instrukcji następującej po pętli.
Pętla
tor(wyrł; wyr2\ wyr3)
instrukcja 1
jest równoważna rozwinięciu «
wyrl;
while (wyr2) { instrukcja wyr3\
}
jeśli nie uwzględniać skutku instrukcji continue, którą opiszemy w p. 3.7.
3-5 PĘTLE WHILE I FOR
Gramatycznie wszystkie trzy składniki instrukcji for są wyrażenia!_
wyr1 i wyr3 są przypisaniami lub wywołaniami funkcji, a wyr2 jest wyrażeniem wa-runkowym. Dowolną z tych części można pominąć, wówczas jednak musi pozostać jej średnik. Pominięcie wyr] lub wyri powoduje usunięcie tej części z rozwinięcia. Jeśli brak warunku wyr2, to przyjmuje się, że jest on zawsze prawdziwy, a więc
for (;;) { }
jest pętlą nieskończoną, która prawdopodobnie zostanie przerwana w inny sposób, choćby przez instrukcję break czy return.
Stosowanie pętli while bądź for w dużym stopniu zależy od osobistych upodobań. Na przykład w instrukcji
while ((c = getchar()) == ” || c == ’\n’ || c == ’\f)
; l* przeskocz białe znaki */
nie występuje ani część inicjująca, ani część modyfikująca, toteż użycie pętli while jest bardziej naturalne.
Tam, gdzie występują proste części inicjująca i przyrostu, lepiej jest korzystać z pętli for, ponieważ skupia ona instrukcje sterujące w widocznym miejscu na szczycie pętli. Najlepiej to widać w instrukcji
for (i = 0; i < n; i++)
• • •
która jest charakterystycznym zwrotem języka C używanym przy przetwarzaniu początkowych n elementów pewnej tablicy, podobnym do pętli DO w Fortranie lub do pętli for w Pascalu. Podobieństwo nie jest jednak doskonałe, gdyż w języku C wartość zmiennej sterującej oraz granicę pętli for można zmieniać wewnątrz pętli, a zmienna sterująca i zachowuje swoją wartość po zakończeniu pętli niezależnie od przyczyny zakończenia. Ponieważ częściami for są dowolne wyrażenia, stosowanie tej pętli nie ogranicza się do postępów arytmetycznych. Mimo to w złym stylu jest „wpychanie” do instrukcji for obliczeń, które jako inicjowanie i przyrost nie mają ze sobą nic wspólnego; lepiej te części zarezerwować dla operacji sterujących wykonaniem pętli.
Większym przykładem będzie inna wersja funkcji atoi przekształcającej ciąg cyfr dziesiętnych na jego numeryczny odpowiednik. Wersja ta jest troszeczkę ogólniejsza od napisanej w rozdz. 2 - pomija początkowe białe znaki oraz uwzględnia znak liczby
91