ebook, ebooki chomikuj

 

[ Pobierz całość w formacie PDF ]
I. Programowanie niestrukturalne
1
Wgłąb języka C
>>>Spis treści<<<
Wydawnictwo Helion
2
Wgłąb języka C
PRZEDMOWA
Niniejsza książka jest pomyślana jako książka dla programistów. Nie stanowi
ona całościowego, systematycznego opisu języka C i nie jest książką do nauki
programowania. Mam natomiast nadzieję, że będzie ona pożyteczna dla każde-
go, kto zna i używa języka C. Można na tę książkę spojrzeć na dwa sposoby.
Z jednej strony zawiera ona bardzo solidne i dogłębne opisy pewnych zagadnień
i może służyć jako podręcznik, do którego się często sięga w pracy (takie są roz-
działy o funkcjach formatowanego wejścia-wyjścia i preprocesorze). Z drugiej
zaś strony książka ta pełna jest perełek, nietypowych konstrukcji i zastosowań
języka. Słowem, nawet zaawansowani programiści znajdą tu coś ciekawego.
Rozdziały są właściwie niezależne od siebie i mogą być czytane w dowolnej
kolejności. Tym nie mniej, są one ułożone kolejno, według rosnącego stopnia
trudności i czytane po kolei będą najłatwiejsze do zrozumienia. Poza tym, przed
przeczytaniem rozdziału o programowaniu współbieżnym, w którym bardzo in-
tensywnie jest używany preprocesor, radzę przeczytać rozdział o preprocesorze.
Na deser radzę zostawić ostatni rozdział o niewiele mówiącym tytule "Kod wy-
nikowy". Opisuję w nim między innymi jak kompilować programy w C żeby
otrzymać kod o długości rzędu 50 bajtów i jak automatycznie zamienić zwykły
program w program rezydentny. Po przeczytaniu tego rozdziału trudno będzie
się oprzeć przed spędzeniem nocy przy komputerze.
Gliwice 29.05.1993
A.S.
I. Programowanie niestrukturalne
3
I. Programowanie niestrukturalne
Tytuł może trochę dziwić: w książkach o programowaniu można raczej spotkać
rozdziały o programowaniu strukturalnym. Wielu programistów i autorów ma do
sprawy strukturalności stosunek dogmatyczny, nie dopuszczając żadnych od-
stępstw. Ja chciałbym tutaj wziąć w obronę "wyklęte niestrukturalności" i przy
okazji przedstawić sposób ich realizacji w języku C. Rozdział ten przedstawia
zarówno zastosowania konstrukcji niestrukturalnych w "solidnym" programowa-
niu, jak i pewne "sztuczki". W niektórych przykładach pokażę, że czasami algo-
rytm niestrukturalny może dać bardziej czytelny program. Znajdą się w tym
rozdziale także konstrukcje nietypowe, prawdopodobnie mniej czytelne,
w których niestrukturalność zastosowano w celu otrzymania bardzo zwięzłego
kodu.
Przypomnijmy najpierw, na czym polega programowanie strukturalne. Zakłada
ono, że sterowanie nie może być przekazywane przy pomocy żadnych instrukcji
skoku z wyjątkiem tych "zaszytych" w instrukcjach sterowania pętli (
for
Przyjęcie takiej zasady jest na ogół słuszne i zmusza do bardziej porządnego kon-
struowania programu (piszę "zmusza", bo w wielu przypadkach zapisanie algoryt-
mu w sposób strukturalny jest trudniejsze). Czasami jednak podporządkowanie się
tej zasadzie powoduje zbytnie zagnieżdżenie struktur programu i czyni go mniej
czytelnym. W takiej sytuacji należy oczywiście zastosować rozwiązanie dające
program bardziej przejrzysty, nawet jeśli jest ono niestrukturalne. Innym powodem
zastosowania konstrukcji niestrukturalnej jest chęć skrócenia kodu wynikowego
(na przykład w programach rezydentnych). W takich sytuacjach mądrze zaplano-
wany skok pozwala często uniknąć zbędnego powtarzania jakiejś sekwencji in-
strukcji.
while
4
Wgłąb języka C
1.Instrukcje break i continue
Wbrew dość powszechnemu mniemaniu programowanie niestrukturalne to nie
tylko, i nawet nie przede wszystkim instrukcja
goto
języku C najczęściej
używane instrukcje niestrukturalne to
break
i
continue
Można powiedzieć, że
są to instrukcje bardziej "cywilizowane" od
goto
Sprowadzają się one do wyko-
nania skoku, ale nie jest to skok do dowolnie umieszczonej etykiety lecz
w konkretne miejsce, związane z pętlą, w obrębie której instrukcje te występują
Instrukcja
break
powoduje wyjście z pętli, czyli zakończenie jej działania
z powodu innego niż niespełnienie warunku w instrukcji pętli. Użycie instrukcji
break
jest możliwe w dowolnym miejscu pętli i może wystąpić dowolną ilość ra-
zy. Wyjście z pętli za pomocą instrukcji
break
jest bardzo wygodne, gdy waru-
nek wyjścia ze względu na swoją naturę nie powinien być dołączony do głównego
warunku pętli (takim warunkiem jest np. sprawdzanie, czy nie wystąpił błąd). In-
strukcja
break
powoduje wyjście tylko z tej pętli, w której się bezpośrednio znaj-
duje i nie umożliwia wyjścia na zewnątrz kilku zagnieżdżonych pętli. Strukturalną
alternatywą dla instrukcji
break
jest rozbudowanie warunku pętli. Czasami trzeba
użyć specjalnej zmiennej sterującej i dodać do warunku pętli sprawdzanie jej war-
tości. Taki zapis jest zwykle mniej czytelny, szczególnie gdy warunki pętli są i tak
rozbudowane, lub trzeba dodawać zmienną sterującą. Dodatkową wadą jest fakt,
że przed wyjściem z pętli
for
(przed sprawdzeniem warunku) zostanie wyliczone
wyrażenie modyfikujące (trzecie wyrażenie w instrukcji
for
)
Oto kilka sytuacji, w których instrukcja
break
umożliwia napisanie czytelnego
i naturalnego kodu:
Czytanie pliku aż do znalezienia danego znaku.
while((c=getc(file)!=EOF)
if(c=='

')break;
W wyniku wykonania tej pętli, wskaźnik pliku zostanie ustawiony w pozycji za
pierwszym wystąpieniem znaku '
'.
Użycie rozwiązania wykorzystującego instrukcję
break
odwzorowuje naturalne
sformułowanie problemu: czytamy kolejne znaki aż do końca pliku
while((c=getc(file)!=EOF)
i dla każdego sprawdzamy, czy nie jest to znak '
'
if(c=='

')break;
Połączenie warunków w podobnych wypadkach daje zwykle wyrażenie złożone,
trudniejsze do zrozumienia. Zdaję sobie sprawę, że każdy programista bezbłędnie
rozumie najbardziej skomplikowane wyrażenia w swoim programie i irytują go ar-
gumenty typu: 'za kilka miesięcy nie będziesz wiedział co Twój program robi' albo
I. Programowanie niestrukturalne
5
'należy pisać tak, żeby program był zrozumiały także dla innych'. Moim zdaniem
jednak istnieje ważniejszy argument za porządnym kodowaniem programów. Je-
żeli programista ma wyrobiony nawyk zastanawiania się, jak zakodować wymy-
ślony algorytm, a nie pisania szybko, byle działało (niestety, sam tak często robię),
to jest szansa, że zanim zrealizuje swój pierwszy pomysł, wymyśli lepszy algo-
rytm.
Czasami jakiś warunek opuszczenia pętli powinien znaleźć się we-
wnątrz ciała pętli i nie może być umieszczony w jej głównym warunku,
który znajduje się na początku albo na końcu. Oczywiście nie oznacza
to, że nie da się takich algorytmów zapisać z jednym tylko warunkiem
pętli. Aby to jednak zrobić, trzeba często stosować zmienne pomocnicze
i dodatkowe instrukcje warunkowe. Sytuację taką ilustrują poniższe
przykłady:
do {
openwind(38,9,66,11,"WCZYTA_");
if(edline(name,1,1,25,name))
{
closewind();
break;
}
closewind();
}
while(read());
Jest to uproszczony fragment rzeczywistego programu. Funkcje
openwind
oraz
closewind służą do otwierania i zamykania okienka tekstowego. Funkcja
edline
służy do wczytania z klawiatury ciągu znaków (w tym wypadku nazwy pliku).
Zwraca ona wartość niezerową, gdy użytkownik w czasie wpisywania ciągu naci-
snął klawisz E
SC
. Funkcja
read
odczytuje z dysku plik o nazwie name. Jeżeli pli-
ku nie uda się otworzyć, wypisuje ona komunikat o błędzie i zwraca wartość
niezerową. Oczywiście także tę pętlę dałoby się zapisać w pełni strukturalnie, bez
użycia instrukcji
break
,
ale kod byłby mniej czytelny
Następny fragment pochodzi z rezydentnego programu wyróżniającego
słowa kluczowe języka C na ekranie. Poniższa pętla (zamieszczona tu
w postaci uproszczonej) ma za zadanie sprawdzić, czy w danym
miejscu ekranu (wskazywanym przez zmienną scr) zaczyna się słowo
kluczowe C. Jeżeli takie słowo zostanie znalezione, jest ono wyróżniane
przez zmianę atrybutu. Przed wejściem do pętli zmienna list wskazuje
tablicę słów kluczowych C.
char *listtab[]={"for","int","if","char","while","case","do",
"else","return","void","default","struct",
"switch","far","extern","break","goto",
"float","const","continue","include","define",
"unsigned","static","sizeof",0},**list;
/* ... */
[ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • filmowka.pev.pl
  •