C++ WYKŁAD 13 (18.05.2016) Algorytmy. S PIS TREŚCI Funktory i predykaty Funkcje lambda.

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

C++ wykład 9 ( ) Szablony.
C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie obiektowe
C++ wykład 13,14,15 (16/23/ ) STL.
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Programowanie obiektowe
Standardowa biblioteka języka C++
Wzorce.
Język ANSI C Funkcje Wykład: Programowanie komputerów
Static, const, volatile.
PROGRAMOWANIE STRUKTURALNE
Struktury.
Biblioteki i przestrzenie nazw
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Języki programowania obiektowego
Podstawy programowania
Pakiety w Javie Łukasz Smyczyński (132834). Czym są pakiety? Klasy w Javie są grupowane w pewne zbiory zwane pakietami. Pakiety są więc pewnym podzbiorem.
Podstawy programowania II
Podstawy programowania
Podstawy programowania. Język C i C++– podstawy Temat: 1
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład IX.
Programowanie obiektowe III rok EiT
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Podstawy informatyki 2013/2014
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Programowanie obiektowe 2013/2014
Kurs języka C++ – wykład 13 ( )
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 9 ( )
Programowanie w języku C++
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
K URS JĘZYKA C++ – WYKŁAD 10 ( ) Szablony.
Programowanie strukturalne i obiektowe C++
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
Technologie internetowe Wykład 5 Wprowadzenie do skrytpów serwerowych.
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
Paweł Starzyk Obiektowe metody projektowania systemów
Podstawy informatyki Tablice Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Dokumentacja programu komputerowego i etapy tworzenia programów.
K URS JĘZYKA C++ – WYKŁAD 14 ( ) Narzędzia programistyczne w STL.
Podstawy informatyki Preprocesor Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Podstawy informatyki Funkcje Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
C++ WYKŁAD 12 ( ) Własne biblioteki. S PIS TREŚCI Kompilacja i łączenie Moduły Biblioteki Biblioteka statyczna Biblioteka współdzielona Biblioteka.
Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka Podstawy.
Dominik Benduski Michał Mandecki Podstawy Visual Basic w Excelu.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
K URS JĘZYKA C++ – WYKŁAD 1 ( ) Łagodne wprowadzenie do języka C++
K URS JĘZYKA C++ – WYKŁAD 7 ( ) Konwersje.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Typy wyliczeniowe, kolekcje
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
(według:
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 13 ( )
Programowanie obiektowe – zastosowanie języka Java SE
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

C++ WYKŁAD 13 ( ) Algorytmy

S PIS TREŚCI Funktory i predykaty Funkcje lambda

F UNKTORY I PREDYKATY Obiekt funkcyjny to obiekt, w którym jest zdefiniowany operator wywołania funkcji operator(). Zalety obiektów funkcyjnych: posiadają stan (pamięć), mają własny typ (mogą być parametrami szablonów), działają co najmniej tak szybko jak wskaźniki do funkcji. Funktor to obiekt klasy z operatorem wywołania funkcji. Predykat to funktor, który wyniku zwraca wartość boolowską.

O BIEKT FUNKCYJNY JAKO KRYTERIUM SORTOWANIA class Person { public: string firstname() const; string lastname() const; … }; class PersonSortCriterion { public: bool operator() (const Person &p1, const Person &p2) const { // a person is less than another person - if the last name is less // - if the last name is equal and the first name is less return p1.lastname()<p2.lastname() || p1.lastname()==p2.lastname() && p1.firstname()<p2.firstname(); } };

O BIEKT FUNKCYJNY ZE STANEM WEWNĘTRZNYM class IntSequence { private: int value; public: // constructor IntSequence (int initialValue = 0) : value(initialValue) {} // ‘‘function call’’ int operator() () { return ++value; } };

A LGORYTM FOR _ EACH Algorytm for_each aplikuje funkcje zdefiniowaną w obiekcie funkcyjnym do wszystkich elementów kolekcji. Algorytm for_each zwraca swój obiekt funkcyjny. Przykład: class MeanValue { int num; // number of elements long sum; // sum of all element values public: MeanValue () : num(0), sum(0) {} void operator() (int elem) { ++num; // increment count sum += elem; // add value } double value () { return static_cast (sum) / num; } }; // … vector coll = /* … */; MeanValue mv = for_each(coll.begin(), coll.end(), MeanValue()); cout << mv.value() << endl;

P REDEFINIOWANE OBIEKTY FUNKCYJNE Arytmetyczne obiekty funkcyjne: negate<>, plus<>, minus<>, multiplies<>, divides<>, modulus<>. Obiekty funkcyjne porównujące: less<> (domyślne kryterium przy sortowaniu czy wyszukiwaniu binarnym), greater<>, less_equal<>, greater_equal<>, equal_to<>, not_equal_to<>. Obiekty funkcyjne do tworzenia wyrażeń logicznych: logical_not<>, logical_and<>, logical_or<>.

F UNKCJE LAMBDA Programista często chciałby zdefiniować predykatowe funkcje w pobliżu wywołań takich funkcji, jak na przykład pochodzących ze standardowej biblioteki (szczególnie sort i find ) – oczywistym rozwiązaniem jest zdefiniowanie w takim miejscu funkcji lambda (określanej też jako lambda-wyrażenie). Funkcje lambda to anonimowe obiekty funkcyjne. Lambdy nie posiadają ani konstruktora domyślnego ani operatora przypisania. Główne zastosowanie funkcji lambda to ich użycie jako argumentu sterującego obliczeniami w innych funkcjach. Przykład: [](int x, int y) { return x + y; }

F UNKCJE LAMBDA Funkcja lambda określa typ zwracanego wyniku za pomocą frazy -> TYP. Przykład: [](int x, int y) -> int { int z = x * x; return z + y + 1; } Jeśli ciało funkcji lambda składa się z jednej instrukcji return, to typ zwracanego wyniku będzie wydedukowany za pomocą decltype() (możne wtedy pominąć frazę -> TYP ). Przykład: [](int x, int y) // -> decltype(x*x+y+1) { return x * x + y + 1; }

F UNKCJE LAMBDA Dostęp do lokalnych zmiennych lub pól w obiekcie określa się w funkcji lambda za pomocą domknięcia, czyli wewnątrz początkowych nawiasów kwadratowych [] na początku definicji. Domknięcie puste [] oznacza, że funkcja lambda nie potrzebuje dostępu do zmiennych z lokalnego środowiska (zdefiniowanych poza funkcją lambda). Domknięcie [&] oznacza, że wszystkie zmienne z lokalnego środowiska są dostępne przez referencję. Domknięcie [=] oznacza, że wszystkie zmienne z lokalnego środowiska są dostępne przez wartość (kopiowanie wartości następuje w miejscach, w których funkcja lambda odwołuje się do zewnętrznych zmiennych). W domknięciu można umieścić listę zmiennych zewnętrznych, z których funkcja lambda może korzystać, na przykład: int x, y; // … [x, &y] (…) { return …; }

F UNKCJE LAMBDA Można utworzyć obiekt funkcyjny anonimowego typu reprezentujący lambdę : auto lambda = [](…)->…{ … }; Do takiej lamdy można się potem odwołać jak do funkcji: lambda(…); Przykład: vector v {9, 4, 1, 6, 8}; bool sensitive = true; // … auto lambda = [sensitive](int x, int y) { return sensitive ? x<y : abs(x)<abs(y); } sort(v.begin(), v.end(), lambda);

S PIS TREŚCI Kompilacja i łączenie Moduły Biblioteki Biblioteka statyczna Biblioteka współdzielona Biblioteka dynamiczna Tworzenie bibliotek Nazwy zewnętrzne

K OMPILACJA I ŁĄCZENIE Plik jako jednostka kompilacji. Preprocesing – obsługa makr i dyrektyw włączających – dostarcza kompilatorowi jednostkę translacji. Kompilator analizuje jednostkę translacji w izolacji od reszty programu. Fizyczna struktura programu (podział na pliki) powinna wynikać z logicznej struktury programu. Rola linkera przy budowaniu programu albo biblioteki.

M ODUŁY Każdy większy program składa się z pewnej liczby oddzielnych części – modułów. Moduł to kompletny fragment programu (moduł obliczeniowy, moduł we/wy, moduł prezentacji, itp). Podział kodu na moduły porządkuje logikę programu. Należy minimalizować zależności między modułami.

B IBLIOTEKI Moduły, z których może korzystać wiele programów umieszcza się w oddzielnych skompilowanych plikach, zwanych bibliotekami. Typy bibliotek w C++: biblioteka statyczna jest dołączana do programu wynikowego na etapie linkowania; biblioteka współdzielona jest dołączana do programu w trakcie ładowania programu do pamięci; biblioteka dynamiczna jest dołączana do uruchomionego procesu w trakcie działania programu.

B IBLIOTEKI Biblioteka to zbiór klas, funkcji i zmiennych, z których mogą korzystać różne programy. Biblioteka ma postać binarną – jej poszczególne fragmenty są skompilowane (biblioteka jest kolekcją plików obiektowych). Korzystanie z bibliotek ułatwia programowanie (korzystamy z gotowych i sprawdzonych fragmentów kodu) i przyspiesza proces rekompilacji.

B IBLIOTEKI Wynikiem samej kompilacji pliku źródłowego ( plik.c albo plik.cpp ) jest plik plik.o pod Linuxem albo plik.obj pod Windowsem. Biblioteki statyczne mają nazwy libmodul.a pod Linuxem albo modul.lib pod Windowsem. Biblioteki dynamiczne mają nazwy libmodul.so pod Linuxem (tak jak biblioteki współdzielone) albo modul.dll pod Windowsem.

B IBLIOTEKA STATYCZNA Używając biblioteki statycznej przekazujemy jej archiwum linkerowi w czasie kompilacji. Linker wyszukuje w nim tylko tych plików obiektowych, które są niezbędne do działania naszego programu i kopiuje je bezpośrednio do programu. Program wynikowy korzystający z biblioteki statycznej jest obszerniejszy ale szybciej się ładuje do pamięci. Program wynikowy zlinkowany z biblioteką statyczną jest niezależny od plików zewnętrznych. Uaktualnienie biblioteki wymaga rekompilacji programu.

B IBLIOTEKA STATYCZNA lib.cpp lib.o static library prog.cpp prog.o a.out memory linker loader g++ar g++ ssh

B IBLIOTEKA WSPÓŁDZIELONA Programy korzystające biblioteki współdzielonej nie zawierają bezpośrednio kodu z tej biblioteki a tylko referencję do niej. Program wynikowy korzystający z biblioteki współdzielonej jest chudszy ale wolniej ładuje się do pamięci (biblioteki współdzielone są odszukiwane i ładowane do pamięci razem z programem). Program wynikowy skompilowany z biblioteką współdzieloną jest zależny od plików zewnętrznych. Zmodyfikowanie biblioteki współdzielonej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.

B IBLIOTEKA WSPÓŁDZIELONA lib.cpp lib.o shared library prog.cpp prog.o a.out memory linker loader g++ ssh

B IBLIOTEKA DYNAMICZNA Programy korzystające bibliotek dynamicznych nie zawierają bezpośrednio kodu z tej biblioteki ale muszą korzystać ze specjalnych metod włączania takich bibliotek w trakcie działania programu (plik nagłówkowy ). Program wynikowy korzystający z biblioteki dynamicznej jest chudszy i szybciej ładuje się do pamięci, ale działa wolniej (biblioteki dynamiczne można załadować w dowolnym momencie w trakcie działania programu). Program wynikowy skompilowany z biblioteką dynamiczną jest zależny od plików zewnętrznych. Zmodyfikowanie biblioteki dynamicznej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.

B IBLIOTEKA DYNAMICZNA lib.cpp lib.o dynamic library prog.cpp prog.o a.out memory linker loader g++ ssha.out

T WORZENIE BIBLIOTEK ( POD L INUXEM ) Tworzenie programu bez dołączanych bibliotek. Załóżmy, że mamy pliki src1.cpp, src2.cpp i src3.cpp, które stanowią moduł obliczeniowy oraz plik prog.cpp, który będzie korzystał z funkcji i klas zdefiniowanych w module obliczeniowym. Aby skompilować cały program razem z modułem obliczeniowym należy wydać polecenie: $ g++ -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp prog.cpp -o calculation Aby skompilować cały program razem z modułem obliczeniowym i statycznie zlinkować z innymi bibliotekami (rozmiar programu wynikowego będzie znacznie większy) należy wydać polecenie: $ g++ -static … Aby uruchomić skompilowany program należy wydać polecenie: $./calculation Aby sprawdzić z jakimi bibliotekami jest linkowany program i jakie symbole są w nim użyte należy wydać polecenie: $ ldd calculation $ nm calculation

T WORZENIE BIBLIOTEK ( POD L INUXEM ) Program korzystający z biblioteki statycznej. Najpierw kompilujemy pliki źródłowe do plików obiektowych: $ g++ -c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.a : $ ar src libsrc.a src1.o src2.o src3.o Na koniec należy skompilować plik z programem i zlinkować go z biblioteką: $ g++ -c -Wall -ansi -pedantic prog.cpp $ g++ -o calculation prog.o –L. –lsrc Teraz można uruchomić skompilowany program: $./calculation Wyjaśnienie: opcja -L ścieżka określa ścieżkę do biblioteki, opcja -l biblioteka określa nazwę biblioteki.

T WORZENIE BIBLIOTEK ( POD L INUXEM ) Program korzystający z biblioteki współdzielonej. Najpierw kompilujemy pliki źródłowe z opcją -fpic do plików obiektowych: $ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.so : $ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o Na koniec należy skompilować plik z programem i wlinkować do niego informacje o bibliotece: $ g++ -Wall -ansi -pedantic prog.cpp $ g++ -o calculation prog.o –L. –lsrc Przed uruchomieniem programu trzeba zapisać w zmiennej środowiskowej LD_LIBRARY_PATH ścieżkę do biblioteki: $ export LD_LIBRARY_PATH= " LD_LIBRARY_PATH: ścieżka " Teraz można uruchomić skompilowany program: $./calculation

T WORZENIE BIBLIOTEK ( POD L INUXEM ) Program korzystający z biblioteki dynamicznej. Bibliotekę dynamiczną przygotowujemy tak samo jak bibliotekę współdzieloną libsrc.so : $ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp $ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o Na koniec należy skompilować plik z programem i dołączyć do niego dynamicznego linkera opcją -ldl : $ g++ -Wall -ansi -pedantic prog.cpp $ g++ -o calculation prog.o –ldl Teraz można uruchomić skompilowany program: $./calculation Wyjaśnienie: aby skorzystać z dynamicznego linkera należy do programu włączyć plik nagłówkowy ; aby załadować dynamiczną bibliotekę trzeba skorzystać z funkcji dlopen, dlsym, dlerror i dlclose.

N AZWY ZEWNĘTRZNE Nazwa jest łączona zewnętrznie jeśli można jej używać w jednostkach translacji innej niż ta, w której ją zdefiniowano. Nazwę zewnętrzną deklaruje się za pomocą słowa extern. Funkcja wbudowana musi być zdefiniowana w każdej jednostce translacji za pomocą identycznej definicji; ta sama reguła odnosi się do funkcji i klas szablonowych.

N OWOŚCI Z C++11 – SZABLONY ZEWNĘTRZNE I ALIASY SZABLONÓW Kompilator języka C++ musi stworzyć instancję szablonu zawsze kiedy napotka w pełni określony szablon w jednostce translacyjnej. W starszej wersji C++ nie było możliwości wstrzymania tworzenia instancji szablonu w takiej sytuacji. Obecnie wprowadzono ideę szablonów zewnętrznych w celu zablokowania tworzenia instancji w jednostce translacyjnej. Przykład: extern template class std::vector ; Należy zagwarantować, aby w jakiejś innej jednostce translacji instanja tego typu była utworzona. W języku C++ można używać aliasów dla szablonów. Przykład: template using vect = std::vector >;