Lekcja 2 - Zaczynamy pisać program !
Źródła programów zamieszczonych w tej lekcji

Na tej lekcji poznasz kilka procedur, instrukcję warunkową i jedną pętlę, a pod jej koniec będziesz już potrafił napisać np. prosty program zabezpieczający dalszy dostęp poprzez hasło.


Procedura Write

Służy do wypisania na ekran liczby/tekstu:
Const
 jakas_stala=999;

Var
 jakas_zmienna:Word;

Begin
  jakas_zmienna:=448;
  Write(123);              {1}
  Write('bzdura');         {2}
  Write(4*8);              {3}
  Write('4*8');            {4}
  Write(jakas_stala);      {5}
  Write(jakas_zmienna);    {6}
  Write(jakas_zmienna+12); {7}
  Write(3/4);              {8}
End.
Program wypisze na ekranie liczbę 123 {1}, tekst 'bzdura' {2}, wynik działania matematycznego 32 {3}, tekst '4*8' {4}, stałą o wartości 999 {5}, zmienną do której została wprowadzona liczba 448 {6}, oraz tą samą zmienną powiększoną o 12 czyli 460 {7}.

W tym momencie pojawia się dziwna rzecz, w linii {8} zamiast spodziewanego wyniku 0.75 wyświetla nam program liczbe 7.5000000000E-01 ale jest to nic innego jak liczba przed literką E pomnożona o 10 do potęgi takiej jaka się znajduje po literce E czyli 7.5000000000 * 10 -01 i jest to dokładnie 0.75. Aby wynik wyświetlany był jednak w bardziej czytelnej formie, do której jesteśmy na codzień przyzwyczajeni wystarczy użyć zapisu formatującego wyświetlane dane, a dokładniej to należy dodać dwie cyferki oddzielone od siebie dwukropkami np:
  Write(3/4:8:4);
Znaczy to: wyświetl liczbę ograniczając wyświetlanie do 8 znaków przed kropką i 4 po kropce, dzięki temu otrzymamy łatwo czytelny wynik 0.7500

Procedura WRITE nie wykonuje nic więcej oprócz wypisania wartości z pomiędzy nawiasów dlatego wszystkie te wyświetlane wartości będą znajdowały się jednej linii.

Można również podać wszystkie te parametry naraz, oddzielając je przecinkami:
Const
 jakas_stala=999;

Var
 jakas_zmienna:Word;

Begin
  jakas_zmienna:=448;
  Write(123,'bzdura',4*8,'4*8',jakas_stala,jakas_zmienna,jakas_zmienna+12,3/4:8:2);
End.


Procedura WriteLn

Podobnie jak WRITE, WRITELN wypisuje wartość z pomiędzy nawiasów, ale jeszcze dodatkowo po wypisaniu tej wartości przechodzi do następnej linii.
Begin
  WriteLn(123);            {1}
  WriteLn('bzdura');       {2}
  WriteLn('');             {3}
  WriteLn;                 {4}
  WriteLn(4*8);            {5}

End.
W tym przypadku w KOLEJNYCH LINIACH zostaną wyświetlone wartości: liczba 123 {1} , tekst 'bzdura' {2}, pusty ciąg znaków '' {3} ( czyli niczego nie wyświetli i przejdzie do następnej linii ), kolejną pustą linię {4} ( po prostu procedura jest wykonywana podobnie jak w {3} z pustym łańcuchem znaków ) i wynik działania 32 {5}. Podobnie jak w procedurze Write parametry można podawać oddzielone przecinkami:
Begin
  WriteLn(123,'bzdura','',,4*8);
End.
Zwróć uwagę, że w tym przypadku jak pomineliśmy pusty ciąg znaków i po poprostu wpisaliśmy kolejny przecinek ( podobnie jak w {4} ) kompilator wyrzuci nam błąd. Prawidłowym zapisem natomiast jest:
Begin
  WriteLn(123,'bzdura','','',4*8);
End.


