Paket (2) nautisk_mil : constant Float := * foot; ångström : constant Float := 10.0E-10; mile : constant Float := 5280.

Full text

(1)

Paket (1) Ett paket med en praktisk uppsättning konstanter: package LängdKonstanter is -- Alla värden uttryckta i meter: inch: constant Float := 0.0254; foot: constant Float := 12.0 * inch; mile: constant Float := 5280.0 * foot; fermi: constant Float := 10.0E-15; ångström : constant Float := 10.0E-10; nautisk_mil : constant Float := 6076.0 * foot; -- au : Astronomisk enhet au: constant Float := 1.4960E+11; ljusår: constant Float := 9.4607E+15; end LängdKonstanter;

Paket (2)

with LängdKonstanter;

use LängdKonstanter;

procedure Main is

längd : Float; -- i meter.

begin ...

Put(längd * foot, 0, 3, 0);

Put("fot."); New_Line;

end Main;

___________________________

procedure Main is

inch : constant Float := 0.0254;

foot : constant Float := 12.0 * inch;

mile : constant Float := 5280.0 ...

fermi : constant Float := 10.0E-15;

ångström : constant Float := 10.0E-10;

nautisk_mil : constant Float := 6076.0 ...

au : constant Float := 1.4960E+11;

ljusår : constant Float := 9.4607E+15;

längd : Float; -- i meter.

begin ...

Put(längd * foot, 0, 3, 0);

Put("fot."); New_Line;

end Main;

Ett huvudprogram som in- fogar detta paket:

Det fungerar som om det från början hade stått ...

Paket (3)

Ett paket som definierar några typer och konstanter:

package TwoDimTypes is type Point is record

x, y: Float;

end record;

type Circle is record center : Point;

radius : Float;

end record;

type Rectangle is record upper_left : Point;

width : Float;

height : Float;

end record;

Origo : constant Point :=

(0.0, 0.0);

UnitCircle : constant Circle :=

(Origo, 1.0);

end TwoDimTypes;

Paket (4)

Ett användande huvudprogram. Det görwithpå paketet, men inteuse!

with TwoDimTypes;

procedure ppp is

P1, P2 : TwoDimTypes.Point;

Rect : TwoDimTypes.Rectangle;

C1 : TwoDimTypes.Circle :=

TwoDimTypes.UnitCircle;

begin ...

end ppp;

Paketet tas med, men dess innehåll är inte direkt synligt!

Man måste då angepaketnamn. före varje namn ur paketet!

use ser till att paketet ‘öppnas’ så att alla dess beståndsdelar blir direkt synliga.

Skrivsättetpaketnamn.paketkomponentär nödvändigt bara när olika paket innehåller komponenter med samma namn!

(2)

package DatePack is type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); subtype DayNr is integer range 1 .. 31; subtype MonthNr is integer range 1 .. 12; type Date is record Day : DayNr; Month : MonthNr; Year : Natural; end record; (fortsättning följer)

Paket (5) Ett annat paket DatePack som definierar såväl typer och konstanter somsubrutiner! Paketet skall då bestå avtvåfiler. Först paketetsspecifikation: Paket (6) Fortsättning: I paketspecifikationen kan bara subrutiners specifikation förekomma! ... StartOfWeek : constant Weekday := Weekday’first; StartOf2000 : constant Date := (1, 1, 2000); function MakeDate(the_day : DayNr; the_month : MonthNr; the_year : Natural) return Date; procedure GetNextDate(the_date : in out Date); procedure GetNextWeekday(the_weekday : in out Weekday); function IsLeapyear(the_year : Natural) return Boolean; function ToString(the_date : Date) return String; end DatePack;

package body DatePack is function MakeDate(the_day : DayNr; the_month : MonthNr; the_year : Natural) return Date is begin return (the_day, the_month, the_year); end MakeDate; procedure GetNextDate(the_date : in out Date) is begin ... end GetNextDate; (fortsättning följer)

