Witam wszystkich w moim mega tutorialu dotyczącym programowania w języku Ada!
Po pierwsze chciałbym zaznaczyć że tutorial jest wieloplatformowy i nie dotyka rzeczy specyficznych dla danej platformy systemowej. Aczkolwiek nie gwarantuje że każdy przedstawiony tu kod/porada będzie działać.
Tutorial piszę dla średnio zaawansowanych programistów. Jeżeli będzie to potrzebne mogę go rozszerzyć o pewne komentarze.
1. Dlaczego Ada?
W pierwszym rozdziale wypadałoby powiedzieć dlaczego warto poznać Adę?
Powodów może być kilka:
- pracujesz w wojsku jako programista :P
- musisz pisać niezawodny kod
- potrzebujesz języka który umożliwia łatwe utrzymanie kodu
- piszesz aplikacje rozproszone
- szukasz wygodnego, obiektowego i w pełni kompilowalnego języka
Ogólnie mówiąc Ada jest świetnym wyborem dla programisty solidnego, dbającego o użytkowników etc.
Może te wszystkie zalety nadal cię nie przekonały, ja jednak uważam że jest to świetny język posiadający własną filozofię pisania kodu :)
2. Historia Ady
Jak wszyscy wiemy pierwszym programistą była Augusta Ada King, hrabina Lovelace. Jako hołd pierwszej programistce nazwano na jej cześć język opracowany przez amerykański departament obrony.
3. Cechy języka
- Pierwsze co da się zauważyć to składnia przypominająca wyglądem składnie Fotrana(swoją drogą bardzo przyjemna i miła dla oka :))
- Wartościowanie leniwe
- non-case sensitive(nieczułość na wielkość znaków)
- Cały program to jedna wielka procedura zawierająca podprocedury. W przeciwieństwie do C może się nazywać dowolnie :)
- Brak funkcji w stylu print-format etc. Uniemożliwia to dodatkowe błędy związane z nadmiarem lub niedoborem argumentów
- "Zabezpieczenie" kolejności rzutowania.
4.1 Windows
Ściągamy pakiet portów MinGW.
4.2 Linux
Uruchamiamy instalator pakietów i szukamy gcc-ada(ew. może być zapisane jako GNAT). Aby sprawdzić czy GNAT jest w repozytoriach piszemy:
cnf gnat
4.3 Hello World
Aby sprawdzić czy nasz kompilator działa skompilujmy przykładowy program
with ada.text_io; use ada.text_io; procedure Hello is -- Hello example -- Tutaj deklarować będziemy zmienne begin Put_Line("Hello World!"); end Hello;Aby skompilować powyższy przykład uruchamiamy gnatmake:
gnatmake <nazwa_pliku>
Uruchamiamy:
Linux:
./Hello
Win:
Hello
(Możliwe że pod Windows będzie trzeba coś linkować...)
5. Podstawy składni
Teraz przyszła pora omówić sobie ten nasz hello world.
Pierwsza linijka informuje o korzystaniu z pakietu(tak biblioteki w Adzie są podzielone w pakiety podobne do tych znanych z Javy). Kolejna jest niejako synonimem C++'owego using namespace czy C# using. Chodzi o to by za każdym razem nie musieć pisać Text_IO(istnieje także wygodniejsze i czytelniejsze rename'owanie pakietów ;)). Jak już mówiłem program(czy też pakiet) w Adzie składa się z jednej wielkiej procedury. W tej procedurze deklarujemy zmienne i podprocedury. "Sekcję" kodu właściwego rozpoczyna słowo begin a kończy end z nazwą procedury. Put_Line wypisuje tekst na standardowe wyjście(nie ma przeszkód by tą procedurą "mówić" do drukarki czy innego urządzenia wyjściowego). Warto zauważyć że każde wyrażenie musi być zakończone średnikem. Komentarze występują jedynie w wersji jednolinijkowej(--).
6.Struktury kontrolne
6.1 If-else
if condition then statement; else other statement; end if;6.2 If-elsif-else
if condition then statement; elsif condition then other statement; elsif condition then other statement; ... else another statement; end if;
6.3 case(odpowiednik switch w innych językach)
case X is when 1 => Walk_The_Dog; when 5 => Launch_Nuke; when 8 | 10 => Sell_All_Stock; when others => Self_Destruct; end case;
when others to odpowiednik default w C.
7. Pętle i skoki
7.1 goto
goto Label; Dont_Do_Something; <<Label>> ...
7.2 return
Dla procedur:
return;
Dla funkcji:
return value;
7.3 Pętla nieskończona:
Endless_Loop:
loop Do_Something; end loop Endless_Loop;
7.4 While
While_Loop : while X <= 5 loop X := Calculate_Something; end loop While_Loop;
7.5 Until
Until_Loop : loop X := Calculate_Something; exit Until_Loop when X > 5; end loop Until_Loop;8. Zmienne
W Ada mamy trzy typy zmiennych:
Integer, Float oraz Access.
Pierwsze dwa jak łatwo zauważyć to typy proste(odpowiednio całkowity i zmiennoprzecinkowy). Trzeci typ to wskaźnik. Jednak prawie w ogóle nie przypomina on wskaźnika znanego z C. Bardziej jest to "iterator" dla struktur i tablic.
Podstawy:
C:int i;
int a, b, c;
int j = 0;
int k, l = 1;
Ada:
i : Integer;
Ada:
i : Integer;
a, b, c : Integer;
j : Integer := 0;
k, l : Integer := 1;
Stałe deklarujemy w ten sposób:
lol : constant :=7;
lub z określeniem typu:
lol : constant Integer :=7;
9. Nowe typy:Ada posiada rozległy mechanizm typów zmiennych. Umożliwia on bardzo dokładne manipulowanie stworzonymi przez nas typami. Aby utworzyć nowy typ o nazwie INT piszemy:
type INT is new Integer;Teraz utworzymy sobie zmienną typu INT:
a : INT;
Warto nadmienić iż nowy typ INT to coś zupełnie różnego od typu Integer!
Nie jest możliwe przypisanie zmiennej typu INT do zmiennej typu Integer i na odwrót!
Należy pamiętać również o tym, że nowy typ wymaga również nowych operatorów a więc nie mamy możliwości operowania na nim zbyt wielkiej!
Aby nie utrudniać sobie życia tworzeniem cały czas operatorów powstały podtypy(subtype po angielsku):
10. Podtypy:
Stwórzmy sobie podtyp INT "dziedziczący" z typu Integer:
subtype INT is Integer; a : INT;Teraz spokojnie możemy przypisać do zmiennej typu INT zmienną typu Integer lub na odwrót.
W typach oraz podtypach możemy definiować ich "rozpiętość" czyli zakres z jakiego mogą przyjmować liczby. Np.:
subtype INT is Integer(0,100); teraz stworzyliśmy typ INT o zakresie od 0 do 100.
11. Podprocedury:
Podprogramy, czy też podprocedury, funkcje, procedury etc. są bardzo użytecznym narzędziem.
Stwórzmy funkcję suma która będzie dodawała A i B a wynik zwracała w zmiennej C:
procedure Suma(A,B: in Integer; C: out Integer) is begin C := A + B; end Suma;Jak widać każdą procedurę tworzymy za pomocą keyword'a procedure. Następnie podajemy jej nazwę. Jako parametry przyjmuję zmienne A i B typu Integer. Warto zwrócić uwagę na poprzedzający typ keyword in. Oznacza on, że te dwa parametry będą używane jedynie wewnątrz procedury i ich wartość nie zostanie zmieniona tak jak dzieje się ze zmienną podaną jako C.
12. Procedure Funkcje() is
W Adzie funkcje jako takie praktycznie nie istnieją. Używa się ich jedynie do przeładowania operatorów przy tworzeniu nowego typu.
function "+" (Op1, Op2: in Nowy_typ) return Nowy_typ is begin -- Definicja operatora dodawania end "+";13. Procedure Wywoływanie_procedur() is
Procedury w Adzie możemy wywoływać na 2 sposoby:
-- Sygnatura procedury procedure Write ( Text: String, X, Y: Integer ) -- Wywołanie Write ("Hello", 5, 10); -- lub Write ( Text => "Hello", X => 5, Y => 10 );