POLITECHNIKA KRAKOWSKA - WIEiK KATEDRA AUTOMATYKI i TECHNIK INFORMACYJNYCH Metody Programowania www.pk.edu.pl/~zk/mp_hp.html Wykładowca: dr inż. Zbigniew Kokosiński zk@pk.edu.pl
Wykład 15: Klasyczne techniki programowania Programowanie strukturalne E.W. Dijkstra (1968) Wady instrukcji GO TO Instrukcje strukturalne Metody projektowania programów Zasada abstrakcji poziomy abstrakcji Programowanie modularne Graficzne przedstawianie programów Schematy blokowe i diagramy strukturalne Niestrukturalność Metoda skrzynek zastępczych Automatyzacja w tworzeniu programów CASE
Programowanie strukturalne Böhm i Jacopini (1966) stworzyli podstawy teoretyczne programowania strukturalnego wykorzystującego tylko trzy podstawowe struktury: sekwencji instrukcji, warunku (if-thenelse) oraz pętli. Większość języków programowania zawierała wówczas popularną instrukcję GO TO. Dopiero list E.W. Dijkstry wskazujący na szkodliwość instrukcji GO TO i postulujący jej eliminację ze wszystkich języków programowania stanowił punkt zwrotny. Rozpoczęła się era programowania strukturalnego. Algorytm, a w ślad za nim program, powinien mieć strukturę zbliżoną do liniowej, pozbawioną krzyżujących się pętli i charakteryzującą się pojedynczym wejściem i wyjściem z każdego podprogramu. Niestosowanie się do tych zaleceń jest źródłem wielu problemów i utraty kontroli nad programem przez programistę.
Niestrukturalny schemat algorytmu
Wady instrukcji GO TO 1. Brak logicznej definicji tej instrukcji, może być stosowana wielokrotnie według uznania programisty w różnych miejscach programu. 2. Przekazywanie sterowania w dowolne miejsce programu narusza jego strukturę hierarchiczną. 3. Program napisany przez jednego programistę staje się nieczytelny dla drugiego, chociaż może być równocześnie logicznie poprawny i efektywny. 4. Stosowanie instrukcji GO TO utrudnia jeśli nie uniemożliwia formalne (zautomatyzowane) dowodzenie poprawności programów. 5. W maszynach z pamięcią wirtualną lub notatnikową wykonanie programu jest wyraźnie dłuższe.
Schemat blokowy programu
Wersja strukturalna i niestrukturalna Program: i:=1; P: if i>n then go to N else if a[i]=x then go to Z else i:=i+1; go to P; N: begin n:=i; a[i]:=x; b[i]:=0; end; Z: b[i]:=b[i]+1; Szkielet programu: Program strukturalny: δ1; δ1; P: if τ1 then go to N while ~τ1 and ~τ2 do δ2; else if τ2 then go to Z if τ1 then δ3; else δ2; δ4; go to P; N: δ3; Z: δ4;
struktura sekwencji Instrukcje strukturalne 1 struktura warunkowa: a) uproszczona, b) pełna
struktura wyboru Instrukcje strukturalne 2
Przykład: implementacje rozgałęzienia n-wartościowego dla n=8 : a) szeregowa, b) kaskadowa
Instrukcje strukturalne 3 struktury pętli : a) until, b) while
Przykład: zagnieżdżanie pętli a) sekwencja b) pierwsza pętla c) pętla zagnieżdżona
Przykład: schematy nietypowe a) z instrukcją exit, b) z pomocniczą zmienną
Metody projektowania programów Pisanie dużych i złożonych programów wymaga podejścia systematycznego, obejmującego : zdefiniowanie problemu do rozwiązania (opis funkcji programu) specyfikację systemu (określenie wymagań pod kątem końcowego użytkownika) Struktura problemu zapisywana jest zwykle w sposób sformalizowany w celu ułatwienia kodowania i późniejszej weryfikacji. Projektowanie obejmuje dostosowanie do własności i ograniczeń środowiska, optymalizację i sposób obsługi programu (komunikację z użytkownikiem). Efektem programowania jest hierarchiczna struktura składników proceduralnych (funkcyjnych) programu, relacje pomiędzy nimi i sposób przekazywania danych.
Metody projektowania programów Schematy planowania: kolejne poziomy abstrakcji definiowane intuicyjnie metodą top-down (Dijkstra); metoda alternatywna: bottom-up. podobna metoda, ale w oparciu o określone kryteria (Constaine, Myers) metoda jak wyżej, ale rozszerzona o matematyczne dowodzenia poprawności (Myers) - wymaga przygotowania matematycznego podział programu na powiązane ze sobą moduły - celem dekompozycji jest minimalizacja liczby tych powiązań, a tym samym redukcję wymiany informacji pomiędzy modułami (Parnas) punktem wyjścia jest określenie struktur danych programu (Jackson, Warnier)
Zasada abstrakcji Konkretne obliczenie reprezentuje zwykle całą klasę obliczeń. Zasada abstrakcji polega na uogólnieniu szczególnego przypadku problemu. Wielokrotne zastosowanie zasady abstrakcji prowadzi do zbudowania systemu hierarchicznego. Na czym polega abstrahowanie? 1. Rozważamy w sposób ogólny rozmiary problemu i wartości danych wejściowych. 2. Program opisuje nie jeden ale całą rodzinę procesów obliczeniowych. Treść programu odzwierciedla wspólne istotne właściwości wszystkich procesów danej klasy. 3. Przetwarzanie danych obejmuje tylko aspekty istotne dla rozwiązania danego problemu. Dane wejściowe są szczegółowe na tyle, aby rozwiązać problem.
Przykład: poziomy opisu
Poziomy abstrakcji żaden poziom nie wie o własnościach i istnieniu poziomów wyższych komunikacja pomiędzy poziomami odbywa się za pomocą sztywnych pośrednictw (interfejsów) każdy poziom jest zestawem modułów każdy poziom posiada pewne zasoby, albo ukryte przed innymi poziomami, albo udostępnione w postaci odpowiedniej abstrakcji
Programowanie modularne moduł = względnie niezależna jednostka programu (podprogram) Moduły w językach programowania: MODULA2 (MODULE nazwa) Turbo Pascal (unit nazwa) ADA (package nazwa is) C++ (static class nazwa nazwa_obiektu) moduł z zewnątrz czarna skrzynka (nazwa+funkcje) moduł od środka wszystkie algorytmy zawarte w module
Programowanie modularne Prostotę systemu modułowego osiąga się przez : minimalizację powiązań międzymodułowych maksymalizację połączeń wewnętrznych Systemy modułowe powiązane: a) ściśle, b) luźno
Graficzne przedstawianie programów A. Sieci działań B. Diagramy strukturalne: 1 sekwencja 2, 3 decyzje 4, 5 pętle
Tworzenie i strukturogramu a) kolejne etapy budowy diagramu, b) przebieg sterowania
Tworzenie i strukturogramu a) pętla while, b) pętla repeat, c) pętla z wyjściem wielokrotnym, d) Pętla w pętli z badaniem z dołu.
Podstawowe elementy niestrukturalne
Metoda skrzynek (bloków) zastępczych Zasady ogólne transformacji schematu : 1. Wprowadzamy dodatkową zmienną, oznaczoną przez np. I 2. Każdej skrzynce w niestrukturalnym schemacie blokowym przyporządkuj numer porządkowy (STOP numer 0). Ponadto w miejscu skrzynki start wpisuje się instrukcję I:=1. 3. Do schematu blokowego wprowadza się skrzynki zastępcze. 4. Transformacja jest wykonywana w oparciu o schemat blokowy, jak na rysunku.
Metoda skrzynek zastępczych
Metoda skrzynek zastępczych przykład
Cykl życia programowania model kaskadowy Fazy modelu kaskadowego : specyfikacja założeń projekt wstępny - struktury projekt szczegółowy programowanie (kodowanie) integracja (scalanie) utrzymanie (maintenance)
Cykl życia programowania model kaskadowy
Automatyzacja tworzenia programów CASE (ang. computer aided software engineering) Zbiór narzędzi do automatyzacji tworzenia programów. Cele CASE: identyfikacja obiektu, dla którego należy skonstruować system informatyczny analiza i dekompozycja problemu na składowe systemu dobór właściwych narzędzi i metod realizacji tych składowych synteza systemu informatycznego
Literatura Malina W., Szwoch M. : Techniki programowania, Wydawnictwo PG, Gdańsk 2001