Zaczynamy! :) Mam nadzieję, że kompilatory są przygotowane, należna motywacja istnieje, możemy zabierać się do solidnej pracy...
Napisanie pierwszego programu będzie banalnie łatwe. Najpierw ja napiszę pierwszy program, a potem opiszę każde słowo po kolei. Tak więc oto ON:
program moj_pierwszy_program;
BEGIN
END.
Nie jest zbyt długi i zawiły, prawda ? Na początek mała wskazówka: nie radzę pisać programów z użyciem polskich czcionek. Po prostu nasz program na innym komputerze może wtedy wyglądać zupełnie inaczej, niż wygląda u nas a spowodowane jest to niemałymi zawiłościami w systemie DOS.
A teraz omówię go linijka po linijce. Pierwsza linia, choć nieobowiązkowa, jest bardzo wskazana. Składa się ona ze słowa program które oznacza, że wpisywany tekst jest programem, a następnie z nazwy nadanej przez nas temu programowi. To, co wpiszemy jako nazwę, zależne jest tylko od naszej wyobraźni, nie ma bowiem wpływu ani na nazwę pliku na dysku, ani na przebieg programu. Służy to po prostu temu, byśmy my, widząc sam tekst programu, mogli na pierwszy rzut oka zorientować się z czym mniej więcej mamy do czynienia.Otwierając kod żródłowy programu często już na pierwszy rzut oka, po tytule możemy skojarzyć co to za program. Po prostu jest to ułatwienie.
Nazwa nadawana programowi podlega jednak pewnym ograniczeniom. Każda nowa nazwa (zwana od teraz identyfikatorem) może składać się tylko z liter (dużych i małych), znaku podkreślenia (_)oraz cyfr, przy czym pierwszy znak nie może być cyfrą. Prawidłowe są zatem identyfikatory _nazwa, nazwa, NAZWA, NaZwA, _naZwa123. Nieprawidłowe są zaś identyfikatory 1nazwa, 12345, ?dziwny_program?, nazw a. Ten ostatni identyfikator zawiera znak spacji, który także nie może znaleźć się w identyfikatorze.
Po identyfikatorze jak może niektórzy zauważyli, znajduje się średnik. Taka jest zasada pisania programów w Pascalu: po każdej instrukcji stawiany jest znak średnika. Choć mamy też parę wyjątków, których większość poznamy już na początku, to o średniku należy pamiętać. Jego brak to najczęstszy z popełnianych błędów.
Pamiętaj, że tutaj musisz być precyzyjny. Jeżeli jakiś znak jest wymagany, jego pominięcie nie jest po prostu możliwe. Musi tam być i już - nic z tym nie zrobisz, musisz się z tym zgodzić.
Zaznaczyć tu trzeba, że Pascal nie rozróżnia małych i wielkich liter. "PROGRAM" znaczy do niego to samo co "program" bądź "PrOgRaM". Dotyczy to wszelkich kompilatorów opartych na języku Pascal
Całość samego programu mieści się zawsze w "klamrach" dwóch instrukcji: begin i end. Zarówno begin jak i end może występować w Pascalu wiele razy, ale trzeba zapamiętać, że zawsze występuje co najmniej raz. Słowo begin oznacza początek, end - koniec. Nie trzeba nawet elementarnej znajomości języka angielskiego, aby to wiedzieć. Wygodnie jest zaznaczać wielkimi literami te "klamry" obejmujące cały program, by móc szybko znaleźć w programie to begin, które rozpoczyna właściwy program i to end, które je kończy.
Po słowie begin nigdy nie stawiamy średnika. To jest już pierwszy wyjątek odnośnie reguły sprzed paru zdań. Samo begin nie jest bowiem żadną instrukcją, nie niesie za sobą żadnej informacji dla kompilatora co do tego, co program ma wykonać. Mówi tylko o rozpoczęciu pewnego bloku, który kończy się słowem end. Początkowo może się wydawać, że wyjątków jest więcej od reguł, ale to nieprawda.Po słowie end średnik występuje prawie zawsze, za wyjątkiem tego jedynego, ostatniego end w programie, po którym występuje kropka. Można to łatwo zapamiętać tłumacząc to sobie tak, iż to ostatnie end oznacza KONIEC. A jak koniec to koniec.... i kropka! Wyjątek jest jeszcze jeden, ale na razie nie chcę wprowadzić zamętu.
Mamy więc nasz pierwszy program. Co on jednak będzie robił? Program jest na tyle krótki, że można go przepisać i sprawdzić. Jak sprawdzić? W poprzednim dziale była już mowa o tym, jak kompilować i uruchamiać programy.
Co więc zauważyłeś? Nic. Mamy bowiem identyfikator programu, mamy "klamry" w których znajduje się program, a pomiędzy klamrami nie ma nic. Program istnieje, ale nic nie wykonuje. Nie ma w nim żadnych instrukcji.Dodajmy więc jedną linię do programu, który teraz wygląda tak:
Writeln ('Dzien Dobry !');
Spacje przed dodaną linią nie są konieczne, jednak wskazane. Samą koncepcję ich używania przedstawię nieco później. Teraz sprawdźmy co robi program. Kompilacja i uruchomienie...Przypominam, że osoby korzystające z całych środowisk programistycznych być może będą zmuszone do "ręcznego" podejrzenia wyników pracy - jeżeli nie wiesz o co chodzi, zapraszam do działu o kompilatorach i raz jeszcze namawiam do studiowania kursu po kolei, a nie wyrywkowo.
Nasz wspaniały program wypisał na ekranie tekst DZIEŃ DOBRY i to wszystko. Zakończył swój żywot i wrócił do poprzednich zajęć. Coś się więc stało, zmusiliśmy nasze pudło do pewnej reakcji. Czy jest jednak sposób, by zmusić program do tego, by pozwolił nam przed zakończeniem swej pracy dłużej podziwiać wyniki działania? Odpowiedzi można łatwo się domyśleć: sposób taki istnieje. Trzeba jednak użyć pewnej instrukcji, która nie znajduje się w zbiorze komend zrozumiałych dla Pascala od razu.
Musimy do tego celu użyć "magazynu" w którym zgromadzone są różne instrukcje Pascala, których sam kompilator nie rozmumie bez wskazania tegoż magazynu. Magazyn taki zwiemy w środowisku Pascala modułem. Wygląda to tak: podczas pisania programu w Pascalu dostępny mamy cały czas jeden moduł o nazwie System. Tam znajdują się te najważniejsze polecenia (m. in. użyte wcześniej Writeln). Aby jednak "wycisnąć" coś więcej z Pascala, musimy wskazać mu kolejne moduły, w których zapisane są kolejne polecenia. Modułem, który teraz użyjemy będzie moduł o nazwie Crt. Nasz program wygląda więc teraz tak:
uses Crt;
ReadKey;
Dodano w nim dwie linie. Linia druga zawiera dwie części: słowo uses, mówiące kompilatorowi o tym, że teraz podamy listę modułów, które ma dodatkowo (oprócz modułu system) używać oraz samą listę tychże modułów. W naszym wypadku lista ta zawiera tylko jedną nazwę modułu, ale nic nie stoi na przeszkodzie, by było ich tam więcej. Kolejne nazwy odzielone są wtedy od siebie przecinkami, ale na razie będziemy używali tylko Crt.
Kolejną nowością w programie jest linia zawierająca tajemnicze polecenie Readkey; W tym przypadku oznacza to tyle co "czekaj, aż naciśnięty zostanie jakikolwiek klawisz" (ReadKey=CzytajKlawisz). Spróbuj teraz uruchomić program. Na ekranie kolejny raz wypisany zostanie twoje Dzień Dobry a program będzie czekał tak długo aż naciśniesz jakiś klawisz. Dopiero wtedy skończy swoje działanie.
Dobrze, program zrobił się mądrzejszy - użytkownik ma wpływ na jego działanie.Przejdźmy jednak teraz do bardziej szczegółowego przyjrzenia się samemu poleceniu Writeln, które mieliśmy przyjemność użyć. Writeln jest "bliźniakiem" instrukcji Write. Obie instrukcje służą do tego samego - do wypisania na ekranie jakiegokolwiek tekstu. Aby to zrobić, piszemy w tekscie programu Writeln, otwieramy nawias i teraz w apostrofach wpisujemy tekst, jaki ma się pojawić na ekranie. Zamykamy nawias. Stawiamy średnik i to wszystko.
Spróbuj dowolnie modyfikować tekst wenątrz instrukcji Writeln. Pamiętaj jednak, że cały tekst musi być ujęty w nawiasy okrągłe i apostrofy:
Writeln ('Pamiętam o apostrofach i nawiasach');
Czym się jednak różnią instrukcje Write od Writeln ? Spróbuj napisać i skompilować taki program:
Program pisanie;
Write ('Tekst numer jeden');
Write ('Tekst numer dwa');
Write ('Tekst numer trzy');
Writeln ('Tekst numer cztery');
Writeln ('Tekst numer piec');
Writeln ('Tekst numer szesc');
Po tym przykładzie nie ma już chyba żadnych wątpliwości. Instrukcja Writeln to złożenie dwóch angileskich słów: write i line. Pierwsze oznacza "pisz", drugie to "linia", co w tłumaczeniu daje pisz linię. Wyświetlenie tekstu spowoduje więc od razu zejście o jedną linię w dół i ustawienie kursora na początku wiersza. To od tego miejsca wypisywany będzie kolejny tekst. Instrukcja Write natomiast wypisuje dowolny tekst, po czym kursor zostaje w miejscu, gdzie kończy się tekst wyświetlony przez instrukcję. Kolejne pisanie na ekranie zacznie się od tego właśnie punktu. Więcej różnic pomiędzy tymi instrukcjami nie ma.
Po całej pracy nasz program będzie oczekiwał na naciśnięcie dowolnego klawisza a to za sprawą instrukcji (czy bardziej fachowo - procedury) ReadKey.
Nie można pominąc faktu, dosyć oczywistego, acz ważnego, że program zaczyna swe wykonywanie od naszego BEGIN i realizuje kolejne polecenia w kolejności takiej, w jakiej zapisaliśmy je w programie. Możemy więc, zmieniając kolejność instrukcji sprawić, że program na przykład najpierw będzie czekał na nacśnięcie klawisza, a później wypisze teksty, czy też wypisze część tekstów, poczeka na klawisz i wypisze resztę. Od Ciebie zależy, w jakiej kolejności będziesz używał poleceń. Program wykona je według Twojego pomysłu. Ty poznajesz jego słownictwo, jego gramatykę i zaczynasz nim rządzić - jako wierny sługa nie będzie się zastanawiał nad logiką, zrobi wszystko tak, jak Ty sobie to poukładasz.
Pragnę tutaj wspomnieć, że gdybyśmy pominęli linię w której wskazano moduł Crt, program po prostu nie wykonałby się. Pascal bowiem nie "zrozumiałby" samego polecenia ReadKey, gdyż jego definicji nie posiada w module System.
Spróbuj także szanowny czytelniku użyć w programie następującej postaci Write:
Write ('Tekst1 ','Tekst2');
Różnica polega na tym, że w tej procedurze jest już kilka parametrów. Nasza procedura wykona się w następujący sposób: wyświetli Tekst1 następnie spotyka przecinek mówiący jej, że ma do wyświetlenia następny element. Następnym elementem jest Tekst2. Ten tekst zostanie zaraz potem wyświetlony.
ĆWICZENIA
1. Aby w późniejszej pracy z Pascalem nie dziwić się, że "program nie chce działać" przepisz nasz program wyświetlający tekst na ekranie i popróbuj, w jaki sposób Pascal reaguje na różne błędy jak np. brak średnika po instrukcji Write, czy błąd w samej instrukcji (np. Writex zamiast Write), pominięcie deklaracji modułu (uses Crt) czy też brak słowa END.Jeżeli jednak kiedykolwiek będziesz miał problemy z uruchomieniem programu, zapraszam na koniec kursu, gdzie znajdziesz opis błędów mogących się pojawić podczas programowania i krótki opis każdego z nich.
2. Czy pamiętasz jeszcze, jak powinieneś skompilować swój program, jak zapisać go na dysku w postaci pliku wykonywalnego (.exe) ?Efekty swojej pracy możesz przecież chcieć komuś pokazać. Jako ćwiczenie potraktuj napisanie pogramu który wyświetla Twoje imię i nazwisko oraz następnie skompilowanie go i odszukanie na dysku twardym samego programu w wersji *.exe. Jeżeli nie radzisz sobie z tym drugim, zajrzyj jeszcze raz do działu o kompilatorach.
Komputer - maszyna licząca !
Jak zapewne każdemu wiadomo, dzisiejsze komputery mają gigantyczną moc obliczeniową. No cóż, nasz poprzedni program jakoś tego nie ukazywał... W ogóle nic nie liczył... Trzeba to więc teraz zmienić.
Zacznijmy od prostego przykładu:
Program policz;
Write (123*234);
Zastosowałem tu znane już polecenie Write. Ta konkretna postać spowoduje wyświetlenie na ekranie wyniku mnożenia - nie spowoduje wypisania na ekranie samego 123*234. Gdybyśmy jednak zażyczyli sobie wypisania na ekranie samego tekstu, bez obliczania jego wartości, parametr po prostu ujmujemy w apostrofy, co znaczy dla Pascala, że nie ma się niczym przejmować, nic nie musi liczyć, tylko po prostu wypisać tekst.
W porządku, program coś obliczył czyli liczenie nie jest mu obce i zrobił to w miarę szybko, jak na komputer przystało. Tak napisany program ma jednak pewną wielką wadę...Żeby policzyć dowolne wyrażenie (może ono być nawet skomplikowane typu 0.45*4+2*(3003+123) ) musimy je wpisywać do samego programu, kompilować i uruchamiać program. Inny problem - czy jeżeli chcielibyśmy wynik obliczenia używać w programie 100 razy, czy musimy za każdym razem męczyć komputer i żądać od niego wysiłku matematycznego ?
Człowiek by się tyle nie trudził - policzyłby raz i potem używał gotowego wyniku. Ale wynik musi jakoś przechować - bądź to w swojej pamięci, bądź na kartce. A komputer ? Na szczęście wszystko da się zrobić. Komputer wszak ma coś takiego jak pamięć (przynajmniej mój ma...). Ta pamięć jest rzeczą bardzo użyteczną. Możemy sobie w niej przechowywać różne rzeczy. Jak się więc do niej dobrać ?
Otóż po pierwsze - jeżeli chcemy coś umieścić w pamięci, musimy to umieścić w konkretne miejsce, żeby móc następnie do tego błyskawicznie sięgnąć. W Pascalu zwykle możemy bez (większego) problemu dysponować pamięcią o rozmiarze około 200 KB. Wszak jest to mało jak na dzisiejsze możliwości komputerów, ale do reszty też się można dobrać, co wymaga niestety pewnych skomplikowanych zabiegów lub też po prostu dobrych kompilatorów. Tak więc mamy 200 KB pamięci i chcemy w niej umieścić pewną liczbę. Ważne jest także to, iż pamięć ta nie może być już wcześniej zajęta - nie trudno bowiem sobie wyobrazić, jakie skutki miałoby wpisanie do pamięci - używanej przez inny program - swojej wartości - tego typu błędy należą do jednych z najbardziej niebezpiecznych dla stabilności systemu.
Po tym wszystkim co napisałem - sprawa może wydawać się skomplikowana. I taką jest, jednak w zwykłych przypadkach jest to zmartwienie kompilatora a nie programisty. Zadaniem programisty jest tylko poinformować kompilator, że potrzebujemy pamięci, ile jej potrzebujemy i co w niej będziemy przechowywali (np. liczba/tekst itp.). Mówiąc krótko - tworzymy do tego celu zmienną.
Zmienną można porównać do "szufladki", do której możemy coś włożyć a następnie wyjąć (lub tylko "obejrzeć" bez wyjmowania). Informację o tym, że potrzebujemy zmiennej przekazujemy za pomocą słowa var. Po var rozpoczyna się tzw. sekcja deklaracji zmiennych. Sekcji var nie trzeba konczyć. Nie jest potrzebne żadne "end". Sekcja kończy się tam, gdzie zaczyna się następna (np. blok BEGIN..END. )
Ważne jest, żeby zmienne zadeklarować (czyli poinformować kompilator o ich istnieniu) przed sekcją w której je wykorzystamy. Tak więc naszą sekcją programu, w której będziemy potrzebowali dostępu do pamięci będzie główny blok programu pomiędzy BEGIN a END. Musimy więc zmienną zadeklarować wcześniej.
Nazbierało się już trochę teorii, warto teraz poprzeć to praktyką...
1
Program zmienna;
2
3
var liczba : Integer;
4
5
ClrScr;
6
liczba:=1+1;
7
Writeln(liczba);
8
9
10
11
Już śpieszę z wyjaśnieniami.... Po pierwsze - te kolejne liczby z lewej strony programu nie powinny znaleźć się w kodzie źródłowym wpisywanym do kompilatora. Używać ich będę po to, aby łatwiej móc komentować przykładowe programy. Omawiając interesujące fragmenty kodu, będę podawał numery linii, o których piszę.
ClrScr oznacza wyczyszczenie całego ekranu tekstowego i jest procedurą znajdującą się w module Crt
Poza tym mamy tu parę nowości. W linii 3 zadeklarowaliśmy naszą pierwszą zmienną, czyli zarezerwowaliśmy dla niej miejsce w pamięci komputera. Tę linię można przetłumaczyć jako zarezerwuj pamięć (var) zarezerwowane miejsce w pamięci nazwij "liczba" (liczba), zarezerwowane miejsce ma przechowywać wartość typu Integer ( : Integer).
Każdy z tych elementów jest niezbędny. Dosyć tajemnicze jest cały czas określanie typu zapamiętywanej wartości. Chodzi o to, iż komputer rezerwując miejsce, musi wiedzieć ile go zarezerwować. Jeżeli musimy zapamiętać liczbę 1 to wystarczy jeden bajt pamięci, jeżeli musimy zapamiętać imię i nazwisko użytkownika programu - potrzebujemy tego miejsca znacznie więcej (co najmniej z 30 bajtów). Pascal posiada kilka typów zmiennych, które gotowe są do użycia w każdej chwili:
Nazwa
Rodzaj wartości
Rozmiar
Zakres
ShortInt
Liczba całkowita
1 bajt
-128 .. 127
Byte
Liczba naturalna
0..255
Integer
2 bajty
-32768..32767
Word
0..65535
LongInt
4 bajty
-2147483648..2147483647
Real
Liczba rzeczywista
6 bajtów
-1,7E38..1,7E38
string
Tekst
do 256 bajtów
Do 255 znaków ASCII
Char
Znak
Jeden znak ASCII
Single
-3,4E38..3,4E38
Double
8 bajtów
-1,7E308..1,7E308
Extended
10 bajtów
-1,1*E4932..1,1*E4932
Comp
-263+1 .. 263-1
Boolean
Wartość logiczna
FALSE lub TRUE (prawda/fałsz)
Można się przerazić patrząc na taką tabelkę, prawda ? Nie radzę wkuwać tego od razu na pamięć. Można się zrazić szybciej, niż myślisz. Ważne jest tylko, aby kojarzyć nazwy zmiennych z ich rodzajami przechowywanej wartości oraz orientacyjny zakres - to jednak przyjdzie samo z czasem, na razie używaj powyższej tabelki, jeżeli tylko masz jakiekolwiek wątpliwości.
Wytłumaczenia bezwzględnie wymaga od razu pewna rzecz:czym jest znak, i znak ASCII ?Znak to np. 'A', 'B' lub 'n', '-', '=', '?' itd.Znakiem jest również #56, #13, #98
Znak jest to bowiem WARTOŚĆ, która zwykle ma swoją reprezentację graficzną w postaci znaku drukowanego. Każdej wartości przyporządkowany jest jakiś symbol, lub czynność komputera.
Standard ASCII ustala dokładnie, jaki symbol lub jaka akcja komputera przyporządkowana jest jakiej wartości.
Do szerszego omówienia typu znakowego przejdziemy parę akapitów dalej.
Jak wybrać właściwy typ zmiennej? Pisząc program wiemy, co będziemy obliczali i jakiego rzędu mogą to być liczby. Jeżeli istnieje niebezpieczeństwo, iż nasza liczba przekroczy zakres zmiennej, po prostu używamy większej zmiennej. Dlaczego zatem nie używać zawsze największej zmiennej? Byłoby to marnotrawstwem pamięci, nieistotne wprawdzie przy programach takich jak nasz, ale kiedy już potrzebujemy kilkanaście tysięcy zmiennych, istotne jest, czy zmienna ma jeden bajt czy 10...
Wiemy już, jak zarezerwować pamięć dla naszej zmiennej. Jak jednak przesłać do pamięci to, co chcemy zapamiętać? Przykład można zobaczyć w linii 6 naszego poprzedniego programu. Piszemy nazwę zmiennej, następnie operator przypisania := oraz to, co chcemy przypisać do zmiennej. Przypisać możemy zarówno liczbę jak i całe wyrażenie - zostanie ono obliczone i przesłane pod adres pamięci jaki obejmuje zmienna. Przykład przypisania jest w naszym programie zawarty w linii 6. Następuje tam obliczenie wartości 1+1 i zapamiętanie jej w zmiennej liczba.
Tutaj sprawa wydaje się prosta, wyjaśnień mogą jednak wymagać inne typy.
Typ rzeczywisty - pamiętać należy, iż typ rzeczywisty prezentuje liczbę z jakąś ograniczoną dokładnością. Związane jest to ściśle z sposobem przechowywania takiej liczby w pamięci. Typ rzeczywisty posiadający np. 10 bajtów zapamiętuje najbardziej istotną część liczby, która zmieści mu się w tychże dziesięciu bajtach. Jeżeli więc podamy liczbę 1234567890.0987654321 to może się zdarzyć, że cyfr będących na najniższych pozycjach program nie zapamięta, zaokrąglając pamiętaną wartość. Po odczytaniu tej liczby, możemy więc otrzymać liczbę 1234567890.099. Jeżeli natomiast podamy liczbę 1.123456789 to pamięci wystarczy na zapamiętanie jej z pełną dokładnością.Liczby wyjątkowo duże lub o wyjątkowo dużej precyzji mogą więc zatem być zaokrąglane. Istotne jest także, żeby w zapisie liczby rzeczywistej używać kropki a nie przecinka !
Będąc przy typie rzeczywistym, omówić należy od razu sposób wyświetlania tejże zmiennej za pomocą instrukcji Write. Spróbuj napisać program, który wyświetli zmienną typu Real. Jeżeli jesteś leniwym czytelnikiem (co nie wróży Ci dobrze w nauce programowania...) to już mówię jaki będzie efekt.
To jest liczba 12 przechowywana w zmiennej typu rzeczywistego, wyświetlona na ekranie przez naszą instrukcję.
1.20000000000000E+0001
Hmmm.... Użytkownik naszego programu w tym momencie może popukać się w czółko i szybko poszukać możliwości opuszczenia tych dziwnych okolic. Nic dziwnego - gdybym nie napisał, że to jest 12, to trudno by było do tego dojść. Otóż taki zapis oznacza nic innego jak tylko
1.20000000000000 * 101, czyli 12.0000000000000 czyli po prostu 12.
Czy można to jakoś poprawić ? Oczywiście, że można, gdyby było ina...
Grzelu5