D/Podstawy
Podstawy
edytujNasz pierwszy program i jego modyfikacje z poprzedniego rozdziału nie robiły zbyt skomplikowanych czynności - jedynie wyświetlały wcześniej zadany tekst. To oczywiście dopiero początek tego, co potrafi D.
W tym rozdziale opiszemy czym dokładnie jest język D, jak działa, co potrafi i jakiego typu programy można w nim pisać. W ogólności będzie to również wstęp o tym co inne języki potrafią.
Języki programowania
edytujKomputery wbrew pozorom są maszynami bardzo prostymi, i choć może się wydawać iż potrafią dużo nawet skomplikowany rzeczy, nie jest to do końca prawdą. W swej prostocie komputery potrafią robić jedynie bardzo elementarne czynności, takie jak dodanie lub odjęcie dwóch liczb, przemieszczenie jednej komórki pamięci do innej, czy skok w inne miejsce programu (z ewentualnym warunkiem kiedy skok wykonać, a kiedy nie). Już te 3 elementarne operacje wystarczą do zbudowania w pełni sprawnego komputera i całej współczesnej informatyki! Zapytasz zapewne: "Jak to? Przecież komputery potrafią operować na tekście, obrazie, dźwiękach, komunikować się przez sieć i wiele innych." Okazuje się, iż wszystkie te o wiele bardziej skomplikowane problemy można wyrazić w ostatecznym rozrachunku jako proste elementarne operacje. W wielu przypadkach tych elementarnych operacji będzie bardzo dużo, jednak komputery są bardzo szybkie i potrafią robić bezbłędnie miliardy takich operacji na sekundę. Program jest zbiorem kolejnych takich instrukcji wykonywanych przez komputer i operujących na danych które też są liczbami. Odstępstwa od liniowego wykonywania programu nazywamy skokami (czasami wywołaniami, ponieważ czasami potrzebujemy wrócić do miejsca z którego wykonaliśmy skok).
No dobrze - zapytasz - ale zapewne musi być bardzo trudno napisać programy tylko używając tych elementarnych operacji. Tak, bardzo trudno. Język w którym używa się tych elementarnych operacji nazywa się językiem asembler, i droga z kodu zapisanego w w tym języku do postaci jeszcze bardziej zrozumiałej przez komputer (kod maszynowy) jest praktycznie natychmiastowa. Tego typu języków używało się w dawnych czasach kiedy nie istniały jeszcze języki wysokiego poziomu (takie jak C czy D). Również dzisiaj się używa asemblerów, kiedy nie możemy użyć innego języka (np. pisząc fragmenty jądra systemu operacyjnego) albo są ku temu inne powody (np. język asembler pozwala programiście o dostatecznej wiedzy stworzyć kod który będzie dużo szybszy niż napisany w innych językach). Mimo swej prostoty asemblery są trudne w użytkowaniu, i dlatego używa się języków wysokiego poziomu. W tych językach można definiować nowe operacje (funkcje) oraz inne niż liczby reprezentacje danych (typy,struktury) i ich używać w bardziej abstrakcyjnym sensie. Natomiast program zwany kompilatorem przetłumaczy ten kod do asemblera, i wygeneruj kod maszynowy dla procesora.
Dalsze wytłumaczenie podstaw programowania opiszemy na języku D, ponieważ to on jest tematem tego podręcznika. :)
Język D
edytujJęzyk D należy do rodziny obiektowo zorientowanych języków imperatywnych.
Imperatywność oznacza, iż to programista decyduje co w jakiej kolejności wykonać. Jest to naturalny opis większości algorytmów i przepisów, w których trzeba wykonać coś krok po kroku. Istnieją również innego typu języki (zwane deklaratywnymi) w których nie podaje się kolejności wykonywania kroków, lecz raczej same kroki i zbiory reguł które są dozwolone i jako zagadkę dla kompilatora i komputera pozostawiamy znalezienie rozwiązania. Okazuje się że wiele problemów i algorytmów łatwiej zapisać w drugi sposób (np. rozwiązywanie łamigłówek czy elementy sztucznej inteligencji).
Obiekty są konstrukcjami w języku które umożliwiają na zamknięcie w jednym kawałku programu powiązanych cech i używanie ich jako całość. Dyskusje o obiektach zostawimy na następne rozdziały, jednak podamy tu mały przykład. Obiektem może być na przykład samochód. Dobrze jest traktować samochód jako jeden pojedynczy obiekt, a nie zbiór takich obiektów jak karoseria, cztery koła, silnik, system kierowania i pasażerowie. Oczywiście samochód może te elementy zawierać w sobie (jako pod obiekty), lecz używając samochodu (na obiektach można wykonywać różne operacje) nie chcemy sterować bezpośrednio silnikiem czy każdym kołem osobno, raczej chcemy po prostu sterować samochodem bez znajomości jego wewnętrznej budowy. Czasami również chcemy mieć wiele różnych samochodów których tak samo się używa, albo pewną abstrakcję kierowania pojazdu nie zależnie czy używamy samochodu, roweru czy ciężarówki. Zapewne chcielibyśmy te obiekty też umieścić w garażu. Kiedy mówimy o językach obiektowych właśnie mamy namyśli tego typu obiekty. W późniejszych przekonamy się że ta koncepcja ułatwia pisanie i rozbudowywanie programów.
Struktura blokowa
edytujW języku D można grupować zbiór instrukcji w bloki przy pomocy nawiasów klamrowych i traktować ten zbiór instrukcji jako jedna duża instrukcja. W naszym pierwszym przykładzie użyliśmy już struktury blokowej. Treść funkcji main była umieszczona właśnie w takim bloku, co umożliwiło nam w pojedynczej funkcji wykonanie kilku rzeczy (wyświetlenia kilku napisów).
Struktura blokowa jest wykorzystywana w języku D bardzo często. Jest tak ponieważ większość konstrukcji języka wymaga pojedyńczej instrukcji, natomiast struktura blokowa pozwala połączyć wiele instrukcji w jedną.
Kontrola wykonywania i pętle
edytujWielokrotnie będziemy chcieli wykonać jakąś instrukcje (lub blok) jedynie pod pewnym warunkiem. Na przykład kiedy wczytamy pewną liczbę z klawiatury, będziemy chcieli sprawdzić czy jest to liczba większa od zera. W zależności od tego jaki jest wynik takiego testu, chcemy albo kontynuować program (i na przykład obliczyć pierwiastek kwadratowy), albo alternatywnie zgłosić błąd użytkownikowi. Język D umożliwia na sprawdzanie warunków (przy pomocy instrukcji if, else oraz switch) i wykonywanie alternatywnych fragmentów kodu.
Ponieważ komputery są dobre w wykonywaniu identycznych czynności na dużych ilościach danych (np. wyświetlić piksel po pikselu duży obrazek), czy powtarzaniu podobnych czynności o nieznacznie zmienionych warunkach (np. wyświetlić kolejne liczby naturalne od 1 do 1000), chcielibyśmy mieć możliwość napisania elementarnej operacji którą chcemy wykonać i nakazaniu wykonania jej zadaną (być może nieznanej podczas pisania programu) ilość razy. Język D umożliwia to przy pomocy pętli (instrukcję for, while, do, foreach).
Wielokrotnie będziemy również chcieli wykonać bardzo podobną czynność w kilku miejscach programu. Dobrze jest wtedy tą instrukcję napisać raz jako funkcję i odwoływać się przez jej nazwę. Przykładem może być funkcja rozwiązania równania kwadratowego. Jeśli w naszym programie z jakichś względów musimy w 5 różnych miejscach rozwiązać równania kwadratowe o różnych współczynnikach, wygodnie jest napisać funkcję przyjmującą jako argumenty te współczynniki a zwracającą rozwiązania. Ma to wiele zalet, po pierwsze oszczędzamy pisania, po drugie kod jest krótszy i bardziej przejrzysty, po trzecie być może kiedyś ktoś wymyśli lepszy sposób rozwiązywania naszego równania i będziemy musieli jedynie zmodyfikować jedna funkcje, a jej wywołania pozostaną bez zmian.
Zmienne
edytujSame instrukcje wykonywania tych samych czynności nie są jeszcze wystarczające aby stworzyć użyteczny program. Będziemy potrzebować zmiennych, a następnie wykonywać operacje na nich. Język D dostarcza zmiennych różnych rodzajów (typów): liczby naturalne i rzeczywiste, zespolone, litery oraz napisy. Możemy również tworzyć zmienne nowych typów złożone z typów podstawowych, takie jak tablice czy obiekty zawierające zmienne różnych typów.
Obiekty
edytujD udostępnia też możliwość tworzenia wysokopoziomowych struktur i przypisanych do nich operacji, dzięki czemu poziom abstrakcji języka znacznie zbliża się do naszego świata. Możemy dysponować obiektem Szkoła i wygodnie na nim operować mimo że składa się z m.in. stopnia, numeru, nazwy, klas itd. Koniec końców programowanie staje się znacznie wygodniejsze, ponieważ programista patrząc w kod widzi spreparowany wycinek rzeczywistości.
Co w takim razie potrafi D?
edytujPrzedstawione powyżej elementy programowania (instrukcję, insturkcję warunkowe, pętle, funkcje i zmienne) są podstawą każdego języka imperatywnego, i mogą posłużyć do tworzenia bardzo zaawansowanych programów. Używając tylko tych elementów można tworzyć programy matematyczne, obliczeniowe, symulacje komputerowe, gry komputerowe, sieciowe, serwery, edytory tekstów, programy analizujące dane, sortujące i wiele wiele innych.
Język D został zaprojektowany, aby był wygodny w wielu ogólnych zastosowaniach i w większości wypadków tak jest. Istnieją jednak przypadki kiedy lepiej użyć wyspecjalizowanych języków programowania do konkretnego zadania (na przykład jeśli chcemy operować nie na konkretnych danych, a raczej symbolach, albo nie znamy dobrego algorytmu do jakiegoś problemu i łatwiej będzie nam użyć języka deklaratywnego). Nie żeby nie dało się tych samych rzeczy wykonać w D. Po prostu istnieją języki w których pewne czynności mogą być wykonane prościej. Nie ma języków idealnych, D jedynie zbliża się do takiego języka.