Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw Mirosław Głowacki 1 1 Akademia Górniczo-Hutnicza im. Stanisława Staszica w Ktrakowie Wydział Inżynierii Metali i Informatyki Stosowanej Katedra Informatyki Stosowanej i Modelowania Październik 2016 Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 1 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 2 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 3 / 31
Bardzo prosty program Większość kursów programowania rozpoczyna się od prostego, szablonowego kodu wyświetlającego napis Hello World! Spójrzmy na taki kod napisany w c++, który w tłumaczeniu na polski wyświetla oczywiście Witaj Świecie! #include <iostream> using namespace std; int main(){ cout << "Hello World!" << endl; return 0; Nasuwa się pytanie: po co jest instrukcja: using namespace std; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 4 / 31
Bardzo prosty program Najpierw jednak analiza kodu: Za pomocą #include <iostream> dołączyliśmy odpowiedni, tak zwany plik nagłówkowy, który umożliwia skorzystanie z odpowiedniej biblioteki i wypisywanie informacji na ekran (ściślej do standardowego strumienia wyjściowego). Dzięki int main() {... można zdefiniować funkcję główną, która jest zawsze uruchomiana podczas startu programu. Operacja cout << umożliwia wypisywanie pewnych informacji. W naszym przypadku wypisaliśmy napis "Hello World!", a następnie przedłużyliśmy to polecenie za pomocą znaku << i wstawiliśmy nową linię, która jest zdefiniowana przez endl. Za pomocą return 0 informujemy system, że program działał prawidłowo i nie wystąpiły żadne problemy. Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 5 / 31
Bardzo prosty program Wracamy do pytania co powoduje instrukcja: using namespace std? Najpierw inna wersja prostego programu: #include <iostream> int main(){ std::cout << "Hello World!" << std::endl; return 0; Jak widać usunieto linię using namespace std, a cout i endl poprzedzono nazwą std i operatorem ::. Właśnie std jest nazwą pewnej przestrzeni nazw. Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 6 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 7 / 31
Przestrzeń nazw std W przestrzeni nazw std znajdziemy cały arsenał narzędzi: począwszy od pewnych bardzo przydatnych funkcji np. sortowania, wyszukiwania, a skończywszy na tak zwanych pojemnikach, które pozwalają w łatwy sposób przechowywać pewne wartości. Aby mieć dostęp do tych narzędzi musimy dołączyć odpowiedni plik nagłówkowy, używając do tego dyrektywy #include. Pisząc std::cout << informujemy kompilator, że chcemy wejść do przestrzeni nazw std i skorzystać ze znajdującej się tam operacji cout << Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 8 / 31
Przestrzenie nazw Nie musimy za każdym razem odwoływać się do przestrzeni nazw, kiedy chcemy wywołać pewną, należącą do niej funkcję. Linią kodu: using namespace znajduje w przestrzeni nazw pn. pn ; udostępniamy wszystko, co się Dzięki temu nie musimy się martwić w jakiej przestrzeni nazw znajduje się funkcja czy klasa - wszystko jest pod ręką. Oczywiście nie musimy przenosić wszystkiego z danej przestrzeni nazw, a tylko pewne wybrane elementy: # include <iostream> using std::endl int main(){ std::cout << "Hello World!" << endl ; return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 9 / 31
Przestrzenie nazw Za pomocą using std::endl poinformowaliśmy kompilator, że używana przez nas funkcja kończąca linię (czyli endl ), znajduje się w przestrzeni nazw std. Dzięki temu można zamiast std::endl spokojnie pisać endl. Nie powinno być problemów także wtedy, gdybyśmy napisali std::endl. Nie wykonaliśmy analogicznej operacji na encji cout ściślej nie wstawiliśmy instrukcji using std::cout więc nadal trzeba poprzedzać ją nazwą tej przestrzeni. Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 10 / 31
Przestrzenie nazw Ale właściwie do czego są używane przestrzenie nazw? Przede wszystkim zapewniają pewien komfort programiście. Tworząc jakąś funkcję, nie musimy się martwić jak się ją nazwie, ponieważ raczej nie spowoduje to żadnych kolizji nazw z nazwami innych funkcji, które znajdują się w innych bibliotekach chyba, że wybierzemy nazwę już zdefiniowaną w używanej przestrzeni nazw. W obrębie różnych przestrzeni nazw można tworzyć funkcje o takich samych: nazwach deklaracjach ale przeznaczone do zupełnie innych operacji! Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 11 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 12 / 31
Własne przestrzenie nazw Własne przestrzenie nazw tworzyone są za pomocą słowa kluczowego namespace. Przestrzeń nazw HelloWorld zawierającą funkcję hello() można stworzyć w sposób następujący: #include <iostream> namespace HelloWorld{ void hello(){ std::cout << "Hello World!" << std::endl; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 13 / 31
Własne przestrzenie nazw Odwołanie do funkcji hello() przestrzeni HellowWord może wyglądać następująco: int main(){ HelloWorld::hello(); return 0; Oczywiście, umieszczając w kodzie programu instrukcję using namespace HelloWorld przed funkcją main (a nawet wewnątrz tej funkcji), nie ma konieczności odwoływania się bezpośrednio do HelloWorld, wystarczy samo hello(). using namespace HelloWorld; int main(){ hello(); return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 14 / 31
Własne przestrzenie nazw Przestrzeń nazw można budować na raty: namespace Kalkulator{ double suma(double a, double b) {return a + b; double roznica(double a, double b){return a - b; // // inny fragment kodu // namespace Kalkulator{ double iloczyn(double a, double b) {return a * b; double iloraz(double a, double b) {return a / b; Wewnątrz tak utworzonej przestrzeni nazw Kalkulator można znaleźć wszystkie zdefiniowane funkcje. Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 15 / 31
Własne przestrzenie nazw Tworząc funkcję w pewnej przestrzeni nazw możemy podać samą jej deklarację, a potem w innym miejscu pełną definicję. #include <iostream> namespace Kalkulator{ int suma(int a, int b); using namespace std; int main( ){ cout << Kalkulator::suma( 10, 20 ) << endl; return 0; namespace Kalkulator{ int suma(int a, int b) {return a + b; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 16 / 31
Własne przestrzenie nazw Fragment tekstu: namespace Kalkulator { int suma(int a, int b) {return a + b; int roznica(int a, int b) {return a - b; można zastąpić: int Kalkulator::suma(int a, int b){ return a + b; int Kalkulator::roznica(int a, int b){ return a - b; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 17 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 18 / 31
Jeszcze o standartowej przestrzeni nazw Dzięki plikowi nagłówkowemu iostream można operować na standardowym wejściu i wyjściu. Korzystaliśmy już z funkcji cout zrzucającej informacje do standartowego strumienia wyjściowego. Pobieranie informacji ze ze standardowego strumienia wejściowego jest obsługiwane przez inną funkcję przestrzeni std - funkcję cin. int main( ){ int a; // wypisujemy "a:" na wyjście i czekamy na a std::cout << "a = "; std::cin >> a; // wypisujemy kwadrat tej liczb std::cout << "a * a = " << a * a << std::endl; return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 19 / 31
Jeszcze o standartowej przestrzeni nazw Dzięki std::cin >> można nadać wartość dowolnej zmiennej. Zmienna ta nie musi być liczbą, może to być tekst. W c++ bardzo często łańcuch znaków przechowuje się w zmiennej typu string - który także jest częścią std. Aby można było utworzyć taką zmienną trzeba najpierw dołączyć plik nagłówkowy #include <string>. #include <iostream> #include <string> using namespace std; int main(){ string imie cout << "Podaj swoje imie: "; cin >> imie; cout << "Twoje imie to: " << imie << endl; return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 20 / 31
Jeszcze o standartowej przestrzeni nazw Zauważmy, prostotę z jaką się korzysta ze zmiennej typu string. Jest to pewna klasa opracowana na potrzeby języka c++. Jeśli chcemy połączyć dwa napisy, wystarczy wykorzystać przeciążony operator+. #include <iostream> #include <string> using namespace std; int main(){ string imie, nazwisko, osoba; cout << "Podaj swoje imie: "; cin >> imie; cout << "Podaj nazwisko: "; cin >> nazwisko; osoba = imie + " " + nazwisko; // suma napisów cout << "Jestem " << osoba << endl; return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 21 / 31
Jeszcze o standartowej przestrzeni nazw Program wygeneruje następujący strumień wyjściowy: Podaj swoje imie: Jan Podaj nazwisko: Kowalski Jestem Jan Kowalski Można także wykorzystywać operator+= do sklejania tekstów. int main(){ string imie, nazwisko; cout << "Podaj swoje imie: "; cin >> imie; cout << "Podaj nazwisko: "; cin >> nazwisko; nazwisko = nazwisko + " "; nazwisko += imie; // tu tez suma napisów cout << "Jestem " << nazwisko << endl; return 0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 22 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 23 / 31
Korzystanie z bibliotek standardowych c i c++ Jeżeli zastosujemy pewne uproszczenie, to możemy stwierdzić, że język c++ jest rozwinięciem c, W dalszym ciągu można korzystać z biblioteki standardowej c (tzw. libc ). Ze względu na zachowanie wstecznej kompatybilności umożliwiono korzystanie z niej tak jak wcześniej w c. Dlatego w c++ bez trudu można skompilować następujący program. #include <string.h> int main(int argc, char **argv){ if( argc < 2 ) return -1; return strcmp(argv[0], argv[1]); Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 24 / 31
Korzystanie z bibliotek standardowych c i c++ Jednak dostępna jest też wersja libc przygotowana specjalnie dla c++. Pliki nagłówkowe są w niej inaczej nazywane i wszystkie funkcje znajdują się dodatkowo w przestrzeni nazw std. Tak więc program napisany w sposób właściwy dla c++ wyglądałby następująco: #include <cstring> using namespace std; int main(int argc, char **argv){ if( argc < 2 ) return -1; return strcmp(argv[0], argv[1]); Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 25 / 31
Korzystanie z bibliotek standardowych c i c++ Należy zauważyć, że: Dołączany plik nagłówkowy ma dodaną na początku literę c. Nie jest używane rozszerzenie.h. reguła ta dotyczy wszystkich plików, z których składa się biblioteka standardowa c. W swoich programach lepiej jest używać wersji przygotowanej dla c++, a to z trzech powodów: po pierwsze, dzięki przestrzeniom nazw unikniemy kolizji nazw z własnymi funkcjami, po drugie, wersja ta ma wbudowaną obsługę wyjątków. po trzecie, czasami libc przygotowana dla c wywołuje ostrzeżenia lub błędy kompilacji w kompilatorach c++. Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 26 / 31
Spis treści 1 Bardzo prosty program 2 Standartowa przestrzenie nazw 3 Własne przestrzenie nazw 4 Więcej o standartowej przestrzeni nazw 5 Standartowe biblioteki c i c++ 6 Przykładowy program Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 27 / 31
Przykładowy program 1/4 #include <iostream> #include <cmath> using namespace std; namespace p2d{ class punkt{ double x, y; public: punkt(){x = 0.; y = 0.; punkt(double, double); double odlegl(punkt&); ; punkt::punkt(double x0, double y0){ x = x0; y = y0; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 28 / 31
Przykładowy program 2/4 double punkt::odlegl(punkt& koniec){ double dx = koniec.x - x; double dy = koniec.y - y; return sqrt(dx*dx + dy*dy); namespace p3d{ class punkt{ double x, y, z; public: punkt(){x = 0.; y = 0.; z = 0.; punkt(double, double, double); double odlegl(punkt&); ; Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 29 / 31
Przykładowy program 3/4 punkt::punkt(double x0, double y0, double z0){ x = x0; y = y0; z = z0; double punkt::odlegl(punkt& koniec){ double dx = koniec.x - x; double dy = koniec.y - y; double dz = koniec.z - z; return sqrt(dx*dx + dy*dy + dz*dz); Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 30 / 31
Przykładowy program 4/4 int main(){ p2d::punkt p1, p2(1., 1.); p3d::punkt p3, p4(1., 1., 1.); cout << "odleglosc punktow p1 i p2 = " << p1.odlegl(p2) << endl; cout << "odleglosc punktow p3 i p4 = " << p3.odlegl(p4) << endl; return 0; Program ten wygeneruje następujący strumień wyjściowy: odleglosc punktow p1 i p2 = 1.41421 odleglosc punktow p3 i p4 = 1.73205 Mirosław Głowacki (AGH, UJK) Programowanie w języku c++ 2016 31 / 31