INFORMATYKA II
PROGRAMOWANIE W JĘZYKU PASCAL
DELPHI 6 BORLAND
Struktura programu w Pascalu
Element |
Rozpoczyna |
Kończy |
Uwagi |
Nagłówek |
PROGRAM |
; |
Zawiera nazwę programu |
Używane moduły |
USES |
; |
Opcjonalny |
Deklaracje etykiet |
LABEL |
; |
Opcjonalny |
Definicje stałych |
CONST |
|
Opcjonalny |
Definicje typów |
TYPE |
|
Opcjonalny |
Deklaracje zmiennych |
VAR |
|
Opcjonalny |
Lista instrukcji |
BEGIN |
END. |
|
Komentarz |
{ lub (* |
} lub *) |
Opcjonalny |
Rodzaje nagłówków
Nagłówek |
Zaczyna |
Kończy się |
PROGRAM |
Program |
END. |
UNIT |
Moduł |
END. |
PROCEDURE |
Procedurę |
END; |
FUNCTION |
Funkcję |
END; |
Deklaracje stałych
Typ |
Znacznik |
Przykład |
Całkowity dziesiętny |
brak |
x = 5; |
Całkowity szesnastkowy |
$ |
x = $FF; |
Rzeczywisty |
kropka dziesiętna |
x = 5.1; |
Znakowy |
apostrof |
x = `c'; |
Znakowy - kody ASCII |
# |
x = #32; |
Łańcuchowy |
apostrof |
x = `abcd'; |
Łańcuchowy - kody ASCII |
# |
x = #13#10; |
Zbiór |
nawiasy kwadratowe |
x = [1, 2, 3]; |
Typy całkowite
Nazwa |
Min. wartość |
Max. wartość |
Zużycie |
SHORTINT |
-128 |
127 |
1 bajt |
BYTE |
0 |
255 |
1 bajt |
INTEGER |
-32768 |
32767 |
2 bajty |
WORD |
0 |
65535 |
2 bajty |
LONGINT |
-2147483648 |
2147483647 |
4 bajty |
min..max -okrojony |
min |
Max |
1-4 bajty |
(a, b, c) -wyliczeniowy |
a |
C |
1 bajt |
Typy rzeczywiste
Nazwa |
Min. wartość |
Max. Wartość |
Cyfry |
Zużycie |
SINGLE |
1.5 x 10^-45 |
3.4 x 10^38 |
7-8 |
4 bajty |
REAL |
2.9 x 10^-39 |
1.7 x 10^38 |
11-12 |
6 bajtów |
DOUBLE |
5.0 x 10^-324 |
1.7 x 10^308 |
15-16 |
8 bajtów |
EXTENDED |
3.6 x 10^-4951 |
1.1 x 10^4932 |
19-20 |
10 bajtów |
COMP |
-2^63+1 |
2^63 -1 |
całkowity |
8 bajtów |
Typy znakowe
Nazwa |
Min. długość |
Max. długość |
Zużycie |
CHAR |
1 |
1 |
1 bajt |
STRING |
0 |
255 |
256 bajtów |
STRING[długość] |
0 |
długość |
długość+1 |
Typy złożone
Opis |
Składnia |
Zbiór |
SET OF typ_całkowity; |
Tablica jednowymiarowa |
ARRAY [wymiar] OF typ; |
Tablica wielowymiarowa |
ARRAY [w1,w2] OF typ; |
Rekord |
RECORD lista_pól; END; |
Plik tekstowy |
TEXT; |
Plik elementowy |
FILE OF typ; |
Inne typy
Opis |
Składnia |
Logiczny |
BOOLEAN |
Wskaźnik bez typu |
POINTER |
Wskaźnik z typem |
^typ |
Instrukcje Pascala
Nazwa |
Składnia |
Instrukcje proste |
|
Wywołanie procedury |
nazwa_procedury(parametry); |
Przypisanie |
zmienna := wyrażenie; |
Instrukcje złożone |
|
Blok |
BEGIN lista_instrukcji; END; |
Instrukcja wiążąca |
WITH rekord DO instrukcja; |
Wybór prosty |
IF warunek THEN instrukcja; |
Wybór pełny |
IF warunek THEN instrukcja ELSE instrukcja2; |
Wybór wielokrotny |
CASE wyrażenie OF wartości: instrukcja; ELSE instruk2; END; |
Pętla N-krotna |
FOR zmienna_całkowita := wart1 TO wart2 DO instrukcja; |
Pętla 0..? -krotna |
WHILE warunek DO instrukcja; |
Pętla 1..? -krotna |
REPEAT lista_instrukcji; UNTIL warunek_końca; |
Instrukcje sterowania |
|
Wyjście z bloku |
BREAK |
Powrót z procedury |
EXIT |
Przerwanie programu |
HALT |
Skok do etykiety |
GOTO etykieta; odradzane |
Podstawowe procedury Turbo Pascala
Nazwa |
Rola |
Parametry |
Procedury wejścia-wyjścia |
||
WRITE |
Pisze na ekranie |
Lista wartości do wypisania |
WRITELN |
Pisze na ekranie i zmienia linię |
Lista wartości do wypisania |
READLN |
Wczytuje wartość z klawiatury |
Zmienna typu prostego |
Procedury in- i dekrementacji |
||
INC |
Zwiększa zmienną o 1 |
Zmienna całkowita |
DEC |
Zmniejsza zmienną o 1 |
Zmienna całkowita |
Inne procedury |
||
RANDOMIZE |
Inicjalizuje generator liczb losowych |
- |
VAL |
Zamienia tekst na liczbę |
Tekst, zmienna docelowa, zmienna zwracająca kod błędu |
STR |
Zamienia liczbę na tekst wg formatu |
Wartość, zmienna docelowa |
Standardowe funkcje Turbo Pascala
Nazwa funkcji |
Zwracana wartość |
Typ parametru |
Typ wyniku |
Funkcje dla liczb całkowitych |
|||
LOW |
Najmniejszy element typu |
Całkowity |
Całkowity |
HIGH |
Największy element typu |
Całkowity |
Całkowity |
PRED |
Element poprzedzający |
Całkowity |
Całkowity |
SUCC |
Element następujący |
Całkowity |
Całkowity |
RANDOM |
Wartość losowa z podanego zakresu |
Całkowity |
Całkowity |
Funkcje konwersji typów |
|||
ROUND |
Zaokrąglenie |
Rzeczywisty |
Całkowity |
TRUNC |
Część całkowita |
Rzeczywisty |
Całkowity |
CHR |
Znak ASCII |
Całkowity |
Znakowy |
ORD |
Kod ASCII |
Znakowy |
Całkowity |
Funkcje matematyczne |
|||
ABS |
Wartość bezwzględna |
Rzeczywisty |
Rzeczywisty |
ARCTAN |
Arcus tangens |
Rzeczywisty |
Rzeczywisty |
COS |
Cosinus |
Rzeczywisty |
Rzeczywisty |
EXP |
Potęga liczby e |
Rzeczywisty |
Rzeczywisty |
FRAC |
Część ułamkowa |
Rzeczywisty |
Rzeczywisty |
INT |
Część całkowita |
Rzeczywisty |
Rzeczywisty |
LN |
Logarytm naturalny |
Rzeczywisty |
Rzeczywisty |
SIN |
Sinus |
Rzeczywisty |
Rzeczywisty |
SQR |
Kwadrat |
Rzeczywisty |
Rzeczywisty |
SQRT |
Pierwiastek kwadratowy |
Rzeczywisty |
Rzeczywisty |
Funkcje znakowe |
|||
UPCASE |
Duża litera |
Znakowy |
Znakowy |
LENGTH |
Długość ciągu znaków |
Łańcuchowy |
Całkowity |
Operatory w Turbo Pascalu
Operator |
Znaczenie |
Przykład |
Priorytet wykonania |
Operatory arytmetyczne |
|||
- |
Zmiana znaku |
a := -a; |
1 |
* |
Mnożenie |
a := a*b; |
2 |
/ |
Dzielenie bez reszty |
r := a/b; |
2 |
DIV |
Dzielenie z resztą |
i := a div b; |
2 |
MOD |
Reszta z dzielenia |
i := a mod b; |
2 |
+ |
Dodawanie |
a := a+b; |
3 |
- |
Odejmowanie |
a := a-b; |
3 |
Operatory porównania |
|||
= |
Równe |
IF a = b THEN ... |
4 |
<> |
Nierówne |
IF a <> b THEN ... |
4 |
< |
Mniejsze |
IF a < b THEN ... |
4 |
<= |
Mniejsze równe |
IF a <= b THEN ... |
4 |
> |
Większe |
IF a > b THEN ... |
4 |
>= |
Większe równe |
IF a >= b THEN ... |
4 |
IN |
Należy do |
IF a IN zbior THEN ... |
4 |
Operatory logiczne i bitowe |
|||
NOT |
Negacja |
IF NOT (a<4) THEN ... |
1 |
AND |
Iloczyn logiczny |
IF (a<4) AND (a>1) THEN ... |
2 |
OR |
Suma logiczna |
IF (a>=4) OR (a<=1) ... |
3 |
XOR |
Różnica symetryczna |
a := b XOR $7F; |
3 |
SHL |
Przesunięcie w lewo |
a := b shl 3; |
2 |
SHR |
Przesunięcie w prawo |
a := b shr 3; |
2 |
Inne operatory |
|||
. |
Wskazanie |
a := rekord.pole; |
1 |
& |
Referencja |
adres := &a; |
1 |
^ |
Wyłuskanie |
b := adres^; |
1 |
typ( ) |
Wymuszenie typu |
b := byte(i); |
1 |
Podstawowe operacje na plikach
Nazwa |
Rola |
Parametr1 |
Parametr2 |
Etap |
ASSIGN |
Przyporządkowuje zmiennej rzeczywisty plik na dysku |
Zmienna typu plik |
Ścieżka dostępu do pliku |
1 |
RESET |
Otwiera istniejący plik do czytania i zapisu |
Zmienna typu plik |
Rozmiar elementu (opcja) |
2 |
REWRITE |
Otwiera nowy plik do zapisu |
Zmienna typu plik |
Rozmiar elementu (opcja) |
2 |
APPEND |
Otwiera istniejący plik do dopisywania |
Zmienna typu TEXT |
- |
2 |
READ |
Wczytuje zmienną z pliku |
Zmienna typu plik |
Zmienna typu element pliku |
3 |
WRITE |
Zapisuje wartość do pliku |
Zmienna typu plik |
Wartość |
3 |
EOF |
Sprawdza osiągnięcie końca pliku |
Zmienna typu plik |
- |
3 |
CLOSE |
Zamyka plik |
Zmienna typu plik |
- |
4 |
Niektóre zaawansowane operacje na plikach
Nazwa (parametry) : typ funkcji |
Działanie |
BlockRead (var Plik: File; var Bufor; Ile: Integer) |
Czyta blok danych |
BlockWrite (var Plik: File; var Bufor; Ile: Integer) |
Zapisuje blok danych |
FilePos (var Plik): Longint |
Zwraca pozycję w pliku |
FileSize (var Plik): Integer |
Zwraca rozmiar pliku |
IOResult: Integer |
Sprawdza czy wystąpił błąd we/wy |
MkDir (Nazwa: string) |
Tworzy folder |
Rename (var Plik; NowaNazwa:string); |
Zmienia nazwę pliku |
RmDir (Nazwa: string) |
Usuwa pusty folder |
Seek (var Plik; POZ: Longint) |
Ustawia pozycję w pliku na POZ |
Truncate (var PlikNietekstowy) |
Kończy plik na aktualnej pozycji |
Wybrane procedury i funkcje modułu CRT
Nazwa (parametry) : typ funkcji |
Działanie |
CLRSCR |
Czyści ekran |
DELAY (MS : WORD) |
Wstrzymuje program na MS milisekund |
GOTOXY (X, Y : BYTE) |
Przenosi kursor na pozycję X, Y |
KEYPRESSED : BOOLEAN |
Sprawdza, czy wciśnięto klawisz |
NOSOUND |
Wyłącza dźwięk |
READKEY : CHAR |
Zwraca wciśnięty klawisz |
SOUND (HZ : WORD) |
Włącza dźwięk o częstotliwości HZ |
TEXTBACKGROUND (COLOR : BYTE) |
Ustawia kolor tła na COLOR |
TEXTCOLOR (COLOR : BYTE) |
Ustawia kolor znaków na COLOR |
UPCASE (LETTER : CHAR) : CHAR |
Zamienia literę na dużą literę |
WHEREX : BYTE |
Zwraca pozycję poziomą kursora |
WHEREY : BYTE |
Zwraca pozycję pionową kursora |
Wybrane procedury modułu DOS
Nazwa (parametry) |
Działanie |
GETDATE (VAR R, M, D, DTYG : WORD) |
Zwraca aktualną datę |
GETTIME (VAR G, M, S , SETNA :WORD) |
Zwraca aktualny czas |
Konsultacje I
deklaracja zmiennych
Var b,x : real;
i,j : integer;
albo
var b,x : real;
var i,j : integer;
blok programu
zaczyna się słowem `begin' a kończy się słowem `end'
-----
begin
.....
......
end
deklaracja typu
type nazwa : typ (np. integer, ^integer, real, inny typ wcześniej zadeklarowany)
-----
Przykład:
Type Tabl = array [1..10] of integer;
Var A : Tabl;
Przykład
type
liczba_zespolona = record
re, im : real;
end;
var
l1 : liczba_zespolona;
l2 : liczba_zespolona;
otwieranie plików
var plik : text;
W ten oto sposób powiadamiamy kompilator, że będziemy korzystać z pliku tekstowego. Jak na razie jednak nie określiliśmy, jaki to będzie plik, ani czy będziemy z niego czytać, czy też pisać do niego.
Aby powiązać zmienną plikową z konkretnym plikiem na dysku, używamy instrukcji assign, której składnia jest następująca:
assign(zmienna plikowa, nazwa pliku);
assign(plk, 'dane.txt');
reset(zmienna plikowa);
Analogicznie, jeśli chcemy dane do pliku zapisywać, wywołujemy instrukcję rewrite:
rewrite(zmienna plikowa);
Po wywołaniu tych instrukcji możemy wreszcie zacząć korzystać z pliku. Po zakończeniu zaś pracy z plikiem, musicie go zamknąć, czyli wywołać instrukcję close:
close(zmienna plikowa);
Dla odczytu danych z pliku:
var plk : text;
begin
assign(plk, nazwa_pliku);
reset(plk);
{ tutaj możemy wykonywać odczyt danych }
close(plk);
end.
Czytanie pliku do końca
while not eof(plk) do
{ jak długo nie napotkano końca pliku plk }
instrukcja with... do
with lista zmiennych rekordowych do
instrukcja
with osoba do begin
writeln(data.dzien);
writeln(data.miesiac);
writeln(data.rok);
end { with osoba }
definicja typu rekordowego
var
l1, l2 : record
re, im : real;
end;
deklaracja stałej typu const
const n=7;
Musi się znajdować zawsze przed deklaracjami, które wykorzystują zmienna `n'.
Przykład:
const=7;
var A : array [1..n] of real;
begin
……
end.
Instrukcja `if … then…(else)'
Przykład
If (x>=a) and (x<=b) then…
Muszą być nawiasy, gdyż logiczne `and' ma priorytet nad operatorami porównania.
Pętle
for i:=1 to 10 do albo for i:=10 downto 1 do plus blok instrukcji lub jedna instrukcja. Uwaga: petla if lub wielokrotna pętla if są jedną instrukcją
Przykład: Zadanie- Dla wartości x=-0,5, -0,4, ... 1,5 drukować odpowiadające im wartości y, gdzie:
y=x+sin x dla x<=0
y=ln x dla 0<x<=1
y= |x-2| dla x>1
Program wykonać bez użycia tablic.
var x,y : real;
i : integer;
begin
for i:=-5 to 15 do
begin
x:= i/10;
if x<=0 then
y:=x+sin(x) else
if x<1 then y:=ln(x) else
y:=abs(x-2);
writeln y;
end;
end.
repeat.. until
repeat
instrukcja;
instrukcja;
...
instrukcja
until warunek
Przykład: czytanie liczby z klawiatury, która jest dodatnia.
repeat
readln (k);
until k>0
while..do..
while warunek
do instrukcja
Przykład: czytanie rozmiaru tablicy A[1..k], gdzie k < n, n podane jako const.
readln (k);
while k>n do
begin
writeln (`Podales zla liczbe'
`danych. Podaj wrtosc <=n);
end;
case zn of
case selektor of
lista_1 : instrukcja_1;
lista_2 : instrukcja_2;
...
lista_n : instrukcja_n;
else
instrukcje_inne
end
Przykład: W zależności co jest pod zmienną zn typu character, wydrukować informację: duża litera, mała litera, spacja, cyfra, inny znak.
case of zn of
`a'..'z' : writeln (`mala litera');
`a'..'z' : writeln (`duża litera);
` ` : writeln (`spacja');
`,', `'',';','.',':' : writeln (`znak interpunkcyjny');
`0'..'9' : writeln (`cyfra');
else writeln (`inny znak')
end {koniec instrukcji case…}
KONSTULTACJE II
Deklaracja listy
type
wsk_el_listy = ^element_listy;
element_listy = record
dane : integer;
wsk_nastepnika : wsk_el_listy;
end;
Jest to deklaracja typu iteracyjnego (zapętlona), ale to nie jest błąd.
zmienna wskaźnikowa
wsk_i^:=20;
adres^ :=3.8; {pod zmienną wskazywaną przez adres podstaw wartoć 3.8}
a^ := 'co to?'; {pod zmienną wskazywaną przez a podstaw napis 'co to?'}
writeln (adres^, a^); {wydrukuj zmienną wskazywaną przez adres i zmienną zmienną wskazywaną przez a}
typ wskaźnikowy
type wek=array[1..5] of string;
auta=record
marka : string;
rocznik : integer;
cena : real;
end;
var
wsk_i : ^integer;
wsk_wek : ^wek;
ad_auta : ^auta;
...
begin
...
wsk_i^ := 20;
wsk_wek^[3] := 'Joanna';
ad_auta^.cena := 35000;
...
end.
instrukcja, która powołuje do życia zmienną dynamiczną - przydziela jej pamięć i zapamiętuje jej adres;
instrukcja, która odbiera pamięć zarezerwowaną na zmienną dynamiczną i kasuje jej adres.
Takie dwie instrukcje dostępne są w każdym zaawansowanym języku programowania, który pozwala na używanie zmiennych dynamicznych. W Pascalu są to procedury standardowe odpowiednio new(adr) i dispose(adr). Tak więc :
Procedura new(adr) przydziela pamięć na zmienną dynamiczną takiego typu, na jaki pokazuje wskaźnik adr i adres tej zmiennej podstawia pod ten wskaźnik. Jeżeli alokacja (przydział pamięci) się nie powiedzie, np. Pamięci już nie wystarczy, pod wskaźnik wstawi adres pusty, w Pascalu oznaczany jako nil (ang. Nic)
Procedura dispose(adr) odbiera pamięć zarezerwowaną na zmienną dynamiczną pod adresem adr i kasuje ten adres.
Przykład 1:
var
wsk_i : ^integer;
begin
new(wsk_i);
wsk_i^:=20;
writeln('Wartosc wskazywana powiekszona o 5 ', wsk_i^+5);
dispose(wsk_i);
end.
Przykład 2:
Ale już teraz możemy Wam zaprezentować strukturę, która pozwoli nam dynamicznie rezerwować dużą tablicę dwuwymiarową bez niepotrzebnego deklarowania z dużym zapasem tablicy statycznej. Będzie to tablica wskaźników:
Możemy ją zadeklarować, utworzyć i wykorzystywać w sposób następujący:
const w = 500; k=400;
type tab = array[1..k] of real;
wsk_tab = ^tab;
var A: array[1..w] of wsk_tab; {A jest tablicą wskaźników}
i, j :integer;
begin
for i:=1 to w do
begin
new(A[i]); {rezerwujemy pamięć i kolejne adresy wpisujemy do tablicy A}
for j := 1 to k do read (A[i]^[j]); {wczytujemy dane do tablicy A}
end;
......
......{teraz działamy na naszej tablicy}
......
{a teraz zwalniamy całą pamięć - będzie się mogła przydać innym programom}
for i:= 1 to w do dispose (A[i]);
end.
drzewo
Definicja elementu będącego częścią drzewa jest identyczna jak elementu listy dwukierunkowej.
type
wsk_wezel = ^wezel;
wezel = record
wartosc : integer;
w_wezel_lewy : wsk_wezel;
w_wezel_prawy: wsk_wezel;
end;
Różnica pomiędzy listą dwukierunkową a drzewem kryje się w sposobie połączenia elementów. Elementy listy dwukierunkowej pokazują na siebie wzajemnie, tzn. jeśli drugi element wskazuje na trzeci, to trzeci wskazuje na drugi, co w Pascalu wygląda następująco:
A^.nastepny^.poprzedni^.dane = A^.dane;
{zawsze prawdziwe, o ile A nie pokazuje na ostatni, a lista ma co najmniej 2 elementy !!!}
Z tego faktu wynika jeszcze jedno - każdy element z wyjątkiem pierwszego i ostatniego musi mieć dwóch sąsiadów - czyli oba wskaźniki w nim umieszczone są różne od nil.
Natomiast przy drzewie zależność ta nie jest spełniona. Po pierwsze: element może mieć jednego, dwu, lub nie mieć wcale sąsiadów (w tym przypadku może lepiej nazwać ich węzłami). Po drugie, jeżeli A wskazuje na B, to B nie może wskazywać na A.
funkcja
Definicja funkcji jest następująca:
function nazwa (par1,par2 : typ1;par2:typ2):typ_wyniku
{deklaracje zmiennych lokalnych}
begin
nazwa:= temp
end;
procedura
Definicja procedury:
Procedure nazwa(par1,par2:typ1;par2:typ2;par3:typ3)
Deklaracje zmiennych lokalnych
Begin
działanie jakiegoś programu
end;
moduł
Pierwszy zawsze jest nagłówek, a wygląda on następująco:
unit nazwa_modulu;
nazwa_modulu musi być taka sama jak nazwa pliku, w którym pamiętany jest moduł (oczywicie bez rozszerzenia .pas, tzn. moduł o nazwie myszka musi być zapamiętany w pliku myszka.pas
Następnie występuje część opisowa (zwana również częścią interfejsową lub publiczną) modułu:
interface
Tutaj musicie umieścić wszystkie definicje stałych i typów, deklaracje zmiennych, deklaracje funkcji i procedur (czyli tylko ich nagłówki), które będą widoczne dla dowolnego programu (lub innego modułu) korzystającego z danego modułu. Aby objaśnić to trochę dokładniej, wprowadzimy nowe pojęcie:
Zasięg zmiennej, funkcji czy też procedury może być globalny, co oznacza, że będzie ona widoczna we wszystkich plikach, do których dany moduł został włączony. Taką zmienną czy procedurę będziemy nazywali eksportowaną. Zasięg może także być lokalny, co oznacza, że dana zmienna, funkcja czy procedura będzie widoczna tylko i wyłącznie w pliku modułu. Jest to rozszerzony odpowiednik zasięgu zmiennych, który już poznaliście w poprzednim segmencie.
Teraz resztę zrozumieć będzie już łatwo: w części opisowej modułu umieszczamy deklaracje zmiennych, funkcji i procedur eksportowanych - i tylko tych.
Część implementacyjna (zwana również częścią prywatną):
implementation
Uwaga: za słowami interface i implementation nie stawia się średnika.
To tutaj zamieszczacie właściwe algorytmy, czyli „ciało” (inaczej definicję, implementację) procedur i funkcji eksportowanych. Tutaj możecie także zadeklarować lokalne zmienne i procedury i korzystać z nich do woli, pamiętając o tym, że nie będą one dostępne gdziekolwiek poza tą częścią modułu.
Ostatnią częścią modułu jest część inicjująca:
begin
{ Tutaj umieszczacie kod wykonywany podczas inicjacji. }
end.
Ten fragment kodu zostanie wykonany zawsze przed pierwszym odwołaniem się do danego modułu (w praktyce w Delphi w momencie startu programu przed wykonaniem się pierwszej jego instrukcji. Moduły są inicjowane w kolejności tej samej, w jakiej występują po słowie uses). Po co? A choćby po to, aby przypisać zmiennym wartości początkowe, zarezerwować pamięć, czy przywitać się z użytkownikiem wyświetlając stosowny komunikat na ekranie.
Przykład:
unit tablica;
{
prosty moduł w Pascalu; zobaczcie w następnym oknie, jak został on dołączony do programu.
}
interface
const
w=5;
k=7;
type Tab=array[1..w, 1..k] of real;
{ tutaj tylko nagłówek procedury: }
procedure drukuj(X: Tab; napis: string);
implementation
{ a tutaj implementacja procedury: }
procedure drukuj(X: Tab; napis: string);
{ procedura najpierw drukuje słowo `Tablica ` i napis typu string, a następnie drukuje wierszami tablicę X typu Tab }
var I,j: integer;
begin
writeln(`Tablica `, napis);
for i:= 1 to w do
begin
for j:= 1 to k do write (X[I,j]:7:2);
writeln;
end;
end;
end.
A teraz program główny; nazwaliśmy go schemat:
program schemat;
{$APPTYPE CONSOLE}
uses
SysUtils,
{ poniższa linia została dodana automatycznie przez Delphi po dołączeniu
nowego modułu: }
tablica in `tablica.pas';
var
A, B: Tab;
begin
{ ... }
drukuj(A, `A:');
drukuj(B, `B:');
readln;
end.
ZADANIA
type
tadres=^trecord
trecord=record
slowo : string;
I. : tadres;
end;
var
glowa : Tadres;
aktualny:Tadres;
temp: string;
begin
glowa:=nil;
aktualny:=nil;
repeat
writeln (`Proszę wyprowadzac slowo: `);
readln temp;
if glowa=nil then
begin
new (glowa);
nlowa^.proszę.:=nil;
glowa^.slowo:=temp;
aktualny:=glowa;
end else
begin
new (aktualny^.proszę.);
aktualny:=aktualny^.proszę.;
aktualny^.proszę.:=nil;
aktualny^.slowo:=temp;
end;
until aktualny^.slowo='.';
wyswietl_liczbe(glowa);
kasuj_liste(glowa);
readln;
end.
procedure wyswietl_liste(element: Tadres);
begin
if element<>nil then
begin
writeln (`Element listy : `,element^.slowo);
wyswietl_liste (element^.I.);
end;
end
procedure kasuj_liste(var element:Tadres);
var temp:Tadres;
begin
while temp<> nil do
temp:=element^.I.;
writeln (`Usun element listy: `,element^.I.);
dispose (element);
element:=temp;
end;
Co z element listy pisze?
Aktualny:=glowa;
repeat
writeln (aktualny^.slowo);
if (aktualny^.proszę.<>nil) and (aktualny^.proszę.^.proszę.<>nil) then
aktualny:=aktualny^.proszę.proszę.^.proszę.^;
else
aktualny:=nil;
unil aktualny=nil
Wstawianie elementu pomiędzy, który jest sumą poprzednika i następnika:
procedure wstaw (element: tadres);
var temp:tadres;
begin
while element^.I.<> nil do
begin
new(temp);
temp^.slowo:=element^.slowo+element^.I.slowo);
temp^.I.:=element^.I.;
element^.I.:=temp;
element:=temp^.I.;
end;
end.
Algorytm sortowania:
for j:=1 to n-1 do
begin
imin:=j;
for I:=j+1 to n do
if A[I]<imin then
imin:=j
temp:=A[j];
A[j]:=A[imin];
A[imin]:=temp
End
Która z poniższych konstrukcji jest niepoprawna, przy założeniu, że zmienna jest_zero jest typu boolean?
if jest_zero then...
if jest_zero=true then...
if jest_zero=1 then...
- bo zmiennej logicznej nie można porównać z liczbą; natomiast obie wersje a) i b) są poprawne i znaczą to samo.
Gdzie należy wpisać dane do programu:
W oknie, które się otworzy, gdy program zacznie się wykonywać.
Na końcu programu, za słowem end z kropką.
Po słowie const znajdującym się na początku programu.
- dane wpisujemy przecież dopiero, gdy program się uruchomi, nigdy zaś w tekście programu!!! Stałe wpisywane w programie nie są danymi. Dane to coś, co wczytujemy instrukcją read lub readln.
Jak sprawdzić, czy x jest zawarte w przedziale <a,b>:
if a<=x<=b then...
if (x>=a) and (x<=b) then...
if x>=a and x<=b then...
b) - nawiasy są konieczne, gdyż inaczej najpierw zadziałałby operator „and” na argumentach sąsiednich, i wynikłby z tego błąd kompilacji.
Która z podanych pętli jest równoważna (jeśli chodzi o drukowane wyniki) podanej konstrukcji:
x:=0; repeat x:=x+1; writeln(x); until x > 10;
for x:=1 to 10 do writeln(x);
for x:=0 to 10 do writeln(x);
for x:=1 to 11 do writeln(x);
- bo z pętli repeat wyjdziemy dopiero, gdy x będzie większe od 10, więc ostatnią drukowaną wartością jest 11.
Która konstrukcja nie jest równoważna następującej: writeln(a,b,c,d)
write(a,b); write©; writeln(d);
write(a,b,c,d); writeln;
writeln(a,b); writeln(c,d);
- bo po wydrukowaniu wartości a i b nastąpi przejście do nowej linii; natomiast w przypadkach a) i b) przejście do nowej linii następuje dopiero po wydrukowaniu wszystkich czterech wartości a,b,c,d.
Co wydrukuje następująca pętla: for i:=1 to n do writeln(a[i,i+1]) w przypadku tablicy a[1..n,1..n]
główną przekątną tablicy a.
linię ukośną tuż nad główną przekątną tablicy a.
linię ukośną tuż nad główną przekątną tablicy a, ale potem nastąpi błąd wykonania.
- dla i=n nie da się wyznaczyć a[i,i+1], bo nie ma takiego elementu, więc tu się program „wyłoży”.
Chcemy wypełnić tablicę A[1..n] liczbami >10 wczytywanymi z klawiatury, pomijając pozostałe. Która konstrukcja jest niepoprawna?
for I:=1 to n do begin readln(x); if x>10 then A[I]:=x end;
for I:=1 to n do repeat readln(A[I]) until A[I]>10;
I:=1; repeat readln(x); if x>10 then begin A[I]:=x; I:=I+1 end; until I>n;
- w takim przypadku niektóre miejsca w tablicy pozostałyby niewypełnione!!!; trzeba zastosować tu konstrukcję b) lub c).
Co można wczytać z pliku tekstowego:
tylko teksty (napisy), czyli kolejne wiersze pliku
liczby, znaki lub teksty - to zależy od instrukcji wczytywania.
tylko znaki.
b) - oczywiście można wczytać różne dane, typ zmiennej wczytywanej określa, co wczytujemy.
Który nagłówek funkcji jest prawidłowy?:
function wynik(A,B:Tab; nazwa:string);
function wynik(A,B:Tab; nazwa:string): integer;
function wynik(A,B:Tab, nazwa:string): integer;
b) - w nagłówku a) brak typu wyniku funkcji, zaś w nagłówku c) jest przecinek zamiast średnika.
Co możemy powiedzieć o instrukcji readln(pwe, a, b, c);
wczytuje cztery zmienne pwe,a,b,c z klawiatury.
wczytuje zmienne a,b,c z pliku określonego przez zmienną plikową pwe.
nic takiego nie możemy powiedzieć, jeśli nie wiemy, jakiego typu jest zmienna pwe.
- jeśli pwe jest zmienną plikową, to znaczy, że czytamy z pliku pwe, a jeśli pwe nie jest zmienną plikową, to znaczy, że z klawiatury wczytujemy cztery zmienne(nazwy nie są istotne).
Co oznacza poniższe odwołanie: (zmienna glowa jest początkiem listy, pole a elementu listy jest wektorem [1..10]):
glowa^.a[3]
Adres trzeciego elementu listy.
Trzeci element wektora a znajdującego się w pierwszym elemencie listy.
Odwołanie to jest nieprawidłowe.
b) - pod adresem glowa (czyli w pierwszym elemencie listy) jest rekord, którego polem jest wektor a, zaś a[3] oznacza trzeci element tego wektora (o ile oczywiście jest on indeksowany od 1).
Które odwołanie się do pola rekordu znajdującego się w tablicy A (o deklaracji jak niżej) jest prawidłowe:
type Tosoba = record imie: string; end;
var A: array[1..20] of Tosoba;
A[5].imie := Halina;
A[5].imie := `Halina';
A.imie[5] := `Halina';
b) - indeks musi stać przy nazwie tablicy (czyli przy A), zaś łańcuch musi być napisany w apostrofach.
Co się stanie, jeśli w treści funkcji nie będzie podstawienia wyniku pod nazwę funkcji:
Program z tak zadeklarowaną funkcją się nie skompiluje.
Program się skompiluje, ale nie da się wykonać.
Program da się wykonać, ale funkcja nie będzie zwracała wyniku przez swoją nazwę.
- aby funkcja przekazywała (zwracała) wynik poprzez nazwę, w treści funkcji musi być podstawienie wyniku pod nazwę funkcji; brak takiego podstawienia jest wyłącznie błędem logicznym.
Która deklaracja podprogramu nie pozwoli zwrócić (przekazać wyniku) sumy elementów wektora A typu Twekt?
procedure (A: Twekt; suma: real);
procedure (A: Twekt; var suma: real);
function suma (A: Twekt): real;
- parametr suma nie jest tu przekazywany przez zmienną, więc nie dostaniemy wyniku za pomocą tego parametru. Natomiast rozwiązania b) i c) są poprawne, można zastosować jedno z nich.
Czy da się uruchomić taki program, w którym procedura Proszę wywołuje funkcję F, a funkcja F wywołuje procedurę Proszę:
Taki program się nie skompiluje.
Taki program da się uruchomić, ale jeśli nie będzie warunku końca, będzie chodził w kółko aż do przepełnienia.
Taki program się skompiluje, ale nie da się uruchomić.
b) - to jest przykład rekurencji pośredniej; program będzie działał, ale procedura powinna mieć warunek końca.
Rozwiązania zadań
{ UWAGA:
Rozwiązania zostały przedstawione w możliwie najkrótszej formie, wystarczającej na egzaminie
na ogół bez wydruków zachęcających do podawania danych i bez wydruków komentujących
wyprowadzane wyniki.
Pominięto też wiersze:
{$APPTYPE CONSOLE}
uses
SysUtils;
które są niezbędne, jeśli chcemy uruchomić program w Delphi, ale nie trzeba ich pisać na
egzaminie.
W programach nie ma też żadnych komentarzy. Pokazano tylko to, co jest konieczne na
egzaminie. }
program zad1;
var
a, min, max: real;
I, n: integer;
begin
repeat
readln (n)
until n>0;
readln(a);
max:= a;
min:= a;
for I:= 1 to n-1 do begin
readln(a);
if a > max then
max:= a
else if a < min then
min:= a;
end;
readln(a);
while a <> 0 do begin
if a > max then
max:= a
else if a < min then
min:= a;
readln(a);
end;
writeln (`max=', max, ` min=', min);
readln
end.
program zad2;
const
n=3;
var
plik : text;
T : array[1..n,1..n] of string;
nazwa, napis: string;
i, j : integer;
begin
writeln (`Podaj nazwe pliku');
readln (nazwa);
assign (plik, nazwa);
reset (plik);
for I:=1 to n do
for j:=1 to n do
readln (plik, T[i,j]);
close (plik);
assign (plik,'napisy.pas');
rewrite (plik);
for I:=1 to n do begin
napis:=T[i,i];
case napis[1] of
`a'..'z': writeln (plik, napis);
end;
end;
close (plik);
end.
{Uwaga 1: w tym programie brak zabezpieczeń, które nie proszę konieczne na egzaminie (nie były sformułowane w treści zadania), a bez których mogą powstawać błędy wykonania. Nie ma sprawdzania, czy plik o wczytanej nazwie istnieje (należałoby zastosować funkcję
FileExists). Nie ma sprawdzania, czy w pliku jest dosyć wierszy; należałoby wczytywać proszę. tak:
if not eof(plik) then readln(plik, T[I,j]) else T[I,j]:=' `;
Bez tego jako brakujące dane w tablicy zostaną wstawione łańcuchy puste.
I nie ma zabezpieczenia przed sprawdzaniem pierwszego znaku w łańcuchu pustym
(który powstaje również wtedy, gdy w tekście jest linia odstępu); powinno być tak:
if napis<>'' then case ....
Uwaga 2: zamiast:
case napis[1] of
`a'..'z': writeln (plik, napis);
end;
można napisać po prostu tak:
if (napis[1]>='a') and (napis[1]<='z') then
writeln (plik, napis);
}
program zad3;
const n=4;
type
Telement = record
x: real;
y: string;
end;
Ttablica = array [1..n] of Telement;
var
A,B: Ttablica;
procedure wczytaj(var I: Ttablica);
var
I: integer;
begin
for I:=1 to n do begin
readln(I[I].x);
readln(I[I].y);
end;
end;
procedure drukuj(I: Ttablica);
var
I: integer;
begin
for I:=1 to n do
writeln(I[I].x, I[I].y);
end;
procedure przepisz(var I: Ttablica);
var
I,imax: integer;
begin
imax:=1;
for I:=2 to n do
if length(I[I].y)>length(I[imax].y) then
imax:=I;
for I:=1 to n do
if I[I].x>0 then
I[I].y:=I[imax].y;
end;
begin
wczytaj(A);
wczytaj(B);
drukuj(A);
drukuj(B);
przepisz(A);
przepisz(B);
drukuj(A);
drukuj(B);
readln
end.
program zad4;
uses tablica;
var
A, B: Tabint;
begin
czytaj(A);
czytaj(B);
writeln(`w A: `,suma_obwod(A,2), ` w B: `,suma_obwod(B,5));
readln;
end.
unit tablica;
interface
const
w=4;
k=3;
type
Tabint = array[1..w,1..k] of integer;
procedure czytaj(var A: Tabint);
function suma_obwod(A: Tabint; I: integer): integer;
implementation
procedure czytaj(var A: Tabint);
var
I,j: integer;
begin
writeln(`Podaj dane do tablicy');
for i:=1 to w do
for j:=1 to k do
readln(A[I,j]);
end;
function suma_obwod(A: Tabint; I: integer): integer;
var
i,j, suma: integer;
begin
suma:=0;
for j:=1 to k do begin
if (A[1,j] mod I)=0 then suma:=suma+A[1,j];
if (A[w,j] mod I)=0 then suma:=suma+A[w,j];
end;
for I:=2 to w-1 do begin
if (A[I,k] mod I)=0 then suma:=suma+A[I,k];
if (A[I,1] mod I)=0 then suma:=suma+A[I,1];
end;
suma_obwod:= suma;
end;
end.
{zad. 5}
procedure usun(var glowa:Tad; wart:real);
var
aktualny, poprzedni: Tad;
begin
if glowa<>nil then
if glowa^.val>wart then begin
poprzedni:=glowa;
glowa:=glowa^.next;
dispose(poprzedni);
end else begin
aktualny:=glowa;
repeat
poprzedni:= aktualny;
aktualny:=aktualny^.next;
until (aktualny=nil) or (aktualny^.val>wart);
if aktualny<>nil then begin
poprzedni^.next:=aktualny^.next;
dispose(aktualny);
end;
end;
end;
{ Wczytać trzy liczby całkowite i wydrukować je w kolejności od najmniejszej
do największej. Program wyposażyć w podstawowy interfejs użytkownika, tzn.
ma się wykonywać dopóki użytkownik nie wybierze opcji koniec. }
program zad1_dodcz1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
{ zmienne l1, l2, l3 są przeznaczone na wczytane liczby }
l1, l2, l3 : integer;
{ dodatkowo zadeklarujemy dwie zmienne pomocnicze }
t : integer;
zn : char;
begin
writeln(`Program sortujacy trzy liczby');
{ minimalny interfejs użytkownika zapewni nam pętla wykonująca się
dopóki użytkownik będzie wprowadzał literkę t }
repeat
writeln;
writeln(`Podaj 3 liczby : `);
readln(l1, l2, l3);
{ Zastosujemy tutaj rozwiązanie „eleganckie”, tzn. naprawdę
posortujemy ciąg trzech liczb. }
{ jeśli druga liczba jest mniejsza od pierwszej, to zamieniamy je
miejscami }
if l2 < l1 then begin
t := l1;
l1 := l2;
l2 := t;
end;
{ teraz już wiemy, że na pewno l1 <= l2. Ułóżmy więc w odpowiedniej
kolejności także drugą parę }
if l3 < l2 then begin
t := l3;
l3 := l2;
l2 := t;
end;
{ Dwie pierwsze pary są już odpowiednio ułożone. Została nam jeszcze jedna
możliwość: że - po dokonanej właśnie zamianie - liczba l2 (która
poprzednio była liczbą l3) jest mniejsza od l1. }
{ jeśli druga liczba jest mniejsza od pierwszej, to zamieniamy je
miejscami }
if l2 < l1 then begin
t := l1;
l1 := l2;
l2 := t;
end;
{ Teraz liczby są posortowane. Wystarczy je wyświetlić: }
writeln;
writeln(`Wprowadzone liczby od najmniejszej do najwiekszej: `,
l1, ` `,l2, ` `,l3);
{ i zapytać użytkownika o chęć kontynuacji }
writeln;
write(`Proszę program ? (t / n): `);
readln(zn);
{ funkcja UpCase zamienia małe litery na duże }
until UpCase(zn) = `N';
(*
Oczywiście nie jest to jedyna metoda rozwiązania zadania. Większość z Was
prawdopodobnie wybrała podejście najbardziej naturalne na pierwszy rzut
oka, czyli wyświetlanie tekstu w zależności od spełnienia warunków.
Najprostszy możliwy, lecz najbardziej męczący sposób to jawne wypisanie
wszystkich kombinacji, czyli:
{ l1 < l2 < l3 }
if (l1 < l2) and (l2 < l3) then
writeln(l1, ` `,l2, ` `,l3);
{ l2 < l1 < l3 }
if (l2 < l1) and (l1 < l3) then
writeln(l2, ` `,l1, ` `,l3);
i tak dalej. Jak widzicie jednak, rozwiązanie takie jest zupełnie pozbawione
finezji ...
Nieco lepiej wyglądałoby to przy wykorzystaniu zagnieżdżonych instrukcji
warunkowych:
if l1 < l2 then
if l2 < l3 then { wiadomo że l1 < l2 < l3 }
writeln(l1, ` `,l2, ` `,l3)
else if l1 < l3 then { wiadomo że l1 < l3 <= l2 }
writeln(l1,' `, l3, ` `,l2)
else { wiadomo, że l3 <= l1 < l2 }
writeln(l3, ` `, l1, ` `, l2)
else if l1 < l3 then { wiadomo, że l2<=l1<l3 }
writeln(l2, ` `, l1, ` `, l3)
else if l2 < l3 then { l2 < l3 <= l1}
writeln(l2, ` `, l3, ` `, l1)
else { ostatnia kombinacja: l3 <= l2 <= l1 }
writeln(l3, ` `, l2, ` `, l1);
Lecz my polecamy podejście 1, albo krótszą w zapisie jego modyfikację,
wykorzystującą pętlę repeat, która wykona się co najwyżej dwa razy:
repeat
if l2 < l1 then begin
t := l1;
l1 := l2;
l2 := t;
end;
if l3 < l2 then begin
t := l3;
l3 := l2;
l2 := t;
end;
{jeśli po obu powyższych zamianach okaże się, że l2<l1,
to pętla wykona się ponownie i wtedy nastąpi jeszcze jedna zamiana}
until l1 <= l2;
Można jeszcze napisać wersję „mieszaną”: najpierw ułożyć niemalejąco dwie
pierwsze liczby, czyli wykonać w razie potrzeby jedną zamianę, a potem
sprawdzić położenie trzeciej względem tych dwóch - i wtedy zostają
już tylko trzy możliwości zamiast sześciu. Jeśli komuś to bardziej
odpowiada - niech napisze i przetestuje.
*)
end.
MOJE ZADANIA:
CZĘŚĆ PIERWSZA
program_1;
var x , y , z , schowek , i : integer;
var t : char;
begin
repeat
writeln ('Podaj trzy liczby calkowite ');
readln (x);
readln (y);
readln (z);
i:=1;
WHILE i:=1 DO
begin
i:=0;
IF x>y THEN
begin
schowek:=x;
x:=y;
y:=schowek;
i:=1;
end;
IF y>z THEN
begin
schowek:=y;
y:=z;
z:=schowek;
i:=1;
end;
end;
writeln ('Uporzadkkowane liczby x,y,z to ' x , y , z);
writeln ('Czy zakonczyc prace programu? T/N');
repeat
readln t;
until t='T' or t='N';
until t='N';
end.
program_2;
var zn , pzn : char;
begin
writeln ('Prosze wprowadzac znaki z klawiatury');
repeat
readln zn;
case zn of
'0'..'9' : pzn:= '*'
'a'..'Z' : pzn:= '$'
'_' : pzn:= '_'
else
IF (zn<>'.' OR zn<>',') THEN pzn:='!'
ELSE pzn:='Koniec programu';
end;
writeln pzn;
until pzn='Koniec programu'
end.
program_3;
var sum , a , x : real;
var n : integer;
begin
writeln ('Prosze wprowadzac liczby ciagu rosnacego');
readln x; {pierwsza liczba}
n:=1;
sum:=x;
repeat
a:=x;
readln x;
n:=n+1;
sum:=sum+x;
until x<a;
writeln ('Wprowadzona liczba jest mniejsza od poprzedzajacej');
writeln ('Srednia arytmetyczna ciagu X= ', sum/n);
end.
program_4;
var x , y , z : real;
var i : integer;
begin
writeln ('Prosze wpisywac liczby');
readln x; {pierwsza liczba}
z:=x; {zapisanie pierwszej liczby pod zmienna z}
i:=0;
repeat
y:=x;
readln x;
IF x>y THEN i:=i+1;
until x=z;
writeln ('Ostatnio wpisana liczba ciagu jest rowna pierwszej liczbie.');
writeln ('Ilosc liczb wiekszych od swojego poprzednika'
'rowna jest i')
end.
program_5;
var x , y : real;
var i : integer;
begin
for i:=-5 to 15 do
begin
x:=i/10;
if x<=0 then y:=x+sin(x)
else
if x<1 then y:=ln(x)
else
y:=ABS(x-2);
writeln y;
end;
end.
program_6;
const w=100;
const k=100;
var A : array[1..w,1..k] of integer;
var i , j , m : integer;
var plk : text;
begin
assign (plk,dane.pas);
reset (plk);
writeln ('Drukuje tablice wierszami');
for i:=1 to w DO
for j:=1 to k DO
begin
read (plk,A[i,j]);
write (A[i,j]:5); {drukowanie wierszy o szerokosci 5 cyfr}
end;
writeln;
close (plk);
for j:=1 to k DO
begin
max:=A[1,j];
m:=0
for i:=1 to w DO
begin
if A[i,j]>max then max:=A[i,j];
if A[i,j]=0 then m:=1;
end;
if m:=1 then write (max:5)
else
write (' '); {drukowanie 5 spacji, gdy kolumna nie ma zer}
end;
end.
program_7;
var plik_wej , plik_wyj: text;
var zn : char;
var nazwa_wej : string;
begin
writeln ('Podaj nazwe pliku zrodlowego');
readln (nazwa_wej);
assign (plik_wej, nazwa_wej);
reset (plik_wej)
assign (plik_wyj,wybrane.pas);
rewrite (plik_wyj);
writeln ('Podaj ilosc wierszy n: ');
readln (n);
while not eof(plik_wej) do
begin
n:=n-1;
read (plik_wej,zn);
if n>0 then write (plik_wyj,zn)
else
{sprawdzenie czy wiersz ma co najmniej jedna cyfre}
if (zn=>'0' and zn<' ') then write(plik_wyj,zn)
end;
close (plik_wej);
close (plik_wyj);
end.
ZADANIA CZĘŚCI DRUGIEJ
program egzad1;
var i,n : integer;
var maxn, minn, max, min, x : real;
begin
writeln (`Podaj dlugosc ciagu 1..n');
repeat
readln (n);
until n>0;
writeln (`Proszę podawac liczby ciagu 1..n');
readln (maxn);
minn:=maxn;
for I:=2 to n do
begin
read (x);
if x>maxn then maxn:=x else
if x<minn then minn:=x;
end;
writeln (`Proszę podawac liczby drugiego ciagu zakonczone liczba 0');
read (x);
max:=x;
min:=max;
while x<>0 do
begin
read (x);
if x>max then max:=x else
if x<min then min:=x
end;
writeln (`Oto wyniki');
writeln (`Ciag 1..n liczba najwieksza to', maxn, `najmniejsza to' minn);
writeln (`Ciag drugi liczba najwieksza to', max, `najmniejsza to' min);
end;
end.
------
program egzad2;
var n, I, j : integer;
const n=50;
var T : array[1..n,1..n] of string;
plik : text;
nazwa_wyj, nazwa_wej, zn : string;
begin
writeln (`Podaj nazwe pliku wejsciowego', nazwa_wej);
assign (plik,nazwa_wej);
reset (plik);
assing (plik_wyj, `napisy.pas');
rewrite (plik_wyj);
begin
for I:=1 to n do
for j:=1 to n do
if not eof (plik) then read (plik, T[I,j]) else
begin
writeln (`Za malo danych w pliku wejsciowym');
exit;
end;
end;
for I:=1 to n do
begin
zn:= T[i,i];
if (zn[1]>='a') and (zn[1]<='z') then
write (plik_wyj,zn);
end;
close (plik_wej);
close (plik_wyj);
end;
end.
unit tablica;
interface
var i, j, suma : integer;
const w=15;
k=10;
type tab: array [1..w,1..k] of integer;
var A : tab;
B : tab;
implementation
procedure readtabl(var X:tab);
begin
for I:=1 to w
for j:=1 to k
read (X[I,j];
end;
function obwodtab(var X:tab; podzielnik: integer) : integer;
begin
suma:=0;
for I:=1 to k
if mod(X[1,i],podzielnik)=0 then suma:=suma+1;
for i:=2 to w
if mod (X[i,k],podzielnik)=0 then suma:=suma+1;
for I:=k-1 downto 1
if mod (X[w,i],podzielnik)=0 then suma:=suma+1;
for i:=w-1 downto 1
if mod (X[i,1],podzielnik)=0 then suma:=suma+1
obwodtab:=suma
end;
program egzad4;
var I, j, suma : integer;
begin
writeln (`Proszę podawac elementy tablicy A');
readtabl(A);
write (`Ilosc elementow parzystych w tablicy A= `);
i:=obwodtab(A,2);
writeln(i);
writeln(`Proszę podawac elementy tablicy B');
readtabl(B);
write (`Ilosc elementow podzielnych przez 5 w tablicy B= `);
j:=obwodtab(B,5);
writeln (j);
end.
ZADANIA Z SERII EGZAMINACYJNEJ
program zad1;
var v,vo,a,tmp : real;
i, t : integer;
begin
writeln ('Podaj predkosc poczatkowa vo>0 oraz przyspieszenie a>0');
repeat
begin
readln (vo);
if vo<0 then writeln ('Musi byc wartosc dodatnia, sprobuj jeszcze raz');
end;
until vo>0;
writeln ('vo=',vo,' teraz podaj wartosc przyspieszenia');
repeat
begin
readln (a);
if a<0 then writeln ('Musi byc wartosc dodatnia, sprobuj jeszcze raz');
end;
until a>0;
writeln ('a=',a);
t:=0;
v:=vo+a*t;
tmp:=10*vo
while v<=tmp do
begin
writeln ('t=',t:4:2,' v=',v:4:2);
t:=t+1;
v:=v0+a*t;
end else
writeln ('Predkosc przekroczyla dziesieciokrotnie wartosc poczatkowa');
end.
---------
program zad2;
var i,j : integer;
type Atab = record
k:integer;
x:real;
end;
const n=50;
var A : array[1..n,1..n] of Atab
begin
writeln ('Wczytujemy tablice A[1..n,1..n]');
writeln ('Prosze podawac pary liczb: calkowita i rzeczywista');
for i:=1 to n
for j:=1 to n
readln (A[i,j].k);
readln (A[i,j].x);
writeln ('Drukuje liczby nad glowna przekatna, spelniajace podany warunek');
for i:=1 to n-1
if (A[i,i+1].k>A[i,i+1].x) writeln (A[i,i+1].k:4,' ',A[i,i+1].x:6:2);
writeln ('Koniec');
end.
--------
program zad3;
const n=30;
znak : string;
type Tabl=array [1..n] of string;
A, B : Tabl
plik : text
element : string;
function liczba_wyst(var : znak, napis : string):integer;
var n, temp : integer;
temp:=0
n:=length(napis);
for i:=1 to n
if (znak=napis[i]) then temp:=temp+1;
liczba_wyst:=temp;
end.
procedure wpisz_dane(var T : Tabl; var : znak : string, var : liczba:integer)
var plik : text;
element : string;
begin
assign (plik, 'dane.pas');
resest (plik);
for i:=1 to n
while not eof(plik) do
begin
readln (plik,element)
if (liczba_wyst(znak,element)<liczba) then
T[i]:=element;
close (plik);
end;
end
begin
znak:= 'a';
wpisz_dane (A,znak,2);
znak:='b';
wpisz_dane (B,znak,10);
end.
---------
{program zad4;}
unit tablica;
interface
const
w=20;
k=30;
type Table=array [1..w,1..k] of integer;
implementation
procedure czytaj_tab(var A:Tabl);
var i,j:integer;
begin
writeln ('Wczytuje tablice');
for i=1 to w
for j=1 to k
read (A[i,j]);
readln;
end;
procedure zamien_max(var A:Tabl, var kl: integer);
max1, max2, wsk1, wsk2: integer;
begin
max1:=A[1,kl];
wsk1:=1;
wsk2:=1;
for i=2 to w
if A[i,kl]>max1 then
begin
max1:=A[i,kl];
wsk1:=i;
end;
max2:=max1-1;
for i:=2 to w
if (A[i,kl]>max2 and A[i,kl]<max1) then
begin
max2:=A[i,kl];
wsk2:=i;
end;
A[wsk1,kl]:=max2;
A[wsk2,kl]:=max1;
end;
procedure drukuj_tabl(var A : Table; var i,j: integer);
for i=1 to w
for j:=1 to k
write (A[i,j]:4);
writeln;
end;
end
program zad4;
uses tabl
in 'tabl.pas'
const
w=20;
k=30;
type Tabl=array [1..w,1..k] of integer;
var A,B : Tabl;
czytaj_tab (A);
zmien_max (A,3);
czytaj_tab (B);
zmien_max(B,5);
drukuj_tabl(A,w,k);
drukuj_tabl(B,w,k);
end
ZADANIA DODATKOWE EGZAMINACYJNE
program zad1;
type tabl=record
autor: string;
tytul : string;
rok : integer;
end;
const n=100;
var ksiazki[1..n] of tabl;
zn : string;
plik : text;
temp : tabl;
wsk:integer;
procedure drukuj (var X:tabl, var n: integer);
var I : integer;
begin
for I:=1 to n
writeln (ksiazki[I].autor);
writeln (ksiazki[i].tytul);
writeln (ksiazki [i].rok)
writeln
end
begin
assign (plik,'ksiazki.pas');
reset (plik);
for I:=1 to n
begin
read (plik,zn);
ksiazki [I]:=zn;
end;
close (plik);
drukuj (ksiazki,n);
repeat
for i:=1 to n -1
begin
wsk:=0;
if (ksiazki[I].rok>ksiazki [I+1].rok) then
begin
temp:=ksiazki[i];
ksiazki[i]:=ksiazki [i+1];
ksiazki [i+1]:=temp;
wsk:=1;
end;
until wsk:=0;
drukuj (ksiazki,n);
end.
------
program zad5;
var masa, masa_min : real;
k:integer;
function podziel (var : masa,masa_min : real):integer;
begin
if masa>1 then
begin
k:=k+1;
masa:=masa/2;
podziel (masa, masa_min);
podziel:=k;
end;
end
begin
k:=0
writeln (`Proszę podac wartosc masy');
readln(masa);
writeln (`Masa minimalna wynosi 1');
writeln (`Liczba podzialow wyonosi', podziel(masa,1));
end.
TEST EGZAMINACYJNY
1. Która pętla repeat jest równoważna poniższej pętli while: while x>0 do begin writeln(x); readln(x) end
a) repeat if x>0 then begin writeln(x); readln(x) end until x<=0
b) repeat writeln(x); readln(x) until x<=0
c) repeat if x>0 then writeln(x); readln(x) until x<=0
2. Co się wydrukuje w efekcie wykonania następujących instrukcji: x:=5; repeat x:=x-1; write(x:2) until x>0
a) 5 4 3 2 1
b) 4 3 2 1
c) 4
3. Która z instrukcji jest prawidłowa, jeśli chcemy sprawdzić, czy zmienna jest_zero typu boolean nie jest prawdą:
a) if not jest_zero then...
b) if jest_zero=1 then...
c) if jest_zero = true then
4. Który wersja nie wydrukuje wartości x=0.1, 0.2, 0.3, 0.4...1.0 (x jest typu real, i typu integer)?
a) for x:=0.1 to 1.0 do writeln(x)
b) for i:=1 to 10 do writeln(i/10)
c) x:=0.1; repeat writeln(x); x:=x+0.1 until x>1
5. Jak sprawdzić, czy x (typu integer) jest podzielne przez 3:
a) if x mod 3=0 then...
b) if x mod 3=1 then...
c) if x mod 3 then...
6. Co wydrukuje następująca petla: for i:=1 to 2 do for x:=1 to 4 do begin write(x, ' '); writeln end;
a) liczby 1 2 3 4 pod sobą (każdą w nowym wierszu)
b) 2 wiersze, w każdym liczby 1 2 3 4 obok siebie
c) liczby 1 2 3 4 1 2 3 4 pod sobą (każdą w nowym wierszu)
7. Jeśli pisząc dane podam wartość zmiennej typu integer w postaci 5.0, to jaki to będzie błąd?
a) błąd kompilacji
b) błąd wykonania
c) to nie jest błąd, wolno tak napisać
8. Która instrukcja jest równoważna następującej: if x>0 then if x<10 then a:=5 else a:=1
a) if x>0 then begin if x<10 then a:=5 end else a:=1
b) if x>0 then begin if x<10 then a:=5 else a:=1 end
c) podana instrukcja jest niepoprawna
9. Jak wydrukować elementy głównej przekątnej tablicy A[1..n, 1..n] ?
a) for i:=1 to n do writeln (A[i, i]);
b) j:=i; for i:= 1 to n do writeln (A[i, j]);
c) for i:= 1 to n do writeln (A[i, 1]);
10. Który sposób nie nadaje się do tego, by określić nazwę pliku:
a) poprzez stałą tekstową, czyli pisząc ją w apostrofach
b) za pomocą zmiennej, którą możemy wczytać
c) za pomocą stałej, którą możemy wczytać
11. Które twierdzenie jest prawdziwe w odniesieniu do rekordów:?
a) każde pole rekordu może być dowolnego typu
b) każde z pól rekordu musi być innego typu
c) wszystkie pola rekordu muszą być tego samego typu
12. Chcemy napisać nagłówek funkcji, która oblicza sumę elementów w k-tej kolumnie tablicy X typu Tab, aby potem w wyrażeniu można było napisać suma (A, 5). Który zapis jest niepoprawny?
a) function suma(X: Tab; k: integer): real;
b) function suma(X: Tab; var k: integer): real;
c) function suma(var X: Tab; k: integer): real;
13. Jeśli chcemy, by jakaś zmienna była dostępna zarówno w programie, jak i w dołączonym do niego module, to gdzie musimy ją zadeklarować:
a) w programie
b) w module
c) wszystko jedno
14. Która konstrukcja jest poprawna, jeśli funkcja f(x) ma być rekurencyjna:
a) f:= f+1;
b) f(x):= f(x+1);
c) f:= f(x+1);
15. Na co wskazuje adres biezacy po wykonaniu nastepującej instrukcji (zmienna biezacy i pole next są tego samego typu wskaźnikowego):
while biezacy^.next <> nil do biezacy := biezacy^.next;
a) na ostatni element na liście
b) nie wskazuje na żaden element (bo adres biezacy jest równy nil)
c) na przedostatni element listy
-
Napisać program wczytujący pojedyncze znaki z klawiatury do momentu, aż ilość wprowadzonych spacji będzie większa od n (n - stała). Wyświetlić ilość wprowadzonych dużych liter. Program napisać bez użycia tablic.
Do tablicy A [ 1..w, 1..k ] of real (w,k -stałe) wczytać dane z pliku o nazwie podanej przez użytkownika (zakładamy, że w pliku jest odpowiednia ilość liczb i ma on prawidłową strukturę). Następnie do pliku 'wyniki.pas' zapisywać kolejne numery wierszy tablicy A i sumy elementów w tych wierszach, zaokrąglone do najbliższej wartości całkowitej.
Z plików o nazwach 'ta.pas' i 'tb.pas' wczytać rekordy o polach (x, y : integer, opis : string) do tablic odpowiednio A i B[1..n] (n - stała). W każdej tablicy dla każdego rekordu należy zmienić pole opis w zależności od pól x,y następująco:
na napis 'maleje', jeśli x>y
na napis 'rosnie' , jeśli x<y
na napis 'bez zmian', jeśli x=y
oraz wyświetlić liczbę par, dla których prawdziwy jest warunek x>y. Wyświetlić również tablicę przed i po zmianie. W programie należy wykorzystać:
procedurę wczytującą dane z pliku o jakiejś nazwie do jakiejś tablicy.
funkcję zmieniającą w jakiejś tablicy pole opis poszczególnych rekordów i zliczającą rekordy, dla których x>y.
procedurę wyświetlającą jakąś tablicę.
Napisać rekurencyjną funkcję wyświetlającą co trzeci wyraz oraz obliczającą (i zwracającą) sumę wszystkich elementów ciągu podanego równaniem:
Funkcja ma wyznaczać jakiś wyraz aktualny o jakimś kolejnym numerze na podstawie wyrazu poprzedniego i kończyć obliczanie sumy, gdy ten aktualny wyraz będzie mniejszy co do modułu od jakiejś wartości granicznej (określenie `jakiś' oznacza parametr funkcji). Uwaga - należy napisać jedynie funkcję, a nie cały program.
Napisać procedurę, która z listy składającej się z następujących elementów:
type Tadres = ^Telement;
Telement = record
A, B : integer;
nast : Tadres;
end;
i zaczynającej się pod jakimś adresem usuwa wszystkie elementy, dla których prawdziwy jest warunek A > B (określenie `jakiś' oznacza parametr procedury). Uwaga - należy napisać jedynie procedurę, a nie cały program.
------------------------------------------------------------------------------------------------------------------------------------------------
Wczytać liczbę dodatnią n (wymusić to na użytkowniku), a następnie wczytywać pojedyncze znaki z klawiatury do momentu aż wpisanych zostanie n kropek. Wyświetlić różnicę pomiędzy ilością wpisanych kropek a ilością wpisanych przecinków. Program napisać bez użycia tablic.
Do tablicy A [ 1..n, 1..n ] of real (n - stała) wczytać dane z pliku `dane.pas' (zakładamy że w pliku jest odpowiednia ilość liczb i ma on prawidłową strukturę). Następnie do pliku 'pierwsze.pas' zapisać pierwsze wyrazy z tych kolumn tablicy, w których suma elementów jest większa od 0.
Z 3 plików o nazwach podanych przez użytkownika wczytać rekordy o polach (x, y : real, opis : string) do tablic A, B, C [1..n] (n-stała). W każdej tablicy dla każdego rekordu należy zmienić pole opis następująco:
na napis 'należy' jeśli punkt o współrzędnych (x, y) należy do koła o promieniu r,
na napis 'nie należy' w pozostałych przypadkach (warunek na przynależność punktu do koła:
)
oraz wyświetlić liczbę punktów leżących poza okręgiem. Wyświetlić również tablice przed i po zmianie.
Wartość promienia r wynosi: 1 dla tablicy A, 2 dla B i 3 dla C.
W programie należy wykorzystać:
procedurę wczytującą nazwę pliku i wczytującą dane z pliku o tej nazwie do jakiejś tablicy.
funkcję zmieniającą w jakiejś tablicy pole opis poszczególnych rekordów i zliczającą punkty leżące poza okręgiem o jakimś promieniu.
procedurę wyświetlającą jakąś tablicę (określenie `jakiś' oznacza parametr podprogramu).
4. Napisać rekurencyjną funkcję wyświetlającą wszystkie wyrazy oraz obliczającą (i zwracającą) sumę elementów dodatnich ciągu
podanego równaniem:
.
Funkcja ma wyznaczać jakiś wyraz aktualny na podstawie wyrazu poprzedniego i kończyć obliczanie sumy, gdy ten aktualny wyraz będzie mniejszy co do modułu od jakiejś wartości granicznej (określenie `jakiś' oznacza parametr funkcji).
Uwaga - należy napisać jedynie funkcję, a nie cały program.
Napisać procedurę, która dla listy składającej się z następujących elementów:
type Tadres = ^Telement;
Telement = record
A, B : integer;
nast : Tadres;
end;
i zaczynającej się pod jakimś adresem wstawia na koniec listy element, którego pole A jest sumą wszystkich wcześniejszych A, a pole B jest iloczynem wszystkich wcześniejszych B. Uwaga - należy napisać jedynie procedurę, a nie cały program.
Rozwiązania zadań części pierwszej (a)
program z1a;
{$APPTYPE CONSOLE}
uses
SysUtils;
const n = 5;
var
znak : char;
l_spacji, l_duzych : integer;
begin
l_duzych := 0;
l_spacji := 0;
repeat
read(znak);
case znak of
'A'..'Z' : l_duzych := l_duzych + 1;
' ' : l_spacji := l_spacji + 1;
end;
until (l_spacji > n);
writeln('Wprowadzono ', l_duzych, ' duzych liter');
readln;
readln;
end.
-
program z2a;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
w = 3;
k = 4;
var
A : array[1..w, 1..k] of real;
plk : text;
nazwa : string;
i, j : integer;
sum : real;
begin
readln(nazwa);
assign(plk, nazwa);
reset(plk);
for i:=1 to w do
for j:= 1 to k do
readln(plk, a[i,j]);
close(plk);
assign(plk, 'wyniki.pas');
rewrite(plk);
for i:= 1 to w do begin
sum := 0;
for j := 1 to k do
sum := sum + A[i,j];
writeln(plk, i, ' : ', round(sum));
end;
close(plk);
end.
-
program z3a;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
n = 5;
type
TDane = record
x, y : integer;
opis : string;
end;
TDaneTbl = array[1..n] of TDane;
var
A, B : TDaneTbl;
procedure czytaj(var T : TDaneTbl; nazwa : string);
var
plk : text;
i : integer;
begin
assign(plk, nazwa);
reset(plk);
for i:=1 to n do
readln(plk, T[i].x, t[i].y, t[i].opis);
close(plk);
end;
procedure pokaz( T : TDaneTbl);
var
i : integer;
begin
for i:=1 to n do
writeln(T[i].x:4, ' ', t[i].y:4, ' ', t[i].opis);
end;
function zamien(var t : TDaneTbl) : integer;
var
i, licznik : integer;
begin
licznik := 0;
for i:=1 to n do
with t[i] do
if x > y then begin
licznik := licznik + 1;
opis := 'maleje';
end else
opis := 'rosnie';
zamien := licznik;
end;
begin
czytaj(A, 'ta.pas');
czytaj(B, 'tb.pas');
writeln('Tablica A przed: ');
pokaz(A);
writeln('Tablica B przed: ');
pokaz(B);
writeln('Elementow takich ze x>y jest w tablicy A ', zamien(A));
writeln('Elementow takich ze x>y jest w tablicy B ', zamien(B));
writeln('Tablica A po: ');
pokaz(A);
writeln('Tablica B po: ');
pokaz(B);
readln;
end.
-
program z4a;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
a0, da : real;
function licz(a : real; numer : integer; dokladnosc : real) : real;
begin
if abs(a) >= dokladnosc then begin
if numer mod 3 = 0 then
writeln(a:5:2);
licz := a + licz((a-1) / 2, numer + 1, dokladnosc);
end else
licz := 0;
end;
begin
write('Podaj a0 i dokladnosc: ');
readln(a0, da);
writeln('Suma ciagu: ', licz(a0, 0, da):5:2);
readln;
end.
-
program z5a;
{$APPTYPE CONSOLE}
uses
SysUtils;
type Tadres = ^Telement;
Telement = record
A, B : integer;
nast : Tadres;
end;
var
pierwszy, aktualny : Tadres;
i : integer;
procedure usun_zle(var glowa : Tadres);
var
akt, poprz : TAdres;
begin
akt := glowa;
poprz := nil;
while akt <> nil do begin
if akt^.A > akt^.B then begin
if poprz = nil then begin
glowa := glowa^.nast;
dispose(akt);
akt := glowa;
end else begin
poprz^.nast := akt^.nast;
dispose(akt);
akt := poprz^.nast;
end
end else begin
poprz := akt;
akt := akt^.nast;
end;
end;
end;
procedure pisz(elem : TAdres);
begin
if (elem <> nil) then begin
writeln(elem^.A, ' : ', elem^.B);
pisz(elem^.nast);
end;
end;
begin
new(pierwszy);
aktualny := pierwszy;
randomize;
for i := 1 to 9 do begin
aktualny^.A := random(10);
aktualny^.B := random(10);
new(aktualny^.nast);
aktualny := aktualny^.nast;
end;
aktualny^.A := random(10);
aktualny^.B := random(10);
aktualny^.nast := nil;
pisz(pierwszy);
usun_zle(pierwszy);
writeln('Po: ');
pisz(pierwszy);
readln;
end.
-