dr inż. Paweł Myszkowski Politechnika Białostocka Wydział Elektryczny Elektronika i Telekomunikacja, semestr II, studia stacjonarne I stopnia Rok akademicki 2015/2016 Wykład nr 5 (16.03.2016)
Plan prezentacji: paradygmaty programowania generacje języków programowania
Paradygmaty programowania definicje pojęcia "paradygmat" klasyfikacje paradygmatów programowania założenia i uwagi omówienie podstawowych paradygmatów
Paradygmat [gr. parádeigma wzór] 1. ogólnie uznane osiągnięcie naukowe, które w pewnym okresie dostarcza modelowych rozwiązań w danej dziedzinie nauki [Encyklopedia PWN] 2. przyjęty sposób widzenia rzeczywistości w danej dziedzinie, doktrynie itp. [Słownik Języka Polskiego PWN] Bliskie znaczeniowo: wzorzec, punkt widzenia, podejście, model
Paradygmat programowania - wzorzec programowania, przedkładany w danym okresie rozwoju Informatyki ponad inne lub szczególnie ceniony w pewnych okolicznościach lub zastosowaniach, - ogół środków, metod, konwencji stosowany w pewnym sposobie programowania, - zbiór koncepcji reprezentujących podejście do implementacji algorytmów, - zbiór mechanizmów, jakich używa programista pisząc program.
Podstawowe paradygmaty Programowanie Obiektowe Imperatywne Agentowe Deklaratywne Strukturalne Zdarzeniowe Proceduralne Logiczne Funkcyjne Modularne
Uwagi: - paradygmat programowania definiuje punkt podejścia programisty do sterowania i wykonywania programu komputerowego, - różne języki programowania mogą wspierać różne paradygmaty (np. Java i Smalltalk obiektowy, asembler imperatywny), - niektóre języki programowania mogą wspierać wiele różnych paradygmatów (C++ - proceduralny, strukturalny, obiektowy), - wybór paradygmatu ma często kluczowy wpływ na łatwość implementacji algorytmu.
Co odróżnia poszczególne paradygmaty: - sposób podejścia do danych, - sposób podejścia do kodu, - sposób wiązania kodu z danymi, - sposób podejścia do sterowania. Program = Kod + Dane Kod = Algorytm + Język programowania Dane = Struktury + Język programowania Programowanie = przejście od nieformalnego opisu problemu do formalnego opisu implementacji rozwiązania. Sposób przejścia narzuca wybrany paradygmat.
Założenia paradygmatu realizuje się przy użyciu języka programowania. Język programowania może: - wspierać paradygmat: zawiera środki pozwalające wyrażać paradygmat wprost, - umożliwiać paradygmat: pozwala wyrażać pewien paradygmat, ale kosztem dodatkowego wysiłku programisty. Np. język C umożliwia programowanie obiektowe, język C++ wspiera programowanie obiektowe.
Wsparcie dla paradygmatu: - konstrukcje języka np. wywołanie procedury, utworzenie obiektu, aktywacja metody, zdefiniowanie reguły itp., - diagnostyka kompilatora np. sprawdzanie zgodności typów, - diagnostyka czasu wykonania (run-time) np. wykrywanie niezainicjowanych obiektów, - biblioteki standardowe procedury, funkcje, obiekty, reguły, - środowisko programisty specjalizowane edytory, debuggery, itp.
Paradygmat imperatywny polega na sekwencyjnym (krok po kroku) wykonywaniu instrukcji modyfikujących wartości zmiennych. - łac. imperare = rozkazywać - najbardziej podstawowy i naturalny sposób programowania, w którym program jest sekwencją instrukcji, zmieniających stan maszyny, aż do uzyskania pożądanego wyniku, - stan maszyny = zawartość pamięci operacyjnej, rejestrów i znaczników procesora, - bezpośrednio odzwierciedla sposób działania maszyny von Neumanna, jednak nie przystaje do sposobów rozwiązywania problemów przez człowieka,
Paradygmat imperatywny - programy tego typu są czasochłonne w opracowaniu, trudne w utrzymaniu i rzadko nadają się do ponownego użycia kodu. - zastosowanie: przede wszystkim języki niskiego poziomu, - języki wysokiego poziomu Fortran, Algol, Pascal, Ada lub C posługują się pewnymi abstrakcjami, ale wciąż odpowiadają paradygmatowi programowania imperatywnego, - przykład: zmienna jest abstrakcją komórki pamięci instrukcja przypisania pobiera dane z pamięci lub umieszcza dane w komórce.
Paradygmat imperatywny Przykład wyznaczanie rezystancji metodą techniczną: float U, I, R; printf("podaj wartość napięcia na badanej rezystancji"); scanf("%f", &U); printf("podaj wartość prądu płynącego przez rezystancję"); scanf("%f",&i); R = U / I; printf("wartość rezystancji wyznaczona met. techn.: %f",r);
Paradygmat strukturalny charakteryzuje się użyciem prostych, ściśle zdefiniowanych struktur (konstrukcji programistycznych). Rodzaje struktur sterujących: - sekwencja wykonanie instrukcji w określonej kolejności, - selekcja wykonanie jednej z kilku instrukcji zależnie od stanu programu (if-then-else oraz switch-case), - cykl (iteracja) powtarzanie instrukcji tak długo, jak długo spełniony/niespełniony jest dany warunek (for, while, repeat-until). W tym podejściu unikamy instrukcji skoku (goto) oraz innych tego typu (break, continue).
Paradygmat strukturalny Celem stosowania paradygmatu strukturalnego jest pisanie programów przejrzystych, łatwych w rozumieniu i utrzymaniu (w rozumieniu imperatywnym).
Paradygmat strukturalny Przykład wyznaczanie rezystancji metodą techniczną: float U, I, R; //wczytanie danych if (I == 0) { printf("przerwa w obwodzie nie mogę wyznaczyć rezystancji"); } else { R = U / I; printf("wartość rezystancji wyznaczona met. techn.: %f", R); }
Paradygmat zdarzeniowy paradygmat, zgodnie z którym program jest cały czas "atakowany" zdarzeniami, na które musi reagować. Zdarzenia napływają do programu: - od systemu operacyjnego, - od użytkownika (urządzenia sterujące), - od innych uruchomionych programów, - od świata zewnętrznego (inne urządzenia wejściowe). Obecnie nie da się praktycznie napisać aplikacji z interfejsem graficznym, nie stosując paradygmatu zdarzeniowego.
Paradygmat proceduralny zalecający dzielenie kodu na procedury, czyli fragmenty wykonujące ściśle określone operacje. - najstarszy podtyp paradygmatu imperatywnego, - wciąż jeden z najpowszechniej stosowanych, mimo rozwoju nowszych paradygmatów (szczególnie obiektowego), - większość języków programowania ma mechanizmy wsparcia: - wydzielenie porcji kodu w postaci funkcji lub procedury, - różne sposoby przekazywania parametrów: przez kopię, przez nazwę, przez wartość, przez zmienną, przez wskazanie, przez referencję, - zwracanie wartości przez funkcję.
Paradygmat proceduralny Przykład wyznaczanie rezystancji metodą techniczną: float wyznacz_r (float nap, float nat) { return(nap/nat); } int main() { float U, I, R; //wczytanie danych R = wyznacz_r(u,i); printf("wartość rezystancji wyznaczona met. techn.: %f",r); }
Paradygmat obiektowy polega na operowaniu obiektami; obiekt to kombinacja danych określających jego stan oraz operacje z nim związane. - model odpowiada sposobowi opisu rzeczywistości przez człowieka: opisuje ją jako zbiór obiektów posiadających stan i zachowanie, - paradygmat ma zastosowanie nie tylko na etapie implementacji kodu, lecz również na etapie analizy i projektowania, - podejście obiektowe sprzyja tworzeniu kodu nadającego się do wielokrotnego wykorzystania, - wprowadza nowe udogodnienia: enkapsulacja, hermetyzacja, polimorfizm, dziedziczenie. - silne wsparcie: Java, C++, C#, Smalltalk.
Paradygmat obiektowy Przykład wyznaczanie rezystancji metodą techniczną (1/3): class rezystor { float R; float U; float I; public: void przypisz(float nap, float nat); void oblicz(); void wypisz(); }; //definicja klasy //dane //funkcje, czyli metody
Paradygmat obiektowy Przykład wyznaczanie rezystancji metodą techniczną (2/3): void rezystor::przypisz(float nap, float nat) { U=nap; I=nat; //definicje metod } void rezystor::oblicz() { R = U/I; } void rezystor::wypisz() { printf("rezystancja obliczona met. techn.: %f",r); }
Paradygmat obiektowy Przykład wyznaczanie rezystancji metodą techniczną (3/3): rezystor Pt100; //deklaracja obiektu klasy "rezystor" Pt100.przypisz(12.3, 0.45); Pt100.oblicz(); //wywołanie metod na rzecz obiektu Pt100.wypisz();
Paradygmat modularny stanowi rozwinięcie paradygmatu proceduralnego w sytuacji większej złożoności i objętości programu. Paradygmat agentowy stanowi rozwinięcie paradygmatu obiektowego do wyższego poziomu abstrakcji.
Paradygmat logiczny Na program składają się zbiór faktów, zbiór zależności (przesłanki) oraz pewne stwierdzenie (cel). - wykonanie programu to próba udowodnienia celu w oparciu o znane fakty i podane przesłanki : - obliczenia wykonywane są "przy okazji" dowodzenia celu, - program specyfikuje cel, a nie sposób dojścia do niego, - program decyduje, jakich reguł użyć i w jakiej kolejności, aby stwierdzić, czy cel jest osiągalny, - niezbędny jest interpreter! - Prolog najbardziej znany język programowania logicznego.
Paradygmat logiczny Przykład: > znane fakty > Marek jest ojcem Piotra, Piotr jest ojcem Jacka i Kamila > bycie dziadkiem oznacza bycie ojcem ojca > cel wnioskowania > kto jest dziadkiem Jacka? ojciec (Marek, Piotr). ojciec (Piotr, Jacek). ojciec (Piotr, Kamil). dziadek(a, C) :- ojciec(a, B), ojciec(b, C).? dziadek(x, Jacek).
Zagadka Einsteina [tylko 3% populacji jest w stanie ją rozwiązać] 5 ludzi różnych narodowości zamieszkuje 5 domów w 5 różnych kolorach. Wszyscy palą papierosy 5 różnych marek i piją 5 różnych napojów. Hodują zwierzęta 5 różnych gatunków. Który z nich hoduje rybki? Norweg zamieszkuje pierwszy dom Anglik mieszka w czerwonym domu. Zielony dom znajduje się bezpośrednio po lewej stronie domu białego. Duńczyk pija herbatkę. Palacz papierosów light mieszka obok hodowcy kotów. Mieszkaniec żółtego domu pali cygara. Niemiec pali fajkę. Mieszkaniec środkowego domu pija mleko. Palacz papierosów light ma sąsiada, który pija wodę. Palacz papierosów bez filtra hoduje ptaki. Szwed hoduje psy. Norweg mieszka obok niebieskiego domu. Hodowca koni mieszka obok żółtego domu. Palacz mentolowych pija piwo. W zielonym domu pija się kawę.
Zagadka Einsteina [tylko 3% populacji jest w stanie ją rozwiązać] >Rozwiązanie metodą "brute force" Generowanie wszystkich możliwych permutacji danych i odrzucanie tych, które nie spełniają warunków zadania: (5!) 5 = (1*2*3*4*5) 5 = 120 5 = 24 883 200 000 sposobów! >Programowanie logiczne Wprowadzenie danych Sformułowanie reguł Komputer klasy Pentium III Rozwiązanie otrzymane w ciągu ułamków sekundy!
Paradygmat funkcyjny polega na operowaniu nie na zmiennych, lecz na wartościach. Paradygmat aspektowy wspomaga separację zagadnień i rozdzielenie programu na części w jak największym stopniu niezwiązane funkcjonalnie. Paradygmat uogólniony pozwala na pisanie kodu programu bez wcześniejszej znajomości typów danych, na których kod ten będzie pracował.
Podział języków - wieloparadygmatowe: Ada, Clojure, Common Lisp, D, Icon, Nemerle, Ruby, Snobol, Python, Ocaml; - imperatywne: AWK, C, COBOL, Forth, Fortran, Modula 2, Oberon, Pascal, Perl, Rexx; - obiektowe: Action Script, C++, C#, Delphi, Eiffel, Java, JavaScript, Object Pascal, Objective, Oxygene, Smalltalk; - funkcyjne: Clojure, Erlang, F#, Haskell, Lisp, ML, Ocaml, Scheme; -logiczne: Prolog, Goedel.
Generacje języków programowania historię rozwoju języków programowania podzielono na pięć okresów (generacji) generacje opisują zaawansowanie struktur języka i przystępność jego składni dla programisty 5 GL 4 GL 3 GL 2 GL 1 GL
I generacja programowanie bezpośrednio w kodzie binarnym każdy typ komputera posiada własny kod (listę rozkazów procesora) zwany kodem maszynowym każdy program musi być przepisany w konkretnym kodzie maszynowym 1000010110101010100010101011101010011010 1010101010101010010101010010101010010101 0101011111111111010101101111111100000010 1010101010101010101010101010010101001010
II generacja dla ułatwienia programowania każdej kombinacji zerojedynkowej przypisano znaki mnemotechniczne języki operujące mnemonikami nazywane są językami symbolicznymi lub asemblerami asembler jest tłumaczeniem kodu maszynowego, nie musi być pisany pod konkretny typ komputera mov bx, 12 mov ax, 10 add ax, bx mov [3987], 20
III generacja języki III generacji to języki wysokiego poziomu, w których mnemoniki zastąpiono kodem niezależnym od maszyny, zbliżonym do języka naturalnego lub matematycznego języki wysokiego poziomu są uniwersalne często specjalizuje się języki III generacji do określonych zastosowań int x=0; for (int i=0; i<10; i++) x += tablica[i]; printf("suma: %d",x);
IV generacja języki IV generacji to środowiska graficzne, służące do generowania gotowych aplikacji na podstawie predefiniowanych modułów często stanowią rozszerzenie funkcjonalności istniejących języków (np. Visual Basic, Borland C++ Builder, JBuilder) języki programowania obiektowego należą do IV generacji
V generacja języki V generacji to języki programowania w logice, wykorzystujące sztuczną inteligencję, często pod postacią języka naturalnego lub języka zbliżonego do naturalnego często wymagają rozbudowanego środowiska ojciec (Marek, Piotr). ojciec (Piotr, Jacek). ojciec (Piotr, Kamil). dziadek(a, C) :- ojciec(a, B), ojciec(b, C)
Generacje języków - podsumowanie duża im niższy numer generacji, tym bardziej język zbliżony jest do warstwy sprzętowej im wyższy numer generacji, tym język jest bardziej intuicyjny i niezależny od sprzętu 5 GL język naturalny 4 GL SQL, PostScript 3 GL wysokiego poziomu, Java, C, C++ 2 GL niskiego poziomu, kod asemblera zrozumiałość 1 GL kod maszynowy liczba instrukcji mała
Języki programowania - klasyfikacje istnieje ponad 2500 języków programowania "linia czasu" O'Reilly przedstawia ok. 50 najpopularniejszych http://oreilly.com/news/graphics/prog_lang_poster.pdf
Języki programowania - przegląd Fortran (FORmula TRANslator) stworzony w latach 50-tych, ale nadal stosowany (ostatnia wersja: 2oo8 r.) pierwszy język wysokiego poziomu stosowany głównie do obliczeń naukowo-inżynierskich (szczególnie numerycznych) dysponuje ogromną liczbą bibliotek, umożliwiających rozwiązanie praktycznie każdego zadania numerycznego szybki i wydajny kod wynikowy generowany przez kompilatory Fortrana znakomita skalowalność i przenośność oprogramowania brak rozróżniania wielkości liter w zmiennych i słowach kluczowych dostępność bibliotek do programowania wieloprocesorowego i równoległego
Języki programowania - przegląd Fortran (FORmula TRANslator) - przykład kodu
Języki programowania - przegląd BASIC (Beginner All-purpose Symbolic Instruction Code) powstał w 1964 roku w oparciu o języki Algol i Fortran popularny w komputerach 8-bitowych i kalkulatorach programowalnych brak definiowania typów danych początkowo konieczność numerowania instrukcji (linii) 10 PRINT "Witaj" 20 INPUT "Liczba gwiazdek do wyświetlenia: "; ile 30 PRINT "*" 40 LET ile = ile -1 50 IF ile > 0 THEN GOTO 30
Języki programowania - przegląd Pascal język wysokiego poziomu, opracowany w 1970 r. przez Niklausa Wirtha oparty na Algolu szczególnie popularny w latach 1980 1990 znakomity z dydaktycznego punktu widzenia, stąd jego popularność wśród początkujących programistów zalety: czytelność, zwięzłość kodu, kontrola typów danych i zakresów tablic, typ logiczny obecnie coraz rzadziej stosowany w praktyce
Języki programowania - przegląd Pascal - przykład kodu
Języki programowania - przegląd C imperatywny, strukturalny język programowania do programowania systemów operacyjnych i innych zadań niskiego poziomu stworzony przez Dennisa Ritchie cechy: udostępnia gotowe funkcje w bibliotekach umożliwia komentowanie kodu występują słowa kluczowe w programie umożliwia operacje na pamięci działa kontrola typów stosunkowo prosta składnia duża przenośność
Języki programowania - przegląd C++ obiektowy język programowania autorstwa Bjarne Stroustrupa, powstały jako rozszerzenie języka C (1979 r.) nazwa "C++", zaproponowana w 1983 r., pochodzi od operatora inkrementacji C++ zachowuje pełną zgodność z C na poziomie kodu źródłowego występuje niekompatybilność kompilatorów języka C++ w zakresie obsługiwanej składni wspiera różne paradygmaty, więc nie zmusza programisty do wyboru określonego stylu programowania ułatwia tworzenie i korzystanie z bibliotek (napisanych w C, C++ lub innych językach) wysoka wydajność kodu wynikowego
Języki programowania - przegląd Java język tworzenia programów źródłowych kompilowanych do kodu bajtowego, czyli postaci wykonywanej przez maszynę wirtualną opracowany przez Sun MicroSystems cechy: silnie ukierunkowany na obiektowość wszelkie dane i akcje na nich są pogrupowane w klasy obiektów niezależność od architektury przez kompilację do kodu pośredniego duże bezpieczeństwo i niezawodność działania nadaje się do zastosowań sieciowych i programowania rozproszonego
Języki programowania - przegląd Java - przykład kodu
Języki programowania klasyfikacje TIOBE Programming Community Index (March 2016) [1 10] http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Języki programowania klasyfikacje TIOBE Programming Community Index (March2016) [11 20] http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Języki programowania klasyfikacje TIOBE Programming Community Index (March 2016) [język PHP] http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Języki programowania klasyfikacje TIOBE Programming Community Index (March 2015) [Long Term History] http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Dlaczego C/C++? W czołówce najpopularniejszych języków programowania na świecie stanowi podstawę dla wielu innych języków (PHP, JavaScript, ) wspiera wiele paradygmatów (imperatywny, strukturalny, proceduralny, obiektowy) bliżej sprzętu niż Java: obsługa portów, wstawki asemblerowe
Dziękuję za uwagę. Wesołych Świąt Wielkanocnych! Kolejny wykład: 30 marca 2016 Zapraszam!