Tomasz Bajorek
Podstawy programowania
w języku Turbo Pascal
Środowisko zintegrowanego pakietu programowania języka
TURBO PASCAL (7.0).
Wstęp.
Historia praktycznego wykorzystania języków programowania ma kilkadziesiąt lat, choć podstawy teoretyczne algorytmicznego sterowania automatami cyfrowymi są znacznie starsze. Do połowy lat 50-tych panował język maszynowy (komputery Eniac, Mark I). Kodowanie instrukcji procesora odbywa się w postaci ciągu liczb dwójkowych (elementarny rozkaz i dane), co jest bardzo pracochłonne (same liczby, długie algorytmy działań takich jak dodawanie i mnożenie) i powoduje trudność śledzenia błędów. W latach 50-tych zastąpiono kody operacji nazwami mnemotechnicznymi elementarnych operacji (np. mnożenie MPY (multiply), taki język symboliczny zwany jest assemblerem. Assembler to także program tłumaczący na kod maszynowy (wewnętrzny), program dissassembler przeprowadza tłumaczenie odwrotne. Stosowany jest do dziś - np. w oprogramowaniu interfejsów pomiarowych, wprowadzaniu danych z pomiarów, ich obróbka komputerowym przetwarzaniu itp. Cechami assemblera są: zmniejszona ale nadal duża pracochłonność tworzenia algorytmów, możliwość błędów (prawie każda kombinacja znaków można być wykonana), ukierunkowanie na konkretny komputer (procesor) dla którego program był pisany, wąski zbiór rozkazów (prymitywna architektura ówczesnych komputerów, brak rejestrów, brak operacji zmiennoprzecinkowych).
Pod koniec lat 50-tych zapanował etap tzw. języków wysokiego poziomu (kod maszynowy i assembler to niski poziom - bliższy procesorowi). Zapis operacji wykonywanych przez program jest tu łatwiejszy dla programisty, zrozumiały i dobrze kontrolowany. Po stworzeniu kodu źródłowego programu w języku wysokiego poziomu następuje proces tłumaczenia na język wewnętrzny komputera: w całości (kompilacja) i dopiero jego wykonanie, lub też dla niektórych języków (np. Basic, LOGO) kod źródłowy jest tłumaczony w czasie wykonania instrukcja po instrukcji (interpretacja).
Języki wysokiego poziomu po etapie początkowym stały się maszynowo niezależne z powodu wielu wersji kompilatorów (programów kompilujących).
W kolejnych latach nastąpiła obfitość języków programowania. Najważniejsze to:
COBOL - dla przedsiębiorstw, język prawie naturalny *(np. instrukcje MULTIPLY - mnożenie, ADD - dodawanie),
FORTRAN, PASCAL - języki ukierunkowane na obliczenia naukowe,
BASIC, LOGO - prostota, interpretacja w odróżnieniu od kompilacji, tłumaczenie „na bieżąco” każdej instrukcji a nie programu w całości,
PASCAL, C, C+- języki strukturalne (modułowa struktura programów),
OOP (Object Oriented Programming) - języki zorientowane obiektowo (PROLOG, Visual Basic, C++, Delphi -Object Pascal, Java)
Klasyfikacja języków programowania:
do przetwarzania danych: COBOL, dBase
do obliczeń naukowych : Fortran, Pascal,
do programowania systemowego - tworzenie systemów operacyjnych: C, BCPL, BLISS,
opisu zleceń - DOS, MVS,
konwersacyjne: LISP, zmiany z terminala w trakcie konwersacji
symulacyjne - symulacja procesów (najczęściej w czasie rzeczywistym): mechanika, elektronika, termodynamika itp. - SIMULA, CSSL
algorytmiczne (większość): programowanie to zapis sposobu wykonania zadania przy pomocy kolejno wykonywanych instrukcji,
niealgorytmiczne: nie jak ale co ma być zrobione - sterowanie nie algorytmem lecz danymi
obiektowe - nazwane zbiory danych - obiekty; są aktywne i mają swoje własności statyczne (pola) i dynamiczne (metody); poprzez zdarzenia (zwykle wymuszone przez użytkownika) można te własności zmieniać lub wywoływać akcje obliczeniowe przez aktywizację metod,
specjalizowane - ukierunkowane na pewną klasę problemów, np. obróbkę baz danych, analizę układów elektronicznych itp.
Świat rzeczywisty lub abstrakcyjny reprezentowany jest przez dane, na których wykonywane są operacje. Aby opisać dane i operacje potrzebne są ustalone umowy, tworzące tzw. język formalny - zbiór słów nad określonym alfabetem.
Język programowania - zbiór konwencji i umów umożliwiających komunikatywność zapisu i ich zrozumiałość dla kompilatora.
Określa się przy tym:
syntaktykę (składnię) języka - zbiór reguł opisujących poprawne konstrukcje językowe
semantykę - zasady interpretacji tych konstrukcji
Błędy składniowe - np. pominięcie słowa kluczowego instrukcji lub jego przekręcenie,
Błędy semantyczne - np. zły typ danych, licznik pętli nie jest typu całkowitego itp.
Jeżeli spełnione są warunki, iż:
- syntaktyka pozwala na analizę poprawności konstrukcji językowych,
- opis języka obejmuje pragmatykę (zalecenia do używania poprawnych struktur)
to język formalny może być językiem programowania.
Definicja algorytmu:
ALGORYTM - skończony zbiór ściśle określonych zasad rozwiązywania pewnej klasy zadań, przepis - specyfikacja ciągu operacji, które w wyniku działania na wejściowy zbiór obiektów dają zbiór wynikowy.
Opis algorytmu składa się z:
- opisu obiektów podlegających przetwarzaniu,
- opisu czynności wykonywanych na tych obiektach.
deklaracje, definicje - są to opisy obiektów używanych w programie,
instrukcje - czynności na obiektach,
program - algorytm zapisany w języku programowania,
podprogram - wyodrębniona część programu (ze względu na zwiększenie czytelności lub umożliwienie jego wielokrotnego użycia), posiadająca wyodrębnioną nazwę i sposób wymiany informacji z pozostałymi jego częściami,
deklaracja podprogramu - opis podprogramu,
instrukcja wywołania podprogramu - wykonanie, zastosowanie podprogramu wewnątrz programu głównego lub innego podprogramu
Język PASCAL (autor Nicklaus Wirth, lata 70-te) posiada następujące cechy:
Język wysokiego poziomu - stosowanie składni syntaktycznej języka bez znajomości struktury wewnętrznej komputera,
Mechanizmy kontroli struktur i reguł gramatycznych - identyfikacja i poprawa błędów,
Język algorytmiczny - zapis koncepcji i zadań opracowanych przez programistę,
Język strukturalny - fragmenty algorytmu zapisywane są w odrębnych strukturach językowych,
Język modularny - składanie programu z modułów,
Sposoby pisania programu:
Rys.1. Etapy programowania.
program źródłowy utworzony dowolnym edytorem tekstu, następnie kompilacja, ewentualnie konsolidacja (linkowanie - łączenie z podprogramami bibliotecznymi - modułami), wykonanie,
korzystanie z ze zintegrowanych pakietów programistycznych (wewnętrzne narzędzia edycji, kompilacji i konsolidacji, weryfikacji błędów itp.)
Uruchamianie pakietu Turbo Pascal. Podstawowe operacje.
Aktywizacja środowiska programistycznego polega na wykonaniu plików:
turbo [plik.pas] - wersja trybu rzeczywistego DOS
tpx [plik.pas] - wersja trybu chronionego DOS
W systemie Windows dla wygody użytkownika zalecane jest utworzenie skrótu do pliku turbo.exe (np. na pulpicie), ustawiając we właściwościach skrótu opcję „zamykaj przy zakończeniu”, zaś we właściwościach zaawansowanych zaznaczając „Sugeruj tryb MS-DOS jeśli wymagany”.
Rys.2. Okno edytora środowiska Turbo Pascala.
Środowisko języka zgłasza się oknem edytora kodu źródłowego (jak na rys.2). Poniższa tabela przedstawia podstawowe operacje klawiszowe i wyjaśnia pojęcia używane w drop-down menu.
Operacja |
Sposób wykonania - opis |
Dostęp do menu |
ALT+wyróżniona litera nagłówka menu |
Wybór okna edycyjnego |
ALT+nr okna |
Przełączanie: edytor ⇔ OUTPUT⇔ edytor |
ALT+F5 |
Otwarcie pliku |
F3 |
Zapis pliku |
F2 |
Kompilacja |
ALT+ F9 (F9) |
Wykonanie |
CRTL+F9 |
Step over |
F8 - krokowe wykonywanie programu głównego |
Trace into |
F7 - jak wyżej lecz dodatkowo krokowe wykonanie podprogramów |
Watch |
ALT+F7 lub menu Debug-Watch-Add watch - śledzenie wartości wyszczególnionych zmiennych |
Breakpoints |
menu Debug-Add breakpoint - „pułapki” - miejsca chwilowego zatrzymania programu w celu sprawdzenia wartości zmiennych na danym etapie |
Pomoc |
F1 - pomoc ogólna, CTRL+F1 - pomoc kontekstowa |
Oprócz okna edytora (możliwe jest otwarcie wielu okien edycyjnych) najważniejszy jest ekran OUTPUT przedstawiający wyniki wykonania programu - aktywizowany kombinacją klawiszy ALT+F5 w postaci pełnoekranowej lub przez menu Debug - Output w postaci okienkowej.
Błędy
W przypadku wystąpienia błędu proces kompilacji zatrzymuje się i wskazywane jest miejsce wystąpienia błędu z angielskim, skrótowym opisem.
Najczęstsze błędy:
Opis angielski |
Opis |
unknown identifier |
nieznany identyfikator |
syntax error |
zła składnia |
type mismatch |
niezgodność typów |
error in expression |
błąd w wyrażeniu |
unexpected end of file |
nieoczekiwany koniec pliku |
”;” expected |
”;” oczekiwany |
”)” expected |
”)” oczekiwany |
”DO” expected |
oczekiwane słowo kluczowe ”DO” |
Błędy wykonania polegają zazwyczaj na:
niewłaściwym użyciu poprawnych instrukcji,
przekroczeniu zakresów zmiennych (kontrola przez opcję menu Options - Compiler...- Runtime errors - Range checking)
braku możliwości wykonania operacji systemowych,
niewłaściwej operacji matematycznej np. dzielenie przez 0, logarytm z liczby ujemnej itp.
Kombinacja CTRL+Break umożliwia przerwanie „zawieszonego” programu.
Edytor Turbo Pascala
Standardowo pliki pisane w języku Turbo Pascal mają rozszerzenie pas.
Operacje edytorskie mogą się odbywać przez aktywizację pozycji menu, użycie klawiszy nawigacyjnych lub naciśnięcie CTRL+znak (lub CTRL+znak1(Q lub K) a następnie znak2).
Podstawowe operacje edycyjne przedstawia poniższa tabela:
Operacja |
Klawisze |
przesunięcie kursora o znak lub wiersz |
strzałki nawigacyjne |
przewinięcie tekstu o stronę |
PgUp, PgDn |
skok kursora na początek, koniec wiersza |
Home, End |
skok na początek, koniec okna |
CTRL+Home, CTRL+End |
skok na początek, koniec tekstu |
CTRL+PgUp, CTRL+PgDn |
zmiana trybu: wstawianiezastępowanie |
Insert |
wstawienie pustego wiersza |
CTRL+N ENTER w trybie wstawiania |
usunięcie znaku |
Delete lub Backspace |
usunięcie słowa |
CTRL+T |
usunięcie wiersza |
CTRL+Y |
usunięcie reszty wiersza |
CTRL+Q,Y |
zaznaczenie małego bloku |
SHIFT+klawisze nawigacyjne |
zaznaczenie początku bloku |
CTRL+K,B |
zaznaczenie końca bloku |
CTRL+K,K |
zaznaczenie słowa jako bloku |
CTRL+K,T |
ukrycie bloku |
CTRL+K,H |
kopiowanie bloku w miejsce kursora |
CTRL+K,C |
przesunięcie bloku w miejsce kursora |
CTRL+K,V |
usuwanie bloku |
CTRL+K,Y |
wcięcie (indent) bloku |
CTRL+K,I |
cofanie wcięcia bloku |
CTRL+K,U |
zapis bloku do pliku |
CTRL+K,W |
wczytanie bloku z pliku |
CTRL+K,R |
szukanie ciągu znaków(find) |
CRTL+Q,F |
szukanie i zastąpienie(replace) |
CTRL+Q,A |
kontynuacja szukania lub zastępowania |
CTRL+L |
Ćwiczenie
1. Uruchomić środowisko języka Turbo Pascal.
2. Napisać w edytorze środowiska tekst przykładowego, prostego programu:
program test;
begin
writeln(` To jest mój program testowy')
end.
3. Przetestować operacje edycyjne: nawigację po tekście, zaznaczanie słowa, wiersza, kilku wierszy, kasowanie i dopisywanie (w trybie zastępowania i wstawiania), kopiowanie i przenoszenie tekstu z zaznaczaniem bloku, wyszukiwanie ciągu znaków. Zaznaczyć blok tekstu (3 kompletne wiersze) i wykonać jego wcięcie i ponowne wysunięcie. Korzystać ze skrótów klawiszowych zamieszczonych w tabeli.
4. Wykonać operację menu: File - DOS Shell. W trybie DOS utworzyć nowy folder PROGRAMY na dysku roboczym. Wrócić do edytora wpisując polecenie exit. Plik źródłowy zapisać w utworzonym folderze prze operację menu File - Save lub skrót F2 nadając plikowi własną nazwę. Zaobserwować zmianę nazwy w szyldzie okna.
5. Otworzyć nowe okno operacją File - New. Przełączać okna operacją ALT+nr_okna. Rozmieszczać okna na ekranie korzystając z myszki lub (jeśli jest niedostępna) przez operacje menu Window - Size, korzystając z podpowiedzi w pasku stanu. Zapisać plik z okna drugiego na dyskietce.
6. Skopiować tekst programu z okna 1 do okna 2 korzystając z menu Edit (Cut, Copy, Paste). Uaktywnić okno schowka przez operację menu Edit - Show Clipboard.
7. Wykonać kompilację programu (F9). Zaobserwować błędy. Jeśli ich nie będzie wprowadzać celowo błędne postaci słowa kluczowego program, nazwy podprogramu writeln, brak średnika po linii tytułowej, brak kropki na końcu programu itp.. Za każdy razem obserwować komunikaty o błędach.
8. W menu Compile wybrać pozycję Destination memory - spowoduje to zmianę na Destination disk, co oznacza, że odtąd po skompilowaniu programu źródłowego powstanie na dysku plik wykonywalny z rozszerzeniem exe. Sprawdzić w menu Options -Directories... jaki jest docelowy folder dla plików wykonywalnych. Przeprowadzić kompilację programu przykładowego, uruchomić DOS-Shell i znaleźć plik wykonywalny.
9. Wykonać program (CTRL+F9). Przełączyć się na okno OUTPUT (ALT+F5), obejrzeć ekran wyników programu. Powrócić do edytora (ALT+F5). Wykonać ponownie program. Otworzyć okno OUTPUT w postaci okienkowej (menu Debug - Output). Obejrzeć wynik. Wprowadzić modyfikację tekstu w instrukcji writeln wewnątrz apostrofów. Ponownie wykonać program i obejrzeć rezultaty.
SKŁADOWE JĘZYKA. DEKLARACJE.
INSTRUKCJA PRZYPISANIA.
Struktura blokowa programu i podprogramów
Rys.3. Struktura programu źródłowego w jeśyku Turbo Pascal.
Instrukcje wykonywane są kolejno od pierwszej do ostatniej, pod warunkiem, że charakter instrukcji nie stanowi inaczej (np. „pętle”, skoki, przekazanie wykonania do podprogramu itp.)
Nagłówek programu jest opcjonalny- (czyli nieobowiązkowy) i składa się z:
- słowa kluczowego program i identyfikatora (nazwy) o długości do 255 znaków
- opcjonalnych parametrów programu w nawiasie - -nazw plików wejścia i wyjścia (standardowo INPUT oraz OUTPUT)
W sekcji deklaracji opisujemy elementy używane przez program. Istotna jest kolejność deklaracji, np. wcześniej powinna wystąpić deklaracja typu a potem zmiennej tego typu.
W sekcji instrukcji występują kolejne akcje jakie ma wykonać program.
UWAGA:
BEGIN END to początek i koniec sekcji instrukcji,
kropka kończy tekst programu źródłowego, teksty po kropce są ignorowane,
INSTRUKCJE są oddzielane średnikami.
Alfabet języka
Na alfabet języka składają się:
- duże i małe litery alfabetu łacińskiego (rozróżnialne tylko dla stałych tekstowych)
- cyfry 0 do 9
- jednoznakowe symbole specjalne:
+ - * / = < > [ ] .
, : ; ( ) { } ^ # $ @
- dwuznakowe symbole specjalne:
< > < = > = := . .
Podstawowe słowa kluczowe to:
AND |
DOWNTO |
IF |
PROCEDURE |
TYPE |
ARRAY |
ELSE |
IN |
PROGRAM |
UNTIL |
BEGIN |
END |
LABEL |
RECORD |
USES |
CASE |
FILE |
MOD |
REPEAT |
VAR |
CONST |
FOR |
NOT |
SET |
WHILE |
DIV |
FUNCTION |
OF |
THEN |
WITH |
DO |
GOTO |
OR |
TO |
|
Identyfikatory (nazwy)
Identyfikatory własne nadaje użytkownik dla programu, obiektów (zmiennych), typów, podprogramów, modułów. Identyfikatory to nazwy złożone z ciągu znaków.
Identyfikatory standardowe (zastrzeżone):
typów danych - boolean, char, integer, real, string i inne
stałych - false, true, maxint
funkcji - abs, sin, cos, sqr, sqrt, exp i inne
procedur - read, readln, reset, rewrite, write, writeln i inne,
plików - input, output.
Dla większości identyfikatorów standardowych ich użycie jako własnych jest dopuszczalne lecz powoduje przedefiniowanie ich pierwotnego znaczenia.
Zasady tworzenia identyfikatorów (nazw) własnych:
Ciąg znaków (liter, cyfr, znaku podkreślenia _ )
Nie wolno używać spacji wewnątrz nazwy
Pierwszym znakiem musi być litera
Długość identyfikatora do 255 znaków
Nierozróżnialne małe i duże litery
Przykłady:
A, C5, XY20, cyfra, e22, delta, dzienD, IDENT1, ident1
To_jest_dlugi_identyfikator_lecz_poprawny
Uwaga1: IDENT1 i ident1 są traktowane jako ten sam obiekt.
Uwaga2: Można przedefiniować identyfikatory standardowe lecz wtedy tracą one swoje znaczenie i nabierają nowego, nadanego przez użytkownika, np. możemy wprowadzić zmienną o nazwie sin lecz wówczas tracimy możliwość używania funkcji sin.
Komentarz
Komentarz (własne uwagi lub opis działań) ma postać dowolnego ciągu znaków w nawiasach klamrowych:
{ dowolny fragment programu }
UWAGA: Można dezaktywować niektóre instrukcje na etapie testowania programu zamykając je w nawiasach klamrowych. Przydatne jest i do dobrego tonu należy umieszczanie komentarzy lecz nadmiar powoduje zmniejszenie przejrzystości.
Separatory
Separator nagłówka programu, deklaracji i instrukcji to średnik „;”
Separatory symboli języka to:
spacja (lub ciąg spacji), ENTER, komentarz
z tym że:
dwa dowolne słowa kluczowe, identyfikatory lub liczby bez znaku muszą być oddzielone co najmniej jednym separatorem,
ciąg spacji jest równoważny jednej spacji,
po instrukcjach, po których występuje słowo kluczowe END średnik nie jest wymagany.
Stałe (literały)
Stałe liczbowe
A. całkowite
Stałą liczbową całkowitą jest ciąg cyfr bez spacji (ew. poprzedzony znakiem + lub -)
Przykłady: -1 23234 012 0 -1234
$F12A - liczba w zapisie szesnastkowym
Zakres : -32768 do 32767 dla typu integer
-2.15 mld do 2.15 mld (dla typu Longint)
B. rzeczywiste
Stałą liczbową rzeczywistą zapisujemy w dwóch formatach:
Zapis stałopozycyjny
[{±}]m.n gdzie m i n to liczby całkowite, dodatnie
Uwaga: w nawiasach klamrowych { } -elementy do wyboru, w nawiasach kwadratowych [ ] - elementy opcjonalne (mogą zostać pominięte).
UWAGA: kropka rozdziela część całkowitą i ułamkową
Przykłady: 2.333 -456.0
NIE WOLNO: .45 brak części całkowitej
WOLNO: 234. brak 0 po kropce dziesiętnej
Zapis zmiennopozycyjny (wykładniczy)
[-]m[.n]
[-]k
gdzie m,n,k całkowite dodatnie
Litera E (lub e) interpretuje pomnożenie liczby dziesiętnej m.n przez 10 do potęgi k.
Notacja wykładnicza przydatna dla liczb bardzo dużych i bardzo małych.
Przykłady:
0.1 -4.5 34.678 -1.5e-12 3.4E7 {tzn. 3.4.107=34000000}
UWAGA: Zakresy dla różnych podtypów są różne !!!!
B. liczby w układzie szesnastkowym
Stałą w układzie szesnastkowym poprzedzamy znakiem $.
Przykłady: $5 %FFF $1A12
Stałe łańcuchowe
Stałą łańcuchową (tekstową) jest ciąg znaków ograniczonych apostrofami.
Przykłady: 'Turbo Pascal' 'a'
Stałe logiczne
Wartości logiczne nadawane zmiennym i wyrażeniom typu logicznego boolean to:
True - prawda False - fałsz
Deklaracje i definicje
Deklaracja modułów.
Moduły są to biblioteki procedur i funkcji, które (po zadeklarowaniu modułu) można wykorzystać w programie.
uses lista_nazw_modułów ;
np. uses graph;
uses crt,printer;
Definicje stałych (nazw literałów) i ich wartości.
Stałe są nazwanymi obiektami o wartości niezmiennej w trakcie wykonywania programu.
const nazwa1=wartość1; nazwa2=wartość2 ; ....;
np. const e=2.71828;
prawda = true;
nazwisko = 'Kowalski';
Definicja typu
Definicja typu jest nazwanym opisem typu (najczęściej niestandardowego), używanym potem w deklaracjach zmiennych.
type nazwa_typu1 = opis_typu1 ; nazwa_typu2 = opis_typu2 ; .....;
np. type
dni_tyg = (po,wt,sr,cz,pi,so,ni); {typ wyliczeniowy}
ck = 1..20; {typ okrojony}
napis = string[30]; {typ łańcuchowy o długości max. 30 znaków}
Typ wyliczeniowy i okrojony poznamy dokładnie później.
W przypadku stosowania jedynie typów standardowych blok type nie jest potrzebny.
Deklaracje zmiennych.
Deklaracje wprowadzonych przez użytkownika zmiennych umieszczamy w bloku poprzedzonym słowem kluczowym var, w następującej, ogólnej postaci:
var lista nazw zmiennych: nazwa_typu1;
lista nazw zmiennych: nazwa_typu2;
....;
Przykładowe deklaracje:
var
x, suma, v15: integer;
wynik1: real;
znak: char;
czy_jest: boolean;
nazwisko, imie: napis; {typ wcześniej opisany}
var alfa : dni_tyg; { typ wcześniej opisany }
x , y , z : ck; { typ wcześniej opisany}
Można również stosować opisy typów w deklaracji zmiennych, na przykład:
var
liczby : 1..23;
dni : (pon, wto, sro, czw, pia, sob, nie);
Niemniej jednak w niektórych sytuacjach, jak na przykład przy zastosowaniu funkcji i procedur oraz stosowaniu plików elementowych, konieczne będzie wprowadzenie nazw dla typów opisywanych przez użytkownika.
Klasyfikacja typów danych
Każda stała, zmienna, wyrażenie lub funkcja jest pewnego typu - pozwala to uniezależnić się w pewnym stopniu od fizycznej reprezentacji obiektów w pamięci operacyjneja, umożliwia kontrolę dozwolonych wartości dla danego typu.
Typ określa:
Zbiór wartości, do którego należy stała, bądź jakie może przyjmować zmienna czy wyrażenie, lub jakie mogą być generowane przez funkcję,
Zbiór operacji jakie mogą być wykonywane przez funkcję.
Typy oferowane przez język Turbo Pascal:
standardowe typy proste - integer, real, word, byte, boolean, char i inne,
standardowy typ strukturalny - string,
niestandardowe typy proste - okrojony, wyliczeniowy,
niestandardowe typy strukturalne: tablicowy, zbiorowy, rekordowy, plikowy.
Typ standardowy to zbiór wartości i operacje zdefiniowane w języku, z których użytkownik może korzystać bez ich definiowania.
Typy strukturalne (złożone) - wprowadzone w związku z praktycznymi potrzebami reprezentacji danych.
W sekcji instrukcji wolno używać tylko identyfikatorów standardowych i takich, których znaczenie określono w sekcji deklaracji.
Rys. 4. Klasyfikacja typów danych.
Typy proste (porządkowe i rzeczywiste)
Typy porządkowe
A.Typy całkowite
Podstawowy typ całkowity to typ integer. Używamy go w deklaracji zmiennych w przykładowej postaci:
var x, y: integer;
Zakres typu integer zależy od implementacji - dla IBM PC stała Maxint określa maksymalną wartość dla tego typu i jest równa 215-1 = 32767
Inne typy całkowite:
shortint |
-128 do 127 |
word |
0 do 65535 |
byte |
0 do 255 |
longint |
-2.15 mld do 2.15 mld |
B. Typ znakowy - char
Zmienne tego typu mogą przyjmować wartości pojedynczego znaku.
Przykład:
var znak:char;
begin
znak:='c'; {operacja przypisania - nadania wartości}
.....
end.
C. Typ logiczny - boolean
Zmienne tego typu mogą przyjmować wartości stałych logicznych true lub false.
D. Typ wyliczeniowy
Typ wyliczeniowy jest typem prostym, porządkowym stanowiącym skończony, uporządkowany zbiór wartości oznaczonych nazwami (identyfikatorami), wybranymi przez użytkownika :
(lista wartości)
Można zastosować opis typu bezpośrednio przy deklaracji zmiennych:
var
forma: (prostokat, kwadrat, elipsa, okrag);
dzien: (po, wt, sr, cz, pi, so, ni);
lub wcześniej opisać typ
type
figura=(prostokat, kwadrat, elipsa, okrag);
dni = (po, wt, sr, cz, pi, so, ni);
var
forma : figura;
dzien : dni;
Dopuszcza się wykonywanie na obiektach typu wyliczeniowego operacji przypisania, np.:
forma := elipsa;
dzien := po;
porównania (porządek według wyliczenia) np.:
po < wt
elipsa > kwadrat
a także użycia funkcji standardowych dla typów porządkowych, np.:
pred(wt) po {poprzedni element}
ord(wt) 1 {licznik kolejności - liczony od 0}
Dla obiektów tego typu nie wolno stosować operacji arytmetycznych oraz wykorzystywać zmiennych tego typu w instrukcjach wprowadzania i wyprowadzania danych (read/write).
E. Typ okrojony
Typ okrojony wyznacza podzbiór dowolnego typu porządkowego (boolean, char, integer, wyliczeniowy) zwanego typem bazowym:
w1 .. w2
gdzie w1 w2
np. var
dzien : (po, wt, sr, cz, pi, so, ni); {zmienna bazowego typu wyliczeniowego}
zakres: 1..10; {podzbiór typu integer}
cyfra: '0'..'9'; {podzbiór typu char}
dni_wolne: so .. ni;
Operacje i funkcje obowiązują jak dla typu bazowego.
Typy rzeczywiste
Typy rzeczywiste używane są dla zmiennych przyjmujących wartość liczbową rzeczywistą. Podstawowym typem jest tu typ real.
Tabela typów rzeczywistych:
Nazwa typu |
Najmniejsza wartość dodatnia |
Największa wartość |
real |
2.9e-39 |
1.7e38 |
single |
1.5e-45 |
3.4e38 |
double |
5.0e-324 |
1.7e308 |
extended |
3.4e-4932 |
1.1e4932 |
UWAGA 1: opcje pakietu dopuszczają brak sprawdzania zakresów w trakcie wykonania programu, w menu Options - Compiler - Runtime errors - Range checking można uaktywnić sprawdzanie zakresów.
UWAGA 2: PAMIĘĆ: Char - 1 bajt, Integer - 2 bajty, Real - 6 bajtów inne więcej.
Typ łańcuchowy - string
Typ łańcuchowy zmiennej umożliwia przechowywanie wartości typu tekstowego (do 255 znaków)
string - do 255 znaków
string[20] - deklaracja max. długości
Przykład:
....
var nazwisko: String[20];
begin
nazwisko:='Kowalski'; {przypisanie wartości tekstowej do zmiennej}
writeln(nazwisko:15); {wydruk na ekranie w polu o szerokości 15 z wyrównaniem do prawej}
....
end.
Instrukcja przypisania
Instrukcja przypisania jest podstawową, prostą instrukcją w większości języków programowania. Przy jej pomocy zmiennym nadawane są wartości w trakcie wykonywania programu.
identyfikator zmiennej := wyrażenie;
: = dwuznakowy operator przypisania
Najprostsza postać wyrażenia to stała lub zmienna:
W → stała
W → zmienna
W instrukcji przypisania zmiennej o identyfikatorze z lewej strony znaku przypisania nadawana jest wartość obliczonego wyrażenia obecnego po prawej stronie operatora.
UWAGA: zachodzi konieczność zachowania zgodności typów zmiennej i wyrażenia (wyjątkiem jest dopuszczenie przypisania zmiennej typu real wartości wyrażenia typu integer)
Ćwiczenie
1. Wpisać tekst następującego programu, którego zadaniem jest nadanie wartości zdefiniowanym zmiennym prostym rożnych typów. W programie brak jest oczywiście instrukcji wyprowadzających wartości zmiennych na ekran.
program deklaracje;
type
figury = (kwadrat, trojkat, kolo);
napis_krotki = string [5];
var
litera: char;
liczba: integer;
godzina, minuta, sekunda: 1..60;
ilosc, suma: real;
napis_tytulowy : string;
etykieta: napis_krotki;
figura : figury;
czy : boolean;
begin
litera :='A';
godzina := 12;
minuta := 45;
napis_tytulowy := `To jest napis' ;
ilosc := 12.56 ;
suma := ilosc;
figura := kwadrat ;
czy := false ;
end.
2. Uaktywnić okno Watch (menu Debug - Watch). W oknie podglądu wartości zmiennych wstawić (klawisz Insert - Add Watch a następnie wpisanie nazwy zmiennej obserwowanej) wybrane nazwy zmiennych (np. litera, godzina, czy). Wykonywać program krok po kroku (F7) obserwując wartości zmiennych po wykonaniu kolejnych instrukcji.
3. Dokonać próby nadania zmiennym wartości innych typów niż zadeklarowane, na przykład zmiennej logicznej czy nadać dowolną wartość liczbową, czy zmiennej całkowitej godzina wartość rzeczywistą 4.5. Zaobserwować, że nadanie zmiennej ilosc, która jest typu real wartości całkowitej nie powoduje błędu.
4. Wpisać tekst poniższego przykładu:
program wartosci;
const
e = 2.71828;
l_pi = 3.1415926;
fraza = 'Koniec danych';
symbol = ':=' ;
var
litera: char;
godzina: 0..24;
minuta, sekunda: 1..60;
ilosc, suma: real;
napis_tytulowy: string;
begin
godzina := 12 ;
minuta := 23 ;
litera := 'C' ;
ilosc := 56.87e4;
napis_tytulowy :='Wykres `funkcji';
minuta := 24
end.
5. W menu Options - Compiler zaznaczyć w bloku Runtime errors opcję Range checking (sprawdzanie zakresów). Wprowadzić zmiany w programie tak, wartości przekraczały dopuszczalne zakresy, np. dla zmiennej Minuta wartość 100. Uruchomić program i zaobserwować komunikat o błędzie.
Wyrażenia arytmetyczne i logiczne.
Wprowadzanie i wyprowadzanie danych.
Definicja wyrażenia
Wyrażeniem arytmetycznym może być stała, zmienna lub zapis złożonej operacji na stałych, zmiennych i funkcjach (standardowych, bibliotecznych lub własnych użytkownika) z użyciem operatorów arytmetycznych.
Bardziej skomplikowane wyrażenia zawierają operatory i funkcje. Ponadto używamy nawiasów (okrągłych!) w celu zmiany hierarchii działań.
Definicja rekurencyjna wyrażenia (czyli definiowanie przez samą siebie) ma postać:
wyrażenie →stała
wyrażenie →zmienna
wyrażenie → funkcja(wyrażenie)
wyrażenie → wyrażenie operator wyrażenie
Z definicji wynika, że wyrażenia po prawej stronie definicji mogą mieć każdą z postaci definiowanych a zatem np. wyrażenie w nawiasie funkcji może być inną funkcją (tzw. zagnieżdżanie funkcji), operatorami można łączyć wiele wyrażeń itp. Wyrażenia używane są najczęściej w instrukcjach przypisania po prawej stronie znaku :=. Dopuszczalne jest użycie wyrażeń arytmetycznych i logicznych jako parametru procedury wyprowadzania danych (write, writeln) a także w innych instrukcjach zgodnie z zasadami ich składni.
Operatory arytmetyczne
Rozróżniamy następujące operatory:
- jednoargumentowe
zmiana znaku,
+ powielenie znaku,
- dwuargumentowe
- multiplikatywne
mnożenie,
/ dzielenie (rzeczywiste),
div dzielenie całkowite (oba operatory całkowite),
mod reszta z dzielenia całkowitego,
(gdzie znak przedstawia spację),
- addytywne
+ dodawanie,
- odejmowanie.
Przykłady:
7/2 3.5 |
4/2 2.0 |
6.5/2 3.75 |
7 div 2 3 |
17 mod -5 2 |
3.5*x-6/(4-x)+5 |
Hierarchię wykonywania operacji określają następujące reguły:
- nawiasy są najważniejsze (od najbardziej wewnętrznych),
- waga operatorów:
1. jednoargumentowe - najwcześniej wykonywane,
2. multiplikatywne,
3. addytywne - wykonywane na końcu.
Uwaga:
- dla operatorów tej samej wagi - kolejność działań od lewej do prawej,
- jeżeli w wyrażeniu są tylko argumenty całkowite i nie ma dzielenia rzeczywistego to wynik jest typu integer,
- jeżeli występuje chociaż jeden element typu real lub dzielenie jest rzeczywiste to wynik jest typu real.
Na elementach tekstowych (char, string) możemy dokonywać operacji łączenia tekstów (tzw. konkatenacja) używając znaku +,
Np.:
nazwisko := 'Kowalski';
tekst_1 := 'Pan ' + nazwisko ;
w rezultacie zmienna tekst_1 przyjmie wartość tekstową 'Pan Kowalski '.
Funkcje standardowe
Istnieje możliwość użycia w wyrażeniu funkcji standardowych (w kontekście identycznym jak zmienne proste) w postaci:
nazwa_funkcji (argument)
Argumentem może być wyrażenie odpowiedniego typu. Zestaw funkcji standardowych przedstawia tabela.
TABELA. Funkcje standardowe.
Znaczenie |
Nazwa funkcji |
Typ wyniku |
Typ argumentu |
Przykład |
Wartość bezwzględna |
abs |
całkowity rzeczywisty |
całkowity rzeczywisty |
abs(-2) 2 |
Pierwiastek kwadratowy |
sqrt |
rzeczywisty |
rzeczywisty |
sqrt(5.45) |
Kwadrat |
sqr |
rzeczywisty |
rzeczywisty |
sqr(x-5) |
ex |
exp |
rzeczywisty |
rzeczywisty |
exp(-x/2) |
Logarytm naturalny |
ln |
rzeczywisty |
rzeczywisty |
ln(2x-4) |
Sinus |
sin |
rzeczywisty |
rzecz. (radiany) |
sin(3alfa) |
Cosinus |
cos |
rzeczywisty |
rzecz. (radiany) |
cos(beta/2) |
Arcus tangens |
arctan |
rzeczywisty |
rzeczywisty |
arctan(fi) |
Liczba |
pi |
rzeczywisty |
brak (jest to stała predefiniowana) |
sin(30*pi/180) |
Część całkowita |
int |
rzeczywisty |
całkowity rzeczywisty |
int(2.5) 2.0 |
Część ułamkowa |
frac |
rzeczywisty |
całkowity rzeczywisty |
frac(3.6) 3.0 |
Zaokrąglenie |
round |
całkowity |
rzeczywisty |
round(3.6) 4 |
Obcięcie |
trunc |
całkowity |
rzeczywisty |
trunc(3.6) 3 |
Znak następny |
succ |
znakowy |
znakowy |
succ ('g') 'h' |
Znak poprzedni |
pred |
znakowy |
znakowy |
pred(' j ') ' i ' |
znak o podanym kodzie ASCII |
chr |
znakowy |
całkowity |
chr(49) '1' |
kod znaku |
ord |
całkowity |
znakowy |
ord('1') 49 |
Długość tekstu |
length |
łańcuchowy |
całkowity |
length(`alfa') 4 |
W wyrażeniach istotne są wszelkie ograniczenia obszaru określoności, np. użycie ln(-3), sqrt(-5.0) spowoduje błędy wykonania.
Brak w języku funkcji standardowej potęgowania, stąd stosuje się :
x4 xxxx lub sqr (x)sqr (x) lub sqr (sqr (x)),
a w przypadku wyższych lub niecałkowitych potęg stosujemy zapis:
xy exp (yln (x))
Brak w języku również innych, często potrzebnych funkcji, jak na przykład tangens czy logarytm dziesiętny. Trzeba wówczas radzić sobie korzystając z elementarnych definicji matematycznych:
Z rekurencyjnej definicji wyrażenia
Należy zwrócić uwagę na możliwość wystąpienia przekroczenia dopuszczalnych zakresów przy obliczeniach.
Przykładowo poniższe wyrażenie w postaci matematycznej:
należy zapisać w postaci:
(5xx - 2sin (x)+1.5e-5)/(abs (sqrt (x+2)-2)+exp (1.5ln (y)))
W przypadku zastosowania instrukcji:
zmienna := funkcja(zmienna);
obliczana jest wartość funkcji a następnie uaktualniana wartość zmiennej, np.
...
x := 5;
x := 2+sqr(x);
x :=x+5; {powiększenie wartości x o 5}
...
w wyniku uzyskuje się x równe 27.
Funkcje standardowe nie wymagają deklaracji ich użycia ani deklaracji modułu System, w którym są umieszczone.
Możliwe jest stosowanie także funkcji, które umieszczone są w modułach bibliotecznych, np. Crt, Graph i in.. Ich użycie wymaga odpowiedniej deklaracji modułu, np.:
uses crt ;
Użyteczne są funkcje biblioteczne modułu crt:
- clrscr procedura czyszczenia ekranu
- bezparametrowa funkcja readkey, która służy do wczytania z klawiatury jednego znaku,
- bezparametrowa funkcja logiczna keypressed, która służy do sprawdzenia naciśnięcia dowolnego klawisza.
Uwaga na:
operatory arytmetyczne - szczególnie mnożenia - 2*x a nie 2x
format wykładniczy 1.34E-8, 1e7 a nie e7
argumenty funkcji trygonometrycznych w radianach, w przypadku konieczności używania kąta w stopniach należy przeliczyć na radiany wyrażeniem alfa*pi/180,
hierarchię działań - nawiasy
brak potęgowania, brak funkcji tangens i cotangens, logarytm dziesiętny,
różnicę między funkcjami o podobnych nazwach SQR i SQRT.
Wyrażenia logiczne
Wyrażeniem logicznym może być:
1. stała
true prawda 1 - logiczne
false fałsz 0 - logiczne
2. zmienna - typ boolean
3. relacja - porównanie w sensie liczbowym lub tekstowym (wg kolejności alfabetycznej) wg schematu:
wyrażenie1 operator_relacji wyrażenie2
Relacja ma wartość logiczną true lub false. Operatorami relacji są:
(różny)
Przykładowo: x12 2
(4x+1.5) 30.7
nazwisko 'F' nazwiska od F do końca alfabetu
Uwaga: Operatory , , należy używać ostrożnie dla typów rzeczywistych ze względu na przybliżenie wartości.
4. stałe logiczne, zmienne logiczne, relacje (w nawiasie), połączone operatorami logicznymi:
- jednoargumentowym
not (negacja) np. not (i < 5) not obecny
- dwuargumentowymi
and (iloczyn logiczny -„i”) np. (x > 0) and (x < 3)
or (suma logiczna -„lub”) np. (x < 0) or (x > 100)
xor (różnica symetryczna - suma modulo2)
argument 1 |
argument 2 |
and |
or |
xor |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
W operacji przypisania wartości zmiennej logicznej musi zachodzić zgodność typów.
Przykład:
program p3;
var
zwolniony, obecny: boolean;
ocena: real;
liczba_ob: integer;
begin
readln(ocena);
readln(liczba_ob);
obecny := liczba_ob>=6;
zwolniony := (ocena >= 4.5) and obecny;
writeln(zwolniony)
end.
Standardowe procedury czytania i wyprowadzania danych
Do wprowadzenia (standardowo z klawiatury) wartości zmiennej w trakcie wykonania programu służy procedura:
[(lista zmiennych)];
Uwaga: w nawiasach klamrowych { } -elementy do wyboru, w nawiasach kwadratowych [ ] - elementy opcjonalne.
Np. readln (x1, x2, x3, y);
read(x);
Liczby podajemy polami oddzielonymi co najmniej jedną spacją, przecinkiem lub w osobnych wierszach.
Jeżeli wpiszemy za dużo liczb to nadwyżka jest pamiętana dla następnej instrukcji read, natomiast w instrukcji readln czytane jest tyle ile potrzeba a reszta zostaje zignorowana.
Należy uważać na zgodność typów zmiennych i danych (stała całkowita może być wczytana do zmiennej rzeczywistej lecz nie odwrotnie).
Procedurą wyprowadzania danych (standardowo na ekran) jest:
[ (lista elementów) ];
Po wykonaniu instrukcji write kursor pozostaje na końcu wiersza zaś po writeln następuje zmiana wiersza. Elementami listy są stałe, zmienne i wyrażenia wraz z opcjonalnym określeniem formatu wyprowadzenia o postaci:
wyrażenie:m gdzie m to wyrażenie całkowite określające szerokość pola (liczba znaków), dla liczb typu real m 8, jeżeli mniejsze (np. 0) to szerokość dopasowana będzie do niezbędnej liczby cyfr do zapisu wartości (z ewentualnym znakiem),
wyrażenie:m:n m - jak wyżej, n - liczba cyfr po kropce dziesiętnej (tylko typ real).
Przykład:
var x:real ; y:string;
begin
x := -21.546;
y := 'Napis=';
writeln(x); -2.154600000E+01
writeln(x:8); -2.2E+01
writeln(x:10:3); -21.546
writeln(y:10, 'TurboPascal':12); Napis= TurboPascal
end.
Ćwiczenie
Wpisać tekst programu:
program p3_1;
var pensja1,pensja2, srednia: real;begin
(Wprowadzanie danych}
write ('Podaj pensję pierwszą:' ) ; readln(pensja1); write ('Podaj pensję drugą:' ); readln(pensja2);
{Obliczenie średniej} srednia := (pensja1+pensja2)/2;
{Wyprowadzenie wyników}
writeln ; {pusty wiersz}
writeln ('pensja pierwsza:', pensja1:10:2, ` zł'); writeln ('pensja druga :', pensja2:10:2, ` zł'); writeln('Średnia wynosi:':43, srednia:10:2);end.
Wykonać program i obejrzeć wyniki. Wykonać ponownie program zmieniając wartości wprowadzanych danych. Zmienić format wyprowadzanych danych, np. 15:4. Następnie usunąć parametry formatu w procedurze writeln jak poniżej:
writeln ('pensja pierwsza:', pensja1, ` tys. zl'); writeln ('pensja druga :', pensja2, ` tys. zl');
writeln('Średnia :', srednia);
i wykonać program, obserwując postać wyprowadzonych wartości w formacie wykładniczym.
Wprowadzić po nagłówku programu deklarację:
uses crt;
a następnie procedurę czyszczącą ekran:
clrscr;
jako pierwszą instrukcję wykonywalną. Zaobserwować pojawienie się wyników na wyczyszczonym ekranie output przy kolejnych wykonaniach programu.
Zmodyfikować program tak, aby liczył średnią dla trzech liczb o wartościach wprowadzanych klawiatury.
Napisać program:
program p3_2;
uses crt;
var a, b, c, d: integer;
log1, log2, log3: boolean ;
begin
clrscr ;
writeln (`Podaj 2 liczby całkowite oddzielone spacja' );
readln (a, b);
c:= a div b;
d:= a mod b;
log1 := a>0;
log2 := a<>b;
log3 := (a< 5) and (b>= -5);
writeln (`a=', a:3);
writeln (`b=', b:3);
writeln (`c=', c:3);
writeln (`d=', d:3);
writeln (log1:10, log2:10 , log3:10)
end.
Wykonać program kilkukrotnie dla różnych wartości a i b. Przeanalizować otrzymane wartości numeryczne c i d oraz logiczne.
Napisać program, w którym dla zadanej wartości x (np. 3.45) obliczane są wartości następujących wyrażeń i wyprowadzane wyniki na ekran Output:
;
;
;
Sprawdzić zapis wyrażeń, zwracając uwagę na obecność operatorów (szczególnie operatora mnożenia), obecność nawiasów decydujących o hierarchii działań, prawidłowe nazwy funkcji, obowiązkową obecność nawiasów po nazwie funkcji itp. Wykonać program wprowadzając różne wartości x, zwrócić uwagę na błędy wykonania wynikające z niewłaściwych obszarów określoności dla funkcji. Wprowadzać celowo błędy w wyrażeniach, np. brak nawiasów, przekręcone nazwy funkcji itp., zaobserwować wynikające stąd błędy kompilacji.
Napisać program, którego zadaniem będzie znajdowanie kodu ASCII wprowadzanego przez użytkownika znaku.
Napisać program, którego zadaniem będzie znajdowanie znaku o podanym przez użytkownika kodzie ASCII.
Napisać program, który po nadaniu kilku zmiennym wartości tekstowych wypisze je na ekranie:
w jednym wierszu obok siebie,
w osobnych wierszach jeden pod drugim z wyrównaniem do lewej,
w osobnych wierszach jeden pod drugim z przesunięciem w prawo, np.:
tygrys
pantera
piesek
krokodyl
jak wyżej lecz z odstępami międzywierszowymi.
Zadanie do samodzielnego wykonania w domu: Napisać program, w którym zadeklarowane 2 zmienne tekstowe przyjmują wartości dwóch nazwisk wczytywanych z klawiatury w trakcie przebiegu programu. Program sprawdza czy pierwsze nazwisko jest wcześniejsze w kolejności alfabetycznej i umieszcza wynik testu w zmiennej logicznej a następnie wyprowadza jej wartość na ekran.
Schematy blokowe. Instrukcje warunkowe.
Reguły graficzne tworzenia schematów blokowych.
Start i stop
Operacje wejścia i wyjścia
Instrukcja wykonawcza (proces) Blok decyzyjny
Łącznik stronicowy
Rys.5. Symbole operacji używane na schematach blokowych.
Klasyfikacja instrukcji.
Rys.6. Klasyfikacja instukcji w języku Turbo Pascal.
Instrukcje warunkowe.
Instrukcja if.. then ( jeżeli.. to).
Postać skrócona :
if WB then Instrukcja;
„jeżeli” „to”
Wykonywane jest badanie warunku logicznego WB a następnie:
- jeśli WB = true to Instrukcja jest wykonywana,
- jeśli WB = false to Instrukcja jest ignorowana.
Postać pełna:
if WB then Instrukcja_1 else Instrukcja_2;
„jeżeli” „to” „w przeciwnym przypadku”
Wykonywane jest badanie warunku:
- jeśli WB = true to wykonywana jest Instrukcja_1,
- jeśli WB = false to wykonywana jest Instrukcja_2.
Schematy blokowe ilustrujące działanie obu postaci instrukcji ilustruje rysunek.
postać skrócona postać pełna
Rys.7. Schemat blokowy istrukcji if... then...
Przykład:
program p4_1;
uses crt;
var x : real ;
begin
clrscr;
readln(x);
if x = 0 then writeln('Pierwiastek z x wynosi:', sqrt(x):10:3)
else writeln('x jest ujemne');
readln
end.
W przykładzie tym obie instrukcja wyprowadzająca wartość pierwiastka wykonana zostanie jeżeli zajdzie warunek x>=0, w przeciwnym wypadku zostanie wykonana instrukcja wyprowadzająca komunikat że x jest ujemne.
Instrukcje wewnętrzne if mogą także być innymi instrukcjami if. Taką postać stosujemy w przypadku konieczności wykonania różnych instrukcji dla trzech warunków.
Przykład:
program p4_2;
uses crt;
var x : real;
begin
clrscr;
readln (x);
if (x 0) then writeln ('x dodatnie')
else if (x<0) then
writeln ('x ujemne')
else writeln ('x=0');
readln {zatrzymanie ekranu OUTPUT}
end.
Lub inny przykład:
if (x 0) then y := 5
else if (x<0) then y := 6
else y := 7;
Po wykonaniu powyższej instrukcji if odbędą się przypisania:
y → 5 dla x>0
y → 6 dla x<0
y → 7 dla x=0
Instrukcja złożona (sekwencji).
W przypadku konieczności wykonania więcej niż jednej instrukcji dla zachodzącego warunku (lub także nie zachodzącego w drugiej wersji instrukcji if) stosujemy tzw. instrukcję złożoną (sekwencji):
begin
ciąg instrukcji
end;
Przykład:
if x = 0 then
begin
y := y+5;
writeln(y:10:3)
end
else writeln('x jest ujemne');
W przykładzie tym obie instrukcje pomiędzy słowami kluczowymi begin i end wykonane zostaną jeżeli zajdzie warunek x>=0, w przeciwnym wypadku zostanie wykonana instrukcja wyprowadzająca komunikat że x jest ujemne.
Instrukcja wyboru - case
Instrukcja case umożliwia alternatywne wykonanie wielu instrukcji w zależności od wartości wyrażenia typu porządkowego. Postać instrukcji:
case w of
s1,...,sn : Instrukcja_1;
sn+1,...,sm : Instrukcja_2;
....
[ else Instrukcja_k ]
end;
w - wyrażenie selektor typu porządkowego (całkowitego, znakowego),
s - stałe wyboru (etykiety wyboru) w możliwej postaci:
s; - pojedyncza wartość,
s1,...,sn - lista wartości,
s1 .. s2 - zakres wartości.
Działanie instrukcji polega na obliczeniu wartości wyrażenia w i w zależności od wyniku wykonywana jest instrukcja (także złożona) odpowiadająca wartości (wartościom, zakresowi) stałej wyboru.
Instrukcja w opcjonalnym bloku po else wykonywana jest dla wartości nie występującej wcześniej. W listach wyboru można powtarzać te same wartości.
Przykład:
...
readln(miesiac);
case miesiac of
2: dni := 28;
4, 6 , 9, 10: dni := 30;
1..12: dni := 31; {lub else dni := 31}
end ;
Ćwiczenie
Napisać tekst programu p4_1. Wykonać program kilkukrotnie wprowadzając wartości x dodatnie i ujemne. Wykonać program krok po kroku obserwując które instrukcje są wykonywane wewnątrz instrukcji warunkowej.
Napisać tekst programu p4_2. Wykonać program kilkukrotnie wprowadzając wartości x dodatnie i ujemne. Wykonać program krok po kroku, obserwując które instrukcje są wykonywane wewnątrz zagnieżdżanej instrukcji warunkowej.
Napisać tekst programu p4_3. Wykonać program kilkukrotnie wprowadzając różne wartości zmiennej miesiac. Wykonać program krok po kroku.
Zmodyfikować program p4_3 tak, aby dni lutego były równe 28 lub 29 w zależności od tego czy rok jest przestępny (wskazówka: badać przy pomocy instrukcji if.. then.. resztę z dzielenia roku przez 4).
Wpisać tekst programu:
program test4_4;
var p1, p2, p3: real;
spr : boolean;begin
p1:= 34.56; {kąt w stopniach}
p2:= sin(p1*pi/180);
if p2>0 then writeln(` Funkcja ma wartość dodatnią')
else writeln(` Funkcja ma wartość ujemną')
end.
lub
...
begin
p1:= 34.56;
p2:= sin(p1*pi/180);
spr := p2>0;
if spr then writeln(` Funkcja ma wartość dodatnią')
else writeln(` Funkcja ma wartość ujemną')
end.
Przetestować obie wersje programu. Zmodyfikować jego treść tak, aby wartość zmiennej p1 była wprowadzana z klawiatury w trakcie wykonania programu.
Wykonać i przetestować poniższy program, którego zadaniem jest obliczanie pierwiastków równania kwadratowego.
program p4_5;
uses crt;
var
a, b, c, delta, x1, x2: real;
begin
clrscr;
writeln('Podaj współczynniki równania kwadratowego');
write('a=');
readln(a);
write('b=');
readln(b);
write('c=');
readln(c);
delta := b*b-4*a*c;
if delta < 0 then writeln('Brak pierwiastków rzeczywistych')
else
if delta = 0 then writeln('Pierwiastek pojedynczy x1=x2=', -b/2/a)
else
begin
delta := sqrt(delta);
x1 := (-b-delta)/2/a;
x2 := (-b+delta)/2/a;
writeln('Pierwiastki równania kwadratowego');
writeln('x1=':20,x1:10:2);
writeln('x2=':20,x2:10:2)
end;
readln;
end .
Wpisać tekst i przeanalizować poniższy program (instrukcja case z zagnieżdżaniem):
program test4_6;
uses crt;
var nr: integer;
begin
clrscr;
write(`Podaj numer miesiąca:');
readln(nr);
case nr of
4,6,9,11:writeln(`Miesiąc ma 30 dni');
2: writeln(`Miesiąc luty ma 28 lub 29 dni')
else
case nr of
1..12 : writeln(`Miesiąc ma 31 dni');
else writeln(`Nie ma takiego miesiąca')
end;
end;
end.
Wykonać program i kilkakrotnie przetestować jego działanie.
Napisać tekst programu, który wprowadza dowolny rok z przedziału 0 do 4000 i sprawdza czy jest on przestępny. Wskazówka: Zastosować sprawdzanie czy reszta z całkowitego dzielenia roku przez 4 jest równa zero.
Napisać program, który bada podzielność wprowadzanej liczby całkowitej przez 2 i w zależności od reszty z dzielenia (0 lub 1) wyprowadza komunikat czy liczba jest parzysta czy nieparzysta.
Instrukcje iteracyjne (1)
Instrukcja for.. do.. (dla.. wykonuj..)
for Z := Wi1
Wi2 do Instrukcja;
Z - zmienna sterująca (prosta lub indeksowana), typu porządkowego (np. całkowitego lub znakowego).
Wi1 i Wi2 - wyrażenia tego samego typu
Wersja z to Wersja z downto
Rys. 8. Schemat blokowy działania instrukcji for.. do.. .
Wartość zmiennej sterującej zmienia się od Wi1 do Wi2 narastająco (to) lub malejąco (downto), z krokiem 1 w przypadku zmiennej całkowitej lub co znak w wypadku zmiennej typu char.
Np. x := 0;
for i := 1 to 3 do x := x+5; {po 3-krotnie wykonanej iteracji x przyjmie wartość 15}
Instrukcja for jest stosowana gdy z góry znana jest liczba powtórzeń. Wewnątrz iteracji nie wolno zmieniać wartości zmiennej sterującej lecz wolno (i często się to robi) używać zmiennej sterującej w wyrażeniach.
Instrukcją wewnętrzną może być dowolna instrukcja, także inna instrukcja for (zagnieżdżanie iteracji) też instrukcja złożona.
Przykłady:
program p5_1;
var i: integer;
j: char;
begin
for i := 1 to 10 do
begin
for j := 'a' to 'd' do write('');
writeln
end
end.
Zmienna sterująca i ustawiana jest na 1 i wykonywane instrukcje wewnętrzne (w tym wewnętrzne for..do..), następnie zwiększana o 1 wartość i, ponownie wykonywane instrukcje wewnętrzne, itd. Program wyprowadza 10 wierszy po 4 gwiazdki w wierszu.
Drugi przykład zawiera użycie zmiennej sterującej w wyrażeniach:
program p5_2;
var i: integer;
z : real;
begin
z := 2;
for i := 1 to 3 do
begin
z := z + 3 * i;
writeln (z:5*i:2)
end
end.
Efektem programu będzie wyprowadzenie wartości:
5.00 (na 5-ciu pozycjach)
11.00 (na 10-ciu pozycjach)
20.00 (na 15-tu pozycjach)
Ćwiczenie
Wpisać teksty programów przykładowych z rozdziału, w razie potrzeby uzupełniając je o odpowiednie deklaracje, przypisania i instrukcje wyprowadzające wartości zmiennych na ekran Output. Wykonać programy przykładowe używając krokowego śledzenia wartości zmiennych. Testować zmiany zakresów zmiennych sterujących iteracji. W przykładzie p5_1 zmienić typ zmiennej j ze znakowego na całkowity.
Przetestować program obliczający sumę kolejnych N liczb nieparzystych.
program p5_3;
uses crt;
var i, N, suma: integer;
begin
clrscr ;
suma:=0 ;
write('Podaj ile liczb nieparzystych chcesz sumować:') ;
readln( N);
for i:= 1 to N do
suma:= suma+ 2*i -1;
writeln ('Suma wynosi:',suma:10);
readln
end.
Opracować program obliczający wartość funkcji silnia dla podawanej liczby N. Przetestować zakres liczb N dla których program działa prawidłowo. Wprowadzić w programie instrukcję warunkową uniemożliwiającą wprowadzenie N spoza zakresu i żądającą ponownego podania liczby N w dopuszczalnym przedziale.
Opracować program tabelaryzujący funkcje czyli wyprowadzający na ekran 91 wierszy wartości kątów od 0 do 90 stopni a obok w wierszu wartości funkcji sinx i cosx dla tych kątów.
Instrukcje iteracyjne (2)
Instrukcja repeat.. until.. (powtarzaj .. aż..)
Postać ogólna instrukcji:
repeat
ciąg instrukcji
until WB ;
Ciąg instrukcji wewnętrznych jest powtarzany dopóty, dopóki wyrażenie logiczne WB posiada wartość false, zmiana na true powoduje zakończenie pętli. Sprawdzanie warunku odbywa się na końcu pętli, stąd jest ona co najmniej raz wykonywana. Jedna z instrukcji powinna mieć wpływ na wartość wyrażenia logicznego, w przeciwnym wypadku iteracja nigdy się nie skończy. Jeśli błędny warunek spowoduje nieskończoną pętlę możemy przerwać wykonywanie programu kombinacją klawiszy CTRL+Break.
Rys.10. Schemat blokowy instrukcji repeat.. until.. .
Przykład:
program p6_1;
var x:integer;
begin
x := 3;
repeat
x := x + 5;
writeln(x:10)
until x 100;
end.
Program wydrukuje w wierszach kolejne wartości 8, 13.... 103.
Instrukcja while.. do.. (dopóki.. wykonuj..)
Postać ogólna instrukcji:
while WB do Instrukcja;
„dopóki” „wykonuj”
Działanie instrukcji polega na powtarzaniu wykonywania instrukcji dopóki wyrażenie logiczne WB posiada wartość true. Wartość ta jest sprawdzana każdorazowo przed wykonaniem instrukcji. Instrukcja wewnętrzna iteracji może być instrukcją złożoną (begin.....instrukcje... end).
Podobnie jak w repeat..until.. istnieje konieczność wykonania wewnątrz iteracji (także złożonej) operacji wpływającej na wartość wyrażenia logicznego. Jeśli błędny warunek spowoduje nieskończoną pętlę możemy przerwać program kombinacją klawiszy CTRL+Break.
Rys.9. Schemat blokowy instrukcji while.. do..
Przykładowy fragment programu oblicza sumę liczb parzystych od 2 do 100:
program p6_2;
var i,suma:integer;
begin
i := 2;
suma := 0;
while i <= 100 do
begin
suma := suma + i;
i := i + 2;
end;
end.
Ćwiczenie
Wpisać teksty programów przykładowych z rozdziału, w razie potrzeby uzupełniając je o odpowiednie deklaracje, przypisania i instrukcje wyprowadzające wartości zmiennych na ekran Output. W przykładzie p6_1 zamienić miejscami instrukcje wewnętrzne iteracji repeat, sprawdzić i wyjaśnić efekt. Wykonać programy przykładowe używając krokowego śledzenia wartości zmiennych.
Przeanalizować i wykonać poniższy program:
program p6_3;{Przydzielenie do grup wiekowych}
uses crt;
var wiek: integer;
begin
clrscr;
repeat
write( 'Podaj wiek:' );
readln(wiek);
{ if wiek = 0 then break ;}
case wiek of
0 : writeln ( 'Koniec danych' );
1..20 : writeln ( 'GRUPA I' );
21..40 : writeln ( 'GRUPA II' );
41..60 : writeln ( 'GRUPA III' )
else writeln ( 'GRUPA IV' )
end;
until wiek = 0;
writeln ('Naciśnij dowolny klawisz ') ;
repeat until keypressed {X}
end.
Instrukcja {X} jest wielokrotnie wykonywaną iteracją powodującą zatrzymanie ekranu OUTPUT aż do naciśnięcia dowolnego klawisza (funkcja logiczna keypressed pobrana z modułu crt przybiera wówczas wartość true). Uaktywnienie instrukcji w nawiasie klamrowym powoduje przerwanie pętli (procedura break powoduje wcześniejsze zakończenie bieżącej iteracji), sprawdzić to wykonując program krokowo. Czy da się napisać identyczny program ale przy użyciu instrukcji while..do..?
Instrukcje iteracyjne (tego samego lub różnego typu) mogą być zagnieżdżane, jak np. poniżej:
program p6_4;
var a,b,c:integer;
begin
a:=1;
b:=1;
while not (a>=20) do
begin
for c:=2 downto 1 do b:=b+c;
a:=2*b;
end;
writeln( a:5, b:5, c:5)
end.
Przeanalizować powyższy program (bez uruchamiania) i określić końcowe wartości zmiennych a, b, c.
Przetestować krokowo następujący program:
program p6_5;
uses crt;
var znak:char;
begin
write('Naciśnij literę A:');
readln(znak);
while ord(znak)<>65 do
begin
write('To nie ten znak:');
readln(znak)
end; {koniec while}
writeln('Nacisnąłeś A');
repeat until keypressed
end.
Przeanalizować i wykonać poniższy program ilustrujący użycie wszystkich trzech form iteracji w tym samym celu. Wykonywać program „krok po kroku” w celu lepszego zrozumienia zasad działania iteracji.
program p6_6;
var x: 1..7;
begin
writeln('WHILE');
x := 1;
while x = 7 do
begin
write('witaj');
x := x+1;
end;
writeln;
writeln('FOR');
for x := 1 to 7 do write('witaj');
writeln;
writeln ('REPEAT');
x := 1;
repeat
write('witaj');
x := x+1;
until x 7;
readln;
end .
Zadania do samodzielnego wykonania:
a. Opracować program, w którym podajemy dwie liczby, następnie na ekranie drukowany jest ich iloczyn i iloraz. Operacje powtarzają się aż do podania wartości zero dla pierwszej z liczb zadawanych.
b. Opracować program, w którym podajemy liczbę, następnie w pętli jest ona dzielona przez 2, wynik znowu przez 2 i tak dalej aż do uzyskania wartości mniejszej niż 10-20. Dodatkowo wprowadzić zmienną zliczającą ile operacji wykonano i wyprowadzić jej wartość na ekran.
c. Program z pkt. b wzbogacić o wielokrotne jego wykonywanie, tzn. po zakończeniu obliczeń zadawane jest pytanie „czy wykonać obliczenia dla innej liczby?”. Naciśnięcie znaku 't' lub 'n' na klawiaturze powoduje odpowiednie działanie programu.
Typ tablicowy array
Typ tablicowy jest typem strukturalnym (złożonym) stanowiącym skończony zbiór elementów tego samego typu, o położeniu określanym przez indeksy. Zmienna typu tablicowego odpowiada w sensie matematycznym tablicy (macierzy).
Opis typu:
array[ lista typów indeksów ] of typ składowych
typ porządkowy typ dowolny
np. var
tab1: array [ 0..50 ] of integer;
tab2,tab3: array [1..20, 1..30] of real;
tablica: array [ boolean, zakres, dzien_tyg] of char;
Tablice posiadają wymiar zależny od liczby indeksów (1, 2, 3-wymiarowe) oraz rozmiar zależny od zakresu określoności indeksu w każdym wymiarze (np. rozmiar - 10 kolumn, 15 wierszy). Wektor jest tablicą 1-wymiarową.
Zmienne tablicowe całościowe mogą być wykorzystane jedynie w operacji przypisania (przy zgodności typów), np.:
var
tab1, tab2: array [1..10, 1..20] of real;
begin
...
tab1 := tab2;
...
end.
Inne operacje dokonywane być mogą tylko na składowych jeśli są dozwolone dla ich typu. Odniesienie do elementu tablicy dokonuje się w postaci:
nazwa_zmiennej [ indeks1, .... ]
Do nadawania wartości poszczególnym elementom tablicy stosuje się instrukcje wprowadzania danych (read), instrukcje przypisania - często wykorzystując instrukcje for.. do.. gdy poprzez zmienną sterującą iteracji możemy określić indeks(-y) oraz użyć zmiennej sterującej w wyrażeniu przypisywanym elementowi tablicy.
W tablicy dwuwymiarowej trudno jest określić który wymiar opisuje wiersze a który kolumny, gdyż wartości w pamięci operacyjnej układane są „liniowo”. Wszystko zależy od „umowy programowej” i odpowiednio dobierając zmienne sterujące zagnieżdżanych iteracji for.. do.. można wyprowadzić tablicę na ekran wierszami lub kolumnami.
Przykład 1:
program p7_1;
uses crt;
var tab1: array [1..5, 1..5] of real;
{lub
type t55= array [1..5, 1..5] of real;
var tab1:t55; }
i, k :1..5;
begin
clrscr;
tab1[2,3] := 0.1; {nadanie wartości elementowi tablicy}
for i := 1 to 5 do tab1[1, i]:= 0.0; {wypełnianie pierwszego wiersza zerami}
for i := 1 to 5 do tab1[i, i]:= i/2; {wypełnianie przekątnej głównej wartościami 0.5 1 1.5 itd.}
for i := 1 to 5 do
for k:= 1 to 5 do tab1[i, k]:= i+2*k; {wypełnianie całej tablicy stałą wartością, zagnieżdżanie iteracji}
for i := 1 to 5 do
begin
for k:= 1 to 5 do write(tab1[i,k]:4:0);
writeln
end; {wydruk na ekranie całej tablicy}
writeln;
for k:= 1 to 5 do
begin
for i:= 1 to 5 do write(tab1[i,k]:4:0);
writeln
end; {wydruk na ekranie całej tablicy transponowanej - zamiana wierszy i kolumn}
end.
Przykład 2:
program p7_2;
type dni_tyg = (po, wt, sr, cz, pi, so, ni);
wek = array[dni_tyg, boolean] of real;
var x: wek;
begin
...
x[po, true] := 10.2;
x[wt, false]:= 34.0;
writeln(x[wt, false]/100:20:5);
if x[sr,false] > 3e2 then writeln(' W srode za dużo ');
...
end.
Oczywiście tablica typu wek będzie dwuwymiarowa o rozmiarach 7x2.
Przykład 3:
program p7_3;
type opis= (nazw, imie); {wyliczeniowy}
var grupa: array[1..100, opis] of string[30];
i: integer
begin
...
grupa[1, nazw] := 'Kowalski';
if grupa[i, imie] = 'Stanislaw' then
writeln(grupa[i, nazw]:30, grupa[i, imie]:20);
...
end .
Ćwiczenie
Wpisać teksty programów przykładowych z rozdziału, w razie potrzeby uzupełniając je o odpowiednie instrukcje wyprowadzające wartości zmiennych na ekran Output. Prześledzić krokowo programy, obserwując zmienne w oknie Watch.
Opracuj kod programu w którym tablica 5x5 wypełniana jest w pętli kolumnami a jej elementy są:
wartościami średnimi obydwu indeksów
sumami obydwu indeksów
różnicami indeksu wiersza i kolumny
Tablica wyprowadzana jest na ekran.
Opracuj kod programu w którym tablica 5x5 wypełniona jest wartościami 1 (wszystkie elementy) a następnie przeciwprzekątna wartościami 2. Tablica wyprowadzana jest na ekran.
Opracuj kod programu, w którym wektor o rozmiarze 100 wypełniany jest kwadratami kolejnych liczb parzystych aż do przekroczenia wartości 5000 (pozostałe elementy pozostają wypełnione zerami). Tablica wyprowadzana jest na ekran.
Opracować program wyprowadzający na ekran 30 wierszy trójkąta Pascala, definiowanego w postaci:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
....................................................................
gdzie elementy wiersza są sumą sąsiednich elementów wiersza poprzedniego. Dla elementów nieparzystych drukować znak gwiazdki a dla nieparzystych znak spacji. Wykorzystać zagnieżdżane iteracje for..do..
Typ rekordowy - record
Definicja typu rekordowego
Typ rekordowy jest typem strukturalnym o strukturze jednowymiarowej i o składowych dowolnych typów, które nazywają się polami. Zmiennych typu rekordowego używamy w przypadku konieczności utworzenia obiektu opisywanego zbiorem danych różnego typu.
Opis typu:
record
lista_nazw_pól_1: typ1;
lista_nazw_pól_2: typ2;
........
end;
np.
program p8_1;
type
data = record
rok: 1900..2100;
mies: 1..12;
dzien: 1..31;
end;
osoba = record
nazw: string[20];
imie1, imie2: string[15];
data_ur: data; {typ rekordowy wcześniej zdefiniowany}
mezczyzna: boolean;
rodzenstwo: array[1..5] of string[15]
end;
var student:osoba;
begin
....
end.
Pola rekordu mogą być różnego typu, a zatem także rekordowego, tablicowego itp.
Do pól rekordu istnieje dostęp bezpośredni, odwołanie do pola zmiennej odbywa się przez nazwę zmiennej rekordowej i nazwę pola, oddzielonych kropką:
nazwa_zmiennej . nazwa_pola {. ewentualna_nazwa_pola_składowego ...}
np.
student.nazw := 'Kowalski';
if student.data_ur . rok < 1975 then ... {pole data_ur jest typu rekordowego}
UWAGI:
W jednym typie rekordowym wszystkie pola muszą mieć różne nazwy.
Na zmiennych całościowych jedyną dopuszczalną operacją jest przypisanie jednej zmiennej rekordowej wartości innej zmiennej rekordowej tego samego typu, na zmiennych składowych można dokonywać operacji dopuszczalnych dla ich typu.
Tworzenie wielu zmiennych rekordowych dla zapamiętywania strukturalnych danych w trakcie przebiegu programu jest niewygodne, dlatego też często dane tego typu gromadzi się w tablicy (najczęściej jednowymiarowej).
Jeżeli rekordy znajdują się w tablicy, np.
var osoba: record
nazwisko:string;
imie:string:
wiek:0..100
end;
grupa: array [1..30] of osoba;
to dostęp do pola pojedynczego rekordu, będącego elementem tej tablicy może się odbyć w przykładowej postaci:
writeln (grupa[5].nazwisko ) {wczytanie}
lub
grupa[5].nazwisko= 'Kowalski'; {przypisanie}
Przykład:
program p8_2;
type student= record
nazwisko, imie :string[20];
data_ur: record
dzien, miesiac, rok: integer;
end;
rodzenstwo:0..20;
end;
var grupa: array[1..30] of student;
{lub var grupa: array[1..30] of record
nazwisko, imie: string[20]
end;}
var i:1..30;
begin
for i:=1 to 30 do begin
writeln('Podaj dane ', i , '-tego studenta :');
write('Nazwisko');
readln(grupa[i]. nazwisko);
write('Rok urodzenia');
readln(grupa[i]. data_ur.rok);
{....itd. wypełnienie tablicy}
end;
for i:=1 to 30 do
if grupa[i]. data_ur. rok < 1975 then
writeln(grupa[i].nazwisko:30,grupa[i]. rodzenstwo:4);
{wypisanie liczby rodzeństwa tylko dla urodzonych przed 1975 rokiem}
end .
Instrukcja wiążąca - with
Instrukcja with upraszcza zapis dostępu do pól rekordu. Odwołanie w instrukcji (także złożonej) może nastąpić bezpośrednio do nazw pól wymienionych w liście zmiennych, bez wyspecyfikowanej nazwy zmiennej całościowej.
with lista_zmiennych_rekordowych do Istrukcja;
Przykład 1:
program p8_3;
var zespolona: record
rzecz, uroj: real
end;
begin
with zespolona do
begin
rzecz := 2.5;
uroj := 1.0
end;
...
end .
Przykład 2:
program p8_4;
uses crt;
type osoba= record
nr: integer;
nazw: string[30];
end;
var j: 1..10;
student: osoba;
grupa: array[1..10] of osoba;
begin
clrscr;
writeln('Wczytanie danych do tablicy');
with student do
for j := 1 to 10 do
begin
write('Podaj numer: ');
readln(nr);
write('Podaj nazwisko: ');
readln(nazw);
grupa[ j ] := student
end
{.....}
end .
Ćwiczenie
Wpisać teksty programów przykładowych z rozdziału, w razie potrzeby uzupełniając je o odpowiednie instrukcje wyprowadzające wartości zmiennych na ekran Output. Prześledzić krokowo programy, obserwując zmienne w oknie Watch.
Opracuj kod programu, w którym podawane z klawiatury rekordy o organizacji Auto(marka, rocznik, Silnik(pojemność, moc)), gdzie Silnik jest polem typu rekordowego.
Program umożliwia:
wprowadzenie kilku rekordów,
wyświetlenie wprowadzanych danych na ekranie.
Zmodyfikować program tak, aby wprowadzane rekordy były gromadzone w tablicy 1-wymiarowej.
Opracuj kod programu, w którym wykorzystywana jest procedura służąca do mnożenia dwóch liczb zespolonych o organizacji rekordowej Zesp ( re , im ). Wzór na iloczyn dwóch liczb zespolonych to: re3 = re1* re2 - im1* im2, im3 = re1* im2 + re2* im1.
2
1