Języki programowania
Transkrypt
Języki programowania
Języki programowania Nowoczesne techniki programowania Wykład 1 Witold Dyrka [email protected] 5/10/2011 Prawa autorskie Slajdy do wykładu powstały w oparciu o slajdy Bjarne Stroustrupa do kursu Foundations of Engineering II (C++) prowadzonego w Texas A&M University http://www.stroustrup.com/Programming Program wykładów 1. Pierwszy program. Obiekty, typy i wartości 2. Wykonywanie obliczeń. Błędy 3. Pisanie i wykańczanie programu 4. Techniki pisania funkcji i klas 5. Strumienie wejścia/wyjścia 6. Wskaźniki i tablice 7. Systematyka technik i języków programowania Program laboratorium ● Pisanie algorytmów ● Język C++ Materiały Literatura ● Bjarne Stroustrup. Programowanie: Teoria i praktyka z wykorzystaniem C++. Helion (2010) ● Jerzy Grębosz. Symfonia C++ standard. Edition 2000 (2008) ● Dowolny podręcznik języka C++ w standardzie ISO 98 Środowisko programistyczne ● Microsoft Visual C++ (rekomendowane) ● Dowolne środowisko korzystające z GCC Warunki zaliczenia ● ● Projekt programistyczny (50%) ● po trzecim wykładzie (2.XI.2011 r.) ● termin oddania (4.I.2012 r.) Kolokwium (50%) ● ● środa, 18.01.2011 r. Na zaliczenie >50% pkt. Zasady ● Nie toleruję plagiatów ● ● Nie toleruję ściągania ● ● dot. projektów i programów na laboratorium dot. kolokwium i sprawdzianów na laboratorium Zachęcam do korzystania z konsultacji ● ze mną: PT 10-11, pok. 118A/D-1 ● pomiędzy sobą Dlaczego programowanie? Programowanie w medycynie Na przykład: ● Tomografia oprogramowanie skanera, przesyłanie sygnałów, przetwarzanie obrazu ● Chirurgia wspomagana robotami wizualizacja, precyzyjne sterowanie narzędziami, sterowanie na odległość ● Inne: automatyczne badania (np. krwii), urządzenia ultradźwiękowe, komputery kieszonkowe i tzw. mobile health care ● ● Natychmiastowy dostęp do danych pacjenta Projekty medyczne realizowane przez znajomą, niewielką firmę informatyczną z Wrocławia: ● obsługa magazynu lekarstw i apteki szpitala ● optymalizacja produkcji granulatu w dużej firmie farmaceutycznej Czym jest programowanie? ● Powiedzeniem bardzo szybkiemu kolesiowi co ma dokładnie robić ● Planem rozwiązywania problemu przez komputer ● Określeniem kolejności wykonywanych działań ● Z tym, że: ● ● współczesne programy zawierają miliony linii kodu ● i koncentrują się na manipulacji danymi Może więc: Określeniem struktury i zachowania programu oraz sprawdzeniem czy wykonuje on zadanie prawidłowo i dostatecznie sprawnie Czy programowanie jest trudne? ● Zasadniczo jest łatwe: ● ● Napisz maszynie co ma robić Dlaczego jest więc trudne? ;-) ● ● ● ● Chcemy by komputer robił złożone rzeczy, a on jest tylko maszyną Rzeczywistość jest bardziej skomplikowana niż nam się wydaje, a my nie zawsze zdajemy sobie sprawę z implikacji tego czego chcemy „Programowanie jest rozumieniem”, tego co chcemy zautomatyzować Programowanie łączy teorię i praktykę Pierwszy program #include <iostream> // dołącza plik nagłówkowy biblioteki przydatnych // narzędzi int main() { // main() jest początkiem każdego programu C++ std::cout << "Hello, world!\n"; return 0; // wyświetla 13 znaków: Hello, world! // i przechodzi do nowej linii // zwraca wartość oznaczającą sukces } // Cudzysłów typu " " ogranicza literał łańcuchowy // \n oznacza początek nowej linii // Średnik ; kończy każdą instrukcję // Nawiasy klamrowe { … } grupują instrukcje w blok // main() jest funkcją, która nie pobiera argumentów i zwraca wartość całkowitą (int) oznaczającą sukces (0) lub błąd (!0) Pierwszy program (2) /* Pierwszy program - cele – poznanie: kompilatora, środowiska deweloperskiego (IDE) środowiska uruchomieniowego – sprawdzenie reakcji na błędy zapomniany nagłówek, zapomniany cudzysłów kończący łańcuch znakowy pomyłka w nazwie (np. retrun) zapomniany średnik lub nawias klamrowy */ #include <iostream> int main() { cout << "Hello, world!\n"; system(“pause”); return 0; } // dołącza plik nagłówkowy biblioteki narzędzi // main() jest początkiem każdego programu C++ // wyświetla 13 znaków: Hello, world! // i przechodzi do nowej linii // czeka na wciśnięcie klawisza // zwraca wartość oznaczającą sukces Liczy się styl ● ● ● Większa część kodu to jakby gotowy formularz Jedyna instrukcja, która „coś” robi to: cout << "Hello, world!\n" I taki podział jest zupełnie normalny:-) ● ● bez komentarzy, dołączania bibliotek itp. kod nie będzie prosty, zrozumiały, godny zaufania i efektywny Nie wystarczy by jakoś działało ● kod musi być elegancki i poprawny Kompilacja i konsolidacja Kod źródłowy C++ hello_world.cpp Kompilator C++ Program wykonywalny hello_world.exe ● ● Konsolidator (ang. linker) Kod obiektowy hello_world.obj Kod obiektowy biblioteki iostream.obj Kompilator - sprawdza kod napisany w języku programowania - generuje kod obiektowy, specyficzny dla architektury komputera i systemu operacyjnego Konsolidator dołącza kod obiektowy wykorzystywanych bibliotek i porządkuje przestrzeń programu Obiekty, typy i wartości Programowanie polega przede wszystkim na manipulowaniu danymi. Teraz zajmiemy się: ● wprowadzeniem i wyświetlaniem danych ● zmiennymi przechowującymi dane ● pojęciem typu i bezpieczeństwa typu Wprowadzanie i wyświetlanie /* Program wczytujący imię i witający się z użytkownikiem */ #include <iostream> #include <string> int main() { std::cout << "Prosze podac swoje imie (i nacisnac" << " 'enter'):\n"; string imie; // Ta instrukcja to deklaracja zmiennej (imie) // Zmienna posiada określony typ (string) std::cin >> imie; std::cout << "Czesc, " << imie << '\n'; } // Kilka wartości może zostać wyświetlonych w jednej instrukcji // Pominięto return 0; jest ono opcjonalne w main() Wczytywanie zmiennych ● Typ zmiennej określa co można z nią zrobić ● W naszym przypadku: std::cin >> imie; wczytuje znaki ze standardowego wejścia (np. klawiatury), aż do znaku białego (ang. whitespace) ● Znak biały to np. spacja, tabulator, znak nowej linii Wprowadzenie łańcuchów /* Program wczytujący imię i nazwisko oraz witający się z użytkownikiem */ #include <iostream> #include <string> int main() { std::cout << "Prosze podac swoje imie i nazwisko:\n"; string pierwszy; string drugi; std::cin >> pierwszy >> drugi; // wczytuje dwa łańcuchy znakowe string nazwisko = pierwszy + ' ' + drugi; // deklaracja oraz inicja(liza)cja // zmiennej nazwisko std::cout << "Czesc, " << nazwisko << '\n'; } // Dla typu string, operator + oznacza konkatenację, czyli sklejanie łańcuchów. Wprowadzenie liczb całkowitych /* Program wczytujący imię i wiek oraz witający się z użytkownikiem */ #include <iostream> #include <string> int main() { std::cout << "Prosze podac swoje imie i wiek:\n"; string imie; int wiek; // Zmienna całkowita jest typem wbudowanym, // więc nie potrzebuje dołączania nagłówka std::cin >> imie >> wiek; std::cout << "Czesc, " << imie << ', masz ' << wiek <<lat'\n'; } Liczby zmiennoprzecinkowe // Proste działania arytmetyczne #include <iostream> #include <cmath> int main() { std::cout << "Podaj liczbę zmiennoprzecinkową: "; double n; // zmienna zmiennoprzecinkowa typu double std::cin >> n; std::cout << "n = " << n << "\nn+1 = " << n+1 // '\n' oznacza nową linię << "\ntrzy razy n = " << 3*n << "\ndwa n = " << n+n << "\nn kwadrat = " << n*n << "\npolowa z n = " << n/2 << "\npierwiastek kwadratowy z n = " << sqrt(n) // funkcja biblioteczna << std::endl; // to też oznacza nową linię } Typy i literały ● Typy wbudowane ● ● ● bool – logiczny (Boolowski) char – znakowy int – całkowitoliczbowy – ● ● ● ● Literały znakowe: 'a', 'x', '4', '\n', '$' ● Literały całkowitoliczbowe 0, 1, 123, -6, 0x34, 0xa3 ● float Typy biblioteki standardowej ● Literały logiczne: true false short, long, signed, unsigned double – zmiennoprzecinkowy – ● string – łańcuch znakowy complex<Scalar> – liczby zespolone Literały zmiennoprzecinkowe 1.2, 13.345, .3, -0.54, 1.2e3, . 3F, .3F ● Literały łańcuchowe "asdf", "Howdy, all y'all!“ ● Literały zespolone complex<double>(12.3,99) complex<float>(1.3F) ● Typy użytkownika Deklaracja i inicjacja zmiennej int a = 7; int b = 9; a: 7 b: 9 char c = 'a'; c: 'a' double x = 1.2; x: 1.2 string s1 = "Hello, world"; s1: 12 s2: 3 | "Hello, world" string s2 = "1.2"; | "1.2" Obiekty Obiekt jest fragmentem pamięci, który przechowuje wartość pewnego typu Zmienna jest nazwanym obiektem == deklaracja nazywa obiekt int a = 7; char c = 'x'; complex<double> z(1.0,2.0); string s = "qwerty"; s: 6 a: c: z: 7 'x' 1.0 2.0 "qwerty" Bezpieczeństwo typów Zasada bezpieczeństwa typów: ● Każdy obiekt będzie użyty tylko zgodnie z jego typem ● ● ● Zmienna będzie użyto dopiero po inicjacji Tylko operacje zdefiniowane dla zadeklarowanego typu zmiennej będą użyte Każda operacja zdefiniowana dla zmiennej nadaje jej prawidłową wartość Ideał statycznej kontroli typów ● Program naruszający bezpieczeństwo typów nie zostanie skompilowany ● Kompilator zgłasza każde naruszenie Ideał dynamicznej kontroli typów ● Jeśli program narusza bezpieczeństwo typów, zostanie to wykryte w czasie uruchomienia ● Istnieje kod, który wykrywa każde naruszenie nie znalezione przez kompilator Bezpieczeństwo typów w C++ C++ nie zapewnia (pełnej) statycznej kontroli typów ● Żaden powszechnie używany język nie jest w pełni bezpieczny ● Pełna statyczna kontrola typów mogłaby za bardzo ograniczać programistę C++ nie zapewnia (pełnej) dynamicznej kontroli typów ● Istnieją inne języki, które ją zapewniają ● Pełna dynamiczna kontrola typów mogłaby za bardzo ograniczać programistę ● Pełna dynamiczna kontrola typów często generuje większy i wolniejszy kod Będziemy uczyć się technik zapewniających bezpieczeństwo typów. Naruszenie bezpieczeństwa typów niejawne zawężanie (ang. implicit narrowing) // Uwaga: C++ nie zabrania próby umieszczenia dużej wartości // w małej zmiennej (chociaż kompilator może ostrzec przed tym). int main() { int a = 20000; a: char c = a; int b = c; if (a != b) // != oznacza relację nierówności cout << "ups!: " << a << "!=" << b << '\n'; else cout << "Świetnie! Mamy duże znaki\n"; } 20000 c: Spróbuj, jaka będzie wartość b na Twoim komputerze ??? Naruszenie bezpieczeństwa typów (niezainicjowana zmienna) // Uwaga: C++ pozwala użyć niezainicjowanej zmiennej. // Jednak kompilator przeważnie ostrzega przed tym. int main() { int x; char c; double d; // x otrzymuje “losową” wartość początkową // c otrzymuje“losową” wartość początkową // d otrzymuje “losową” wartość początkową // – nie każda zawartość komórki pamięci stanowi poprawną // wartość zmiennoprzecinkową double dd = d; // potencjalny błąd: niektóre implementacje // nie kopiują niepoprawnych wartości zmiennoprzecinkowych cout << " x: " << x << " c: " << c << " d: " << d << '\n'; } Zawsze inicjuj swoje zmienne. Wyjątek: zmienne, których wartości są wprowadzane z zewnątrz. Uwaga: tryb debugowania może inicjować zmienne Ideały programistyczne ● Bezpieczeństwo typów ● Szybkość wykonywania ● Dostosowanie do danej platformy sprzętowej i systemowej ● Możliwość uruchomienia na wielu platformach oraz otrzymanie tych samych wyników ● Zgodność z innym kodem lub systemem ● Łatwość konstrukcji ● Łatwość utrzymania Jako inżynierowie jesteśmy zawsze skazani na kompromisy. Ideały programistyczne ● Bezpieczeństwo typów ● Szybkość wykonywania ● Dostosowanie do danej platformy sprzętowej i systemowej ● Możliwość uruchomienia na wielu platformach oraz otrzymanie tych samych wyników ● Zgodność z innym kodem lub systemem ● Łatwość konstrukcji ● Łatwość utrzymania Jako inżynierowie jesteśmy zawsze skazani na kompromisy. Poprawne nazwy w C++ ● rozpoczynają się zawsze literą ● mogą zawierać litery, cyfry i podkreślenia ● np. poprawne nazwy to: x, liczba_elementow, Fouriera_transformata, z2 ● niepoprawne są natomiast: 12x, czas$do$konca, glowna linia ● ● Nie należy rozpoczynać nazw podkreślnikiem, np. _foo, – składnia zarezerwowana dla kompilatora Nie może definiować nazw, używanych jako słowa kluczowe języka, np. int, if, while, double Dobre nazwy w C++ DOBRE: ● Nazwy znaczące w danym kontekście: ● ● suma_czesciowa, licznik_elementow, eksport_pszenicy Krótkie nazwy używane konwencjonalnie: ● x – jako zmienna lokalna, ● i – jako indeks pętli. ZŁE: ● Skróty i skrótowce są mylące ● Za długie nazwy → program nieczytelny, łatwo o literówkę: ● suma_wszystkich_elementow, pozostale_wolne_miejsca_w_tablicy_symboli Jeszcze jeden pomysł na program... // Konwersja cali na cm i centymetrów na cale: #include <iostream> int main() { const double cm_na_cal = 2.54; int wartosc; char jednostka; while (std::cin >> wartosc >> jednostka) { // wczytuje w pętli if (jednostka == '\"') // znak cala jest znakiem specjalnym w C++ std::cout << wartosc << "\" == " << wartosc*cm_na_cal << "cm\n"; else if (jednostka == 'c') // 'c' jak w cm std::cout << wartosc << "cm == " << wartosc/cm_na_cal << "\"\n"; else return 0; // kończy jeśli podana “zła” jednostka, np. 'q' } } Dziś najważniejsze było to, że... ● Warto, aby inżynier biomedyczny nauczył się dobrze programować ● W programowaniu liczy się styl ● Możemy korzystać ze zmiennych różnych typów ● Zmienna to nazwany obiekt ● Każdy obiekt należy używać tylko zgodnie z jego typem A za 2 tygodnie... ● Wykonywanie obliczeń ● Radzenie sobie z błędami