Paket (7) Detta är bodyn (’kroppen’) till paketet DatePack. Här finns subrutinerna i sin fullständighet! Filen skall ha namnetpaketnamn.adb. ... procedure GetNextWeekday(the_weekday : in out Weekday) is begin ... end GetNextWeekday; function IsLeapyear(the_year : Natural) return Boolean is begin ... end IsLeapYear; (fortsättning följer)Paket (8) Fortsättninen av DatePack’s body:

(3)

... function ToString(n : Natural) return String is S : String := Integer’Image(n); begin return S(2 .. S’Last); end ToString; function ToString(the_date : Date) return String is begin return ToString(the_date.Day) & ’/’ & ToString(the_date.Month) & ’ ’ & ToString(the_date.Year); end ToString; end DatePack;

Paket (9) Slutet av DatePack’s body. Den första funktionen ToString finnsinte i paketets specifikation. Den är då användbar (synlig) bara i denna paketbody! package DatePack2 is type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); subtype DayNr is integer range 1 .. 31; subtype MonthNr is integer range 1 .. 12; type Date is private; --Bara typens namn !! StartOfWeek : constant Weekday := Weekday’first; StartOf2000 : constant Date := (1, 1, 2000); function MakeDate(the_day : DayNr; the_month : MonthNr; the_year : Natural) return Date; procedure GetNextDate(the_date : in out Date); procedure GetNextWeekday(the_weekday : in out Weekday); (fortsättning följer)Paket (10) En ny variant: Detta paket har även enprivat del i specifikationen:

... function IsLeapyear(the_year : Natural) return Boolean; function ToString(the_date : Date) return String; function DayOf(the_date : Date) return DayNr; function MonthOf(the_date : Date) return MonthNr; function YearOf(the_date : Date) return Natural; private type Date is record Day : DayNr; Month : MonthNr; Year : Natural; end record; end DatePack2;

Paket (11) Den privata delen av DatePack2gömmer datatypens utseende för användande program:

Paket (12)

Synlighet mellan paket och användande program.

Användande program

Paketets specifikation

Paketets body publik del

privat del

Vet alltså bara om vad som finns i paketets publika del!

Inget del av paketet vet alltså något om vad som finns i det användande programmet!

(4)

Paket (13) - deklaration av generiskt paket:

generic

type ElementTyp is private;

package KöPack is type Kö is private;

procedure Köa(E : ElementTyp;

K : in out Kö);

procedure Hämta(K : in out Kö;

E : in out ElementTyp;

ÄrTom : in out Boolean);

...

private

Max : constant Integer := 1000;

type IndexTyp is 1 .. Max;

type Lista is array(IndexTyp) of ElementTyp;

type Kö is record

Sista : Integer := 0;

Element : Lista;

end record;

end KöPack;

En body också, förstås. Men den visas inte här.

KöPack är ett sk generiskt paket, ett ofullständigt och i sig oanvänd- bart paket, som fungerar som en mall för att skapa ’riktiga’ paket.

Typnamnet ElementTyp ska betraktas som en slags parameter.

Paket (14) - Instatiering av generiskt paket:

ElementTyp ElementTyp

ElementTyp

KöPack är bara en mall för hur andra paket ska skapas - det kan inte användas som det är.

TypnamnetElementTyp är bara ett ‘parameternamn’ och måste ersättas med ett verkligt typnamn i en kopia av mallen.

Det gör man med t ex dessa konstruktioner, sk instantieringar:

package IntKöande is new KöPack(Integer);

package DateKöande is new KöPack(Date);

Man får då två nya, verkliga paket, med namnenIntKöande respDateKöande, därElementTyphar ersatts av de verkliga typnamnenInteger respDate.

Paketmallen KöPack

Date Date

Date Det verkliga paketet DateKöande Integer

Integer

Integer Det verkliga paketet IntKöande

De här paketen är vad man kallar instanser avKöPackoch de kan nu användas som ‘vanliga’ paket.

Paket (15) - Instantiering av generiskt paket, exempel:

with KöPack;

procedure MyMain is

type Date is ... -- enligt förut, t ex -- Instanser av mallen anpassade för -- Integers resp Dates skapas:

package IntKöande is new KöPack(Integer);

package DateKöande is new KöPack(Date);

use IntKöande, DateKöande;

-- En kövariabel för vardera typen. Eftersom -- typnamnet Kö finns i båda paketen måste man -- ange vilket pakets Kö som avses:

