Zadanie. Przypuśćmy, że dana jest tablica jednowymiarowa zawierająca N elementów.

Algorytm rekurencyjny wypisujący elementy tej tablicy, zaczynając od pierwszego

można zapisać następująco:

Jeżeli tablica jest niepusta, to

Wypisz pierwszy element,

Wypisz tablicę zawierającą pozostałe N 1 elementy.

Napisz procedurę Wypisz_Tablice realizującą ten algorytm w przypadku, gdy elementy

tablicy są typu Integer, przy czym parametr formalny rodzaju wejściowego ma

być typu:

type Integer_Array is array (Integer range <>) of Integer;

i przy realizacji algorytmu wolno korzystać jedynie z atrybutów typów tablicowych.

Rozwiązanie

PROCEDURE Wypisz_Tablice (

T : IN OUT Integer_Array) IS

BEGIN

IF T'Length=1 THEN

Put(T(1));

ELSE

Put(T(1));

New_Line;

DECLARE

T2 : Integer_Array (1 .. T'Length - 1);

BEGIN

FOR I IN 1..T2'Length LOOP

T2(I):=T(I+1);

END LOOP;
Wypisz_Tablice(T2);

END;

END IF;

END Wypisz_Tablice;

Zadanie. Przypuśćmy, że dana jest tablica jednowymiarowa zawierająca N elementów.

Algorytm rekurencyjny wypisujący elementy tej tablicy zaczynając od ostatniego

można zapisać następująco:

Jeżeli tablica jest niepusta, to

Wypisz ostatni element,

Wypisz tablicę zawierającą pozostałe N 1 elementy.

Napisz procedurę Wypisz_Tablice_Od_Konca realizującą ten algorytm w przypadku,

gdy elementy tablicy są typu Integer, przy czym parametr formalny rodzaju wejściowego

ma być typu:

type Integer_Array is array (Integer range <>) of Integer;

i przy realizacji algorytmu wolno korzystać jedynie z atrybutów typów tablicowych.

Rozwiązanie

PROCEDURE Wypisz_Tablice_od_Konca (

T : IN OUT Integer_Array) IS

BEGIN

IF T'Length=1 THEN

Put(T(T'Last));

ELSE

Put(T(T'Last));

New_Line;

DECLARE

T2 : Integer_Array (1 .. T'Length - 1);

BEGIN

FOR I IN 1..T2'Length LOOP

T2(I):=T(I);

END LOOP;
Wypisz_Tablice_od_Konca(T2);

END;

END IF;

END Wypisz_Tablice_od_Konca;

Zadanie. Przypuśćmy, że mamy wyznaczyć iloczyn liczb M i N P i nie możemy

skorzystać z tabliczki mnożenia, natomiast możemy wyłącznie stosować dodawanie. Algorytm

rekurencyjny wyznaczający M N jest następujący:

Jeżeli N = 1, to M N = M ,

w przeciwnym przypadku M N = M + M (N 1).

Napisać funkcję Mnozenie, która realizuje ten algorytm.

Rozwiązanie

FUNCTION Mnozenie (

M : Integer;

N : Positive)

RETURN Integer IS

M1: Integer :=M ;

N1: Positive :=N;

BEGIN

WHILE N1/=1 LOOP

M1:=M1+M;

N1:=N1-1;

END LOOP;

RETURN M1;

END Mnozenie;

Zadanie. Mamy dane deklaracje:

type Wsk_Integer is access Integer;

Wsk1, Wsk2 : Wsk_Integer;

oraz instrukcje

Wsk1 := new Integer'(0);

Wsk2 := new Integer'(100);

Put (Wsk1.All, 3); New_Line;

Put (Wsk2.All, 3); New_Line;

Wsk2.All := Wsk1.All;

Put (Wsk1.All, 3); New_Line;

Put (Wsk2.All, 3); New_Line;

Wsk1.All := 5;

Wsk2.All := 25;

Put (Wsk1.All, 3); New_Line;

Put (Wsk2.All, 3); New_Line;

Wsk1 := Wsk2;

Put (Wsk1.All, 3); New_Line;

Put (Wsk2.All, 3); New_Line;

Podaj wszystkie wartości wypisywane przez wywołania procedury Put.

Rozwiązanie

0  100 0 0 5 25 25 25

Zadanie. Przypuśćmy, że chcemy wyznaczać wartości dowolnych, dobrze określonych

odwzorowań F:

W tym celu piszemy deklaracje

type Wektor_2 is array (1 .. 2) of Float;

type Odwzorowanie is access function (X : in Wektor_2) return Wektor_2;

Napisać funkcję Obraz, której parametrami są argument X typu Wektor_2 i funkcja

typu Odwzorowanie. Funkcja ma wyznaczać wektor Odwzorowanie(X). Następnie

napisać funkcje Przeciwny i Obrocony_O_90 obliczające odpowiednio wektor przeciwny

do argumentu tej pierwszej funkcji i wektor obrócony o kąt o 90 do argumentu drugiej

funkcji, takie, że mogą być parametrami aktualnymi funkcji Obraz. Mając deklaracje

V : Wektor_2 := (1.0, 1.0);

W : Wektor_2;

napisać instrukcje przypisujące zmiennej W wartości obliczone przez funkcję Obraz w

przypadku, gdy jej parametrami aktualnymi są V i funkcje Przeciwny i

Obrocony_O_90.

Rozwiązanie


TYPE Wektor_2 IS ARRAY (1 .. 2) OF Float;

TYPE Odwzorowanie IS ACCESS FUNCTION

(X : IN Wektor_2) RETURN Wektor_2;

FUNCTION Przeciwny (

X : IN Wektor_2)

RETURN Wektor_2 IS

Y : Wektor_2;

BEGIN

Y(1):=-X(1);

Y(2):=-X(2);

RETURN Y;

END Przeciwny;

FUNCTION Obrocony_O_90 (

X : IN Wektor_2)

RETURN Wektor_2 IS

Y : Wektor_2;

BEGIN

Y(1):=-X(2);

Y(2):=X(1);

RETURN Y;

END Obrocony_O_90;

FUNCTION Obraz (

X : IN Wektor_2;

Funkcja : IN Odwzorowanie)

RETURN Wektor_2 IS

Y : Wektor_2;

BEGIN

Y:=Funkcja(X);

RETURN Y;

END Obraz;

Funkcja : Odwzorowanie;

V : Wektor_2 := (1.0, 1.0);

Y : Wektor_2;

BEGIN

Funkcja:=Przeciwny'ACCESS;

Y:=Obraz(V,Funkcja);

Put(Y(1));

New_Line;

PUT(Y(2));

New_line;

Funkcja:=Obrocony_O_90'ACCESS;

Y:=Obraz(V,Funkcja);

Put(Y(1));

New_Line;

PUT(Y(2);


Zadanie. Napisać funkcje First_Component i Second_Component obliczające odpowiednio

pierwszą i drugą składową wektora typu Wektor_2D. Założyć przy tym, że

deklaracja tego typu ma postać

type Wektor_2D is private;

:

private

type Wektor_2D is record

First : Float;

Second : Float;

end record;

Rozwiązanie

FUNCTION First_Component (

X : Wektor_2d)

RETURN Float IS

BEGIN

RETURN X.First;

END First_Component;

FUNCTION SECOND_Component (

X : Wektor_2d)

RETURN Float IS

BEGIN

RETURN X.Second;

END SECOND_Component;

Zadanie. Przyjmując definicję typu Wektor_2D jak wyżej napisać funkcje

Konstruktor_2D, "+", "*", "*" służące odpowiednio do: konstrukcji wektora z jego

składowych, obliczania sumy dwóch wektorów i obliczania iloczynu skalara przez wektor i

wektora przez skalar rzeczywisty.

Rozwiązanie


FUNCTION "+" (

X,

Y : Wektor_2d)

RETURN Wektor_2d IS

V : Wektor_2d;

BEGIN

V.First:=X.First+Y.First;

V.Second:=X.Second+Y.Second;

RETURN V;

END "+";

FUNCTION "*" (

A : Float;

X : Wektor_2d)

RETURN Wektor_2d IS

V : Wektor_2d;

BEGIN

V.First:=A*X.First;

V.Second:=A*X.Second;

RETURN V;

END "*";

FUNCTION "*" (

X : Wektor_2d;

A : Float)

RETURN Wektor_2d IS

BEGIN

RETURN A*X;

END "*";

PROCEDURE Czytaj_Wektor_2d (

X : OUT Wektor_2d) IS

BEGIN

Ada.Float_Text_Io.Get (X.First);
New_Line;

Ada.Float_Text_Io.Get (X.Second);

END Czytaj_Wektor_2d;


Zadanie. Przyjmując definicję typu Wektor_2D jak wyżej napisać pełne deklaracje

stałych Zero, Wersor_1 i Wersor_2, które reprezentują odpowiednio wektory:

0 = (0,0) , 1 e = (1,0) , 2 e = (0,1)

Rozwiązanie

PRIVATE

TYPE Wektor_2D IS

RECORD

First : Float;

Second : Float;

END RECORD;

Zero: CONSTANT Wektor_2D := (0.0,0.0);

E1: CONSTANT Wektor_2D := (1.0,0.0);

E2: CONSTANT Wektor_2D := (0.0,1.0);

Zadanie. Mamy deklaracje

generic

type Typ_Danych is private;

procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych);

...

procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych) is

Temp: Typ_Danych;

begin

Temp := W1;

W1 := W2;

W2 := Temp;

end Wymien_Ogolnie;Czy typ Typ_Danych zadeklarowany w sekcji ogólnej jako

private, może być typem prywatnym ograniczonym - limited private? Uzasadnij

odpowiedź.

Rozwiązanie

Nie może być gdyż typ limited private nie ma zdefiniowanego działania „:=”

Zadanie. Mamy deklaracje

generic

type Typ_Danych is private;

procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych);

Napisać konkretyzację procedury Wymien_Ogolnie w przypadku typu standardowego

Character.

Rozwiązanie

Zad 16.2

PROCEDURE Wymien_Integer IS

NEW Wymien_Ogolnie (Typ_Danych => Character);

Zadanie. Mamy deklaracje

generic

type Typ_Danych is private;

with function Wiekszy(L, R : Typ_Danych) return Boolean;

function Maksimum (W1, W2 : Typ_Danych) return Typ_Danych;Napisać

konkretyzację funkcji Maksimum w przypadku typu standardowego Character.

Rozwiązanie

FUNCTION Maksimum_Character IS

NEW Maksimum (

Typ_Danych => Character,

Wiekszy => ">");