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 [email protected] 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; P: if τ1 then go to N else if τ2 then go to Z else δ2; go to P; N: δ3; Z: δ4; δ1; while ~τ1 and ~τ2 do δ2; if τ1 then δ3; δ4; Instrukcje strukturalne 1 • struktura sekwencji • struktura warunkowa: a) uproszczona, b) pełna Instrukcje strukturalne 2 • struktura wyboru 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