INTKÖ : IntKöande.Kö;

DATEKÖ : DateKöande.Kö;

D : Date := (8, 2, 2006); -- Ett datum;

begin ...

-- Nu kan Date- och Integer-värden köas!

-- Typen på parametrarna avgör vilken -- av de två Köa-procedurerna som väljs:

Köa(12, INTKÖ);

Köa(D, DATEKÖ);

...

Paket (16) - Sammanfattning Ett paket ...

• innehåller helt enkelt en samling deklarationer.

• finns i en eller två egna filer för sig. Filens/filernas ‘förnamn’

skall vara detsamma som paketets namn.

• består av två filer om den innehåller subrutiner, en enda fil om den inte innehåller subrutiner:

- i paketets specfikationsfil (.ads) finns vid behov specifika- tioner (enbart!) av subrutiner, plus andra former av deklara- tioner. Denna fil finns alltid.

- i paketets body-fil (.adb) skall subrutinerna från specifika- tionsfilen finnas i fullständig form.

- bodyfilen kan dessutom innehålla andra deklarationer.

• kan inkluderas i ett annat program med with, och dess synliga innehåll kan sedan göras direkt åtkomligt med use.

• vet aldrig någonting om det program i vilket det inkluderas.

• kan också ha en privat - osynlig - del i specifikationen.

• kan dessutom vara generiskt.

Det program som inkluderar ett paket ...

• vet ingenting om innehållet i paketets body. Det är alltid

‘osynligt’.

• vet heller inget om innehållet i paketspecifikationens eventu- ella privata del.

• kan alltså bara utnyttja det som finns i paketspecifikationens synliga del.

• måste skapa en ‘konkret kopia’ (en instans) om paketet är ge- neriskt. Endast en konkret paketinstans kan use:as.

(5)

Typen String (1)

Den är en sk unconstrained array (array med obestämda index- gränser)! Tänkt deklaration (om den inte redan funnes!):

type String is array(Positive range <>) of Character;

Strängliteraler:

"Summa: " har (den underförstådda) typen array(1 .. 7) of Character;

Strängvariabler:

QM : String := "? ";

kan sedan bara ges nya strängvärden med exakt 2 tecken.

S1 : String(1 .. 12);

kan bara ges strängvärden med exakt 12 tecken:

S1 := "Pettersson ";

Subtyper:

subtype NameType is String(1 .. 30);

subtype ThreeLetter is String(1 .. 3);

Typen String (2) - operationer S2 : String (1 .. 11);

Ch : Character;

T3 : ThreeLetter;

Konkatenering (hopslagning) med operatorn&

S2 := "Hej och " & "hå!";

put("Vanligaste bokstaven är " & Ch);

’Slicing’ - delföljd av tecken:

put(S2(index .. index + 4));

T3 := S2(3 .. 5);

T3 := S2(S2’last - 2 .. s2’last);

S2 := S2(2 .. s2’last) & s2(1);

S2(5 .. 7) := " & ";

Alla jämförelser (=,/=,<, ...) kan också användas!

NB! En generalisering:

Konkatenering, slicing och jämförelser kan användas på alla en- dimensionella arraytyper med element av enkel typ!

Typen String (3)- subrutiner

Variabler, konstanter, subtyper måste ha fixerad längd!

Men parametrar till subrutiner, värden av funktioner tillåts vara av den obegränsade typen String !

function Clip(s : String) return String is begin

for index in reverse s’range loop if s(index) /= ’ ’ then

return s(1 .. index);

end if;

end loop;

return "";

end Clip;

Kan nu anropas med strängar av olika längd:

... Clip("Hejsan ") ... Clip("OK") ...

Värdena har ’oförutsägbar’ längd - icke fix.

Men tilldelning av värdet till en variabel funkar bara om läng- den av värdet stämmer med variabelns deklarerade längd!

Text := Clip("Hejsan "); -- tveksamt!

Däremot fungerar alltid t ex Put(Clip("Hejsan "));

eftersom Put’s parameter också är en obegränsad String!

Figur

Updating...

Referenser

Updating...

Relaterade ämnen :