Procedura Read

Pozwala na wprowadzenie do zmiennej wartość podawaną z klawiatury w czasie działania programu:

Var
 zm1:String;
 zm2:Word;

Begin
 Read(zm1);      {1}
 Read(zm2);      {2}
 Read;           {3}
End.
Program czeka na wprowadzenie dwóch
zmiennych, ZM1 typu STRING {1} oraz ZM2 typu WORD {2}, jeżeli natomiast wywołamy tą procedurę bez żadnych parametrów {3} to program czeka w tym momencie na wciśniecie klawisza Enter. W przypadku wprowadzania zmiennych trzeba uważać na kilka rzeczy:
  • Jeżeli program będzie oczekiwał liczby a my podamy mu tekst, to zastanie on zatrzymany i wyświetli błąd
  • Jeżeli czeka np. na liczbę typu WORD, a podamy mu przekraczającą jej typ liczbę 70000, to w zmiennej znajdzie się całkiem inna liczba której się tam niespodziewaliśmy w tym przypadku będzie to 4464 będzie to tzw. przekręcenie licznika :)
  • Jeżeli czeka na typ STRING a podamy liczbę, to uzna tą liczbę za tekst tak więc nie będzie można jej używać np. w działaniach matematycznych. (Wprawdzie jest funkcja przekształcająca liczbę umieszczoną w typie STRING na WORD, INTEGER itd. ale opowiem o niej dopiero później, niemniej istnieje taka i nazywa się VAL).
Procedura READ przyjmuje kolejne zmienne w tej samej linii jedna za drugą.


Procedura ReadLn

Podobnie jak READ procedura ta pozwala na wprowadzenie do zmiennej wartość podawaną z klawiatury w czasie działania programu, z tym, że po przyjęciu wartości program przechodzi do następnej linii:

Var
 imie:String;

Begin
 Write( 'Jak masz na imie ? : ' );       {1}
 ReadLn( imie );                         {2}
 WriteLn;                                {3}
 WriteLn( 'Witaj ' , imie , '!' );       {4}
 Write( 'Wcisnij Enter...' );
 ReadLn;                                 {5}
End.
Programik ten wypisuje tekst {1} i czeka na wprowadzenie zmiennej IMIE {2}, następnie robi linijkę odstępu {3} i wypisuje tekst, zmienną i znowu tekst {4}. Na sam koniec czeka dodatkowo na wciśniecie klawisza Enter {5}.

Procedura GotoXY

Składnia: GotoXY(x,y:byte); [CRT]

Procedura ta pozwala na umieszczenie kursora (miejsca, od którego np. będą wyświetlane wartości przez Write), w dowolnym miejscu ekranu, procedura ta znajduje się w bibliotece CRT:

Uses CRT;

Begin
  GotoXY(20,10);
  Write('Ten tekst rozpoczyna się w 20 kolumnie i 10 wersie');
End.
W tym programie procedura GotoXY nakazuje przenieść kursor do 20 wiersza i 10 kolumny i wyświetlić tekst.


Procedura Halt

Przerywa ona natychmiast wykonywanie programu i powraca do DOS-a


Procedura ClrScr

Składnia: ClrScr; [CRT]

Usuwa wszystkie znaki z ekranu tekstowego (czyści go) i ustawia kursor w pozycji 0,0 (lewy górny róg ekranu)


Procedura Sound

Składnia: Sound(CZE:word); [CRT]

Włącza dźwięk o częstotliwości CZE ( liczba typu word ) emitowany przez głośnik komputera. Z własnych praktyk zauważyłem że dźwięk o częstotliwości 3160 jest "trochę" denerwujący :)


Procedura NoSound

Składnia: NoSound; [CRT]

Wyłącza dźwięk emitowany przez głośnik komputera, włączony uprzednio przez SOUND.


Procedura Delay

Składnia: Delay(CZAS:word); [CRT]

Wstrzymuje program na określoną (zmienna CZAS) ilość milisekund (1000 milisekund=sekunda), przydatne np. przy procedurze Sound

Uses CRT;

Begin
  Sound(2000);
  Delay(1000);
  NoSound;
End.


Instrukcja Warunkowa IF ... THEN ... [ELSE ...]

Instrukcja ta sprawdza czy jest spełniony warunek postawiony po "IF", jeżeli tak to wykonywana jest instrukcja po słowie "THEN". Można jeszcze po THEN "coś tam", użyć słowa ELSE oznaczającego "w przeciwnym wypadku", umieszczona po ELSE instrukcja zostanie wykonana dopiero wtedy, gry warunek postawiony po "IF" NIE ZOSTAŁ SPEŁNIONY np:

Var
 ttt:Byte;

Begin
  Write('Podaj liczbę z zakresu 0..255 : ');
  ReadLn(ttt);
  IF ttt=40 THEN WriteLn('Podałeś liczbę 40');                                                                          {1}
  IF ttt>100 THEN WriteLn('Podałeś liczbę większą niż 100') ELSE WriteLn('Podałeś liczbę równą lub mniejszą od 100');   {2}
End.
Ograniczę się w opisie programu tylko do rzeczy nowych, a więc:
{1} Instrukcja IF sprawdza czy wpisana liczba to 40, jeżeli tak to wypisuje tekst, jeżeli nie, to omija instrukcję znajdującą się po THEN i przechodzi do następnej linii. Zwróć uwagę na to że przy porównywaniu używa się znaku "=" a przy przypisywaniu znaku ":=".
{2} Instrukcja IF sprawdza czy wpisana liczba jest większa od 100 jeżeli tak to wykonuje instrukcję po THEN i wypisuje tekst, jeżeli nie znaczy to, że liczba jest mniejsza lub RÓWNA 100! i wtedy pomija instrukcję po THEN ale widzi że jest jeszcze instrukcja ELSE i wykonuje wtedy to, co po niej się znajduje. Gdyby liczba była większa niż 100, nie wykonałby nic co znajdowałoby się po instrukcji ELSE !
Specjalnie używam tu tyle razy słowa "instrukcja" po to abyś zapamiętał, że po instrukcjach, które nie kończą fragmentu programu NIE STAWIA SIĘ ŚREDNIKA ! Program ten można zapisać również w takiej postaci abyś widział że faktycznie po IF, THEN, oraz ELSE nie ma tych nieszczęsnych średników. (Rany ale zamotałem :-)
Var
 ttt:Byte;

Begin
  Write('Podaj liczbę z zakresu 0..255 : ');
  ReadLn(ttt);
  IF ttt=40 THEN                                                  {1}
    WriteLn('Podałeś liczbę 40');                                 {1}
  IF ttt>100 THEN                                                 {2}
    WriteLn('Podałeś liczbę większą niż 100') ELSE                {2}
      WriteLn('Podałeś liczbę równą lub mniejszą od 100');        {2}
End.

Instrukcja Grupująca Begin End

Instrukcję grupującą rozpoczyna słowo kluczowe BEGIN, a kończy ją END. Wszystkie instrukcje umieszczone pomiędzy tymi słowami będą traktowane jako jedna. Jest to przydatne np. przy poznanej przez chwilą instrukcji warunkowej IF THEN ELSE np.

Uses CRT;

Var
 strona:byte;

Begin
  Write('1-strona tytulowa  0-koniec : ');
  ReadLn(strona);
  IF strona=1 THEN
  Begin
    ClrScr;
    WriteLn('Program przykładowy w języku Turbo Pascal');
    WriteLn('Autor: Robert Wróbel  (GiGi)');
    WriteLn('Napisany Dnia 20.09.97')
  End;
End.
Jak widzisz po wpisaniu cyfry "1" zostanie wyczyszczony ekran i pojawią się trzy linijki tekstu więc wykona cztery instrukcje zamiast jednej, gdyby nie było BEGIN END to program by wyglądał tak:
Uses CRT;

Var
 strona:byte;

Begin
  Write('1-strona tytulowa  0-koniec : ');
  ReadLn(strona);
  IF strona=1 THEN ClrScr;
  IF strona=1 THEN WriteLn('Program przykładowy w języku Turbo Pascal');
  IF strona=1 THEN WriteLn('Autor: Robert Wróbel  (GiGi)');
  IF strona=1 THEN WriteLn('Napisany Dnia 20.09.97')
End.
Jak widać, teraz jest "trochę" bardziej naśmiecone, a co jeśli ma wykonać 50..100.. linijek ? Aż mi się włos jeży na głowie jak pomyślę :-)


Pętla REPEAT ... UNTIL ...

Jest to również w pewnym sensie instrukcja grupująca i jest traktowana jak jedna instrukcja (podobnie jak Begin...End). Pętla zaczyna się słowem kluczowym REPEAT dalej znajdują się linie do wykonania a zakończona jest słowem UNTIL i warunkiem, który jeżeli zostanie spełniony przerywa pętlę i kontynuuje program, jeżeli nie, powraca na początek (po REPEAT) i wykonuje instrukcje pomiędzy nimi po raz kolejny i znowu dochodzi do UNTIL, znowu sprawdza warunek itd. jest to pętla która zostanie CO NAJMNIEJ RAZ WYKONANA, gdyż warunek znajduje się dopiero na końcu (jest też pętla WHILE .. DO .. w której warunek zostaje sprawdzany na początku) Przykład:

Uses CRT;

Var
 licz:byte;

Begin
 ClrScr;
 REPEAT
   Write('Wpisz jakąś liczbę (0-wyjscie) : ');
   ReadLn(licz);
   WriteLn('Potega liczby ',licz,' to ',licz*licz);
   WriteLn;
 UNTIL licz=0;
End.
Program tak długo podaje potęgi kwadratowe wpisanych liczb póki nie podamy mu cyfry 0, oczywiście te końcowe "0" również spotęguje gdyż dopiero sprawdzi warunek na końcu pętli. Ciekawą rzeczą którą można zrobić to pętla nieskończona, sam zobacz dlaczego :)
Begin
  REPEAT
  UNTIL 1=2;
End.


Podsumowujący Lekcję Program

Już właściwie możesz sam napisać ten obiecany program na hasło i to na bardzo wiele sposobów, jeżeli czujesz się na siłach, to spróbuj go zrobić nie korzystając na razie z następnego podrozdziału jeżeli nawet się nie uda, to na pewno czegoś w tym eksperymentowaniu się nauczysz, a jeżeli uda ci się go wykonać to naprawdę gratuluję ! stałeś się programistą, napisałeś swój pierwszy program korzystając z własnych możliwości ! Nawet jeżeli nie jesteś pewien swojej wiedzy to naprawdę zachęcam: SPRÓBUJ ZANIM POWIESZ ŻE NIE UMIESZ !

I na koniec tej lekcji jedno z praw Murphiego: "Przekleństwa są jedynym językiem doskonale znanym przez programistów z całego świata", jeżeli nie wiesz o co chodzi to sam się niedługo przekonasz ;-)


Tego programu nie będę opisywał powinieneś sam już wiedzieć co do czego służy.
Uses CRT;

Const
 haslo='Pascal';

Var
 wprowadz:String;
 petla:byte;

Begin
  REPEAT
    ClrScr;
    GotoXY(31,12);
    Write('Podaj haslo : ');
    ReadLn(wprowadz);
    IF petla=4 THEN
    REPEAT
      ClrScr;
      GotoXY(31,12);
      Write('Access Denied !');
      Sound(3160);
      Delay(500);
      Sound(3190);
      Delay(500);
    UNTIL 1=2;
    petla:=petla+1;
  UNTIL wprowadz=haslo;
  { Haslo poprawne, dalsza część programu }
End.


Powrot na Strone Glowna