Denna sammanfattning riktar sig till dig som behöver fräscha upp dina kunskaper i Ada, men inte vill plöja igenom en stor och tjock bok som innehåller onödigt mycket information. Dokumentet är i princip en utökad lathund med väl valda och kommenterade exempel. Möjligen kan sammanfattningen vara nyttig även för folk som vill lära sig Ada från början och som har ett annat språk i bakhuvudet.
Denna sammanfattning är till sin natur kortfattad och tar inte upp allt som finns i Ada, utan bara så mycket som brukar ingå i kurser på IDA (Institutionen för datavetenskap). Du kan välja att läsa alla avsnitt i en följd, eller leta upp svar på konkreta problem med hjälp av innehållsförteckningen nedan.
Innan vi börjar gå in på hur Ada fungerar ska vi diskutera några praktiska detaljer som vad källkodsfilerna ska heta och hur man kompilerar och kör dem.
hello.adb
|
|
Exempel 1: Ett enkelt program |
Exemplen i det här dokumentet kommer se ut som exempel 1 ovan. Överst står namnet på filen och därunder följer innehållet (dvs själva programmet). Från det här exemplet kan vi lära oss följande saker:
.adb
. Dessutom
bör filen heta samma sak som huvudproceduren i filen, dvs i det här fallet
Hello
.with
, use
,
procedure
, ...) medan namn på procedurer, variabler och
paket skrivs med inledande versal och understreck mellan orden
(Hello
, Put_Line
, ...). Detta är bara konventioner,
men de kommer hjälpa dig att läsa koden.
|
Exempel 1b: Kompilera och köra program |
Exempel 1b ovan visar hur du kompilerar och kör dina program när du
sitter vid en arbetsstation på IDA. Du kompilerar Ada-källkoden i ett
skalfönster med hjälp av kommandot gnatmake
. Om allt går
som det ska kommer du att se tre rader som talar om vad kompilatorn gör.
Därefter kan du köra programmet enligt ovan.
Om du får felmeddelanden som talar om att kompilatorn inte hittas
måste du installera den med kommandot module add prog/gnat
.
Mer information om installationen av Ada på IDA finns på Tommy Olssons sida Ada på IDA.
exempel2.adb
|
|
Exempel 2: Summera två tal |
Förhoppningsvis inser du att programmet i exempel 2 ovan kommer läsa in två tal från användaren, summera dessa och skriva ut resultatet på skärmen. Strukturen på Ada-programmet är från början till slut följande:
with
och use
som
talar om vilka paket som ska användas i programmet (mer om detta
nedan).begin
finns deklarationer.
Här talar man om namn och typ på de variabler man vill använda. Man kan
också definiera ytterligare procedurer (s.k. underprocedurer) och funktioner,
samt egna typer och paket.begin
och end
.De flesta av funktionerna i exempel 3 finns i olika paket. Den enda
rad i huvudprocedurens kropp som klarar sig utan paket är raden
C := A+B;
. Övriga rader är beroende av de paket som
inkluderas på de två första raderna. Vad är då skillnaden mellan
with
och use
?
with
talar man om för kompilatorn vilka paket man
tänker använda sig av i programmet. På det sättet kan kompilatorn leta
reda på proceduren Put
och ta med den i det färdiga
programmet.use
skulle vi bli tvugna att i den
andra raden skriva Ada.Integer_Text_IO.Get(A);
för att tala
om i vilket paket proceduren Get
finns. Genom att använda
use
talar vi alltså inte bara om vilka paket vi vill använda,
utan också vilka paket vi vill kunna referera till på det kortare sättet.Paketet Ada.Text_IO
innehåller funktioner och procedurer
för att läsa och skriva text. I exempel 3 är procedurerna som finns
på huvudprocedurens rad 1, 3, 6 och 8 hämtade från Ada.Text_IO
.
Paketet Ada.Integer_Text_IO
används för att läsa och skriva
heltal. Raderna med Get
samt raden Put(C);
anropar procedurer i det paketet.
Titta på de två sista Put
-satserna i exempel 3. De kommer
från olika paket men har samma namn. Detta fenomen kallas överlagring
och innebär att två olika procedurer har samma namn. Vi kan skilja dem
åt dels genom att de ligger i olika paket, dels genom att deras argument
är av olika typ. Först kommer en Put
-sats som skriver ut
en textsträng, därefter en som skriver ut ett heltal. (Vi kan alltså inte
skriva ut både ledtexten och summan med samma Put
-sats.)
Ofta vill man dela upp sitt program i flera olika procedurer och
funktioner. Oavsett hur man gör måste det finnas en huvudprocedure med
samma namn som filen. Underprogram deklareras på samma ställe som variabler
m.m., dvs efter raden procedure ... is
men innan raden
begin
.
Underprogrammen följer samma struktur som huvudprogrammet och kan i sin tur innehålla deklarationer av variabler och underprogram. Underprogram behöver inte bara vara procedurer utan kan också vara funktioner, dvs i princip procedurer som returnerar ett värde. Här följer två exempel på förstarader från underprogram:
procedure Proc(A : in Integer; B : out Integer; C : in out Integer) is ... function Func(X : in Integer) return Integer is ...
Med hjälp av markeringarna in
, out
och
in out
anges dataflödesriktningen för argumentet.
Det innebär helt enkelt att argumentet A
endast är indata
till Proc
och inte får byta värde. B
är endast
utdata från Proc
och dess initialvärde är odefinierat. Vid
anropet till Proc
måste det dessutom stå en variabel på andra
positionen så att utdatat kan lagras någonstans. C
är både
in- och utdata.
Exempel på underprogram finns bland annat i exempel 8 nedan.
Om man vill kan man lägga underprogrammen i separata filer, men då finns
det några regler man måste komma ihåg. Precis som för huvudprogrammet
måste filens namn överensstämma med procedurnamnet, dock med undantaget
att filnamnet måste bestå av enbart små bokstäver. Vidare måste man
i varje underprogramsfil ange with
och use
,
eftersom varje fil kompileras för sig. Slutligen inkluderar man
underprogrammen i huvudprogrammet genom att göra with
(naturligtvis utan .adb
på slutet), dock inte
use
.
Med det långa ordet programflödeskontroll menar vi olika sätt att få programmet att göra olika saker. När programmet i exempel 3 körs kommer de olika satserna i källkoden att exekveras (köras) en i taget tills programmet är slut. Ibland vill man dock se till att körningen av programmet tar en annan väg. Detta sker i princip på två olika sätt: repetition eller selektion. Att repetera innebär förstås att man gör någonting flera gånger. Att selektera innebär att välja ut en av flera möjliga saker att göra. Vi ska nedan gå igenom dessa två tekniker och hur de ser ut i Ada.
exempel3.adb
|
|
Exempel 3: Repetition med loop-satser |
Det finns i princip tre olika sätt att upprepa saker och ting i Ada och dessa finns exemplifierade i exempel 3.
for
-satsen används när man i förväg vet exakt hur många
gånger man vill upprepa något. Fördelen med for
-satsen är
att den tar hand om det mesta själv. Repetitionsvariabeln I
behöver inte deklareras och den räknas automatiskt upp med ett i slutet
av loopen.while
-loopen används när man vill upprepa något tills
ett bestämt villkor är uppfyllt. Den skiljer sig från for
-loopen
genom att man måste (a) deklarera repetitionsvariabeln, (b) ge
repetitionsvariabeln ett initialvärde och (c) räkna upp repetitionsvariabeln
själv.exit
.
exempel4.adb
|
|
Exempel 4: Selektion med if
|
Den absolut vanligaste selektionssatsen är if
-satsen.
I exempel 4 testar vi om ett tal är negativt, noll eller positivt.
En if
-sats kan byggas ihop på många olika sätt, så länge
den börjar med if
och avslutas med end if
.
Delarna elsif
och else
är valfria.
exempel5.adb
|
|
Exempel 5: Selektion med case
|
En bättre metod när man har många olika val är att använda sig av
en case
-sats.
Ada har flera olika typer, men de fem viktigaste är följande:
Integer
lagrar heltal, positiva och negativaFloat
lagrar flyttal, dvs decimaltalBooolean
lagrar sanningsvärde, dvs antingen True
eller False
Character
lagrar enskilda teckenString
lagrar strängar, dvs sekvenser av tecken
exempel6.adb
|
|
Exempel 6: Grundläggande typer |
Exempel 6 visar hur man deklararer och initierar variabler av de fem viktigaste datatyperna. Dessutom visar vi hur man kan använda dem. Här kan vi lära oss följande:
Float(I)
vilket innebär att heltalet I
först omvanlas till ett flyttal och därefter summeras med F
.
Detta förfarande kallas explicit typkonvertering.5.0
om man vill lagra heltalet 5 i
ett flyttal.
|
Exempel 6b: Utmatning |
Information om hur man kan justera utmatningen av flyttal finns i avsnitt 6.
utmatning.adb
|
|
Exempel 7: Utmatning av tal |
Exempel 7 visar olika sätt för att mata ut heltal och flyttal. Resultatet av detta illustreras i exempel 7b.
|
Exempel 7b: Resultat av utmatning |
Som vi ser av testkörningen i exempel 7b så kommer heltal att skrivas ut
på ett ganska klumpigt sätt om vi inte anger något annat. Standardmässigt
skrivs heltalen ut med exakt tio tecken där själva talet är högerjusterat
om det skulle bestå av färre än tio siffor. Detta är i praktiken ganska
oanvändbart och därför använder vi det sätt som anges på andra raden i
exempel 7. Med hjälp av Width
kan vi ange hur många tecken
vi vill att utskriften ska använda. Genom att här ange 0 talar vi om att
heltalet ska skrivas ut med exakt så många siffror som behövs.
När det gäller flyttal är det lite mer komplicerat. På fjärde raden i
testkörningen ser vi att det standardmässiga sättet att skriva ut flyttal
på är att ange det som ett tal i intervallet -9 till 9 samt med exponent.
Om vi vill justera detta måste vi använda oss av Fore
,
Aft
och Exp
som anger hur många siffror som
ska visas före respektive efter decimalpunkten, samt hur många siffror som
ska användas för att visa exponenten. Om vi sätter Exp
till 0
tvingar vi fram utskrift utan exponent.
I exempel 7 finns en New_Line
-sats direkt efter
varje Put
. Detta är helt i sin ordning, ty i Ada kan man
mycket väl ha flera satser på samma rad så länge de avslutas med
semikolon.
Mer information om in- och utmatning av strängar finns i avsnitt 8.
En array (sv. fält) är en datastruktur som består av flera enheter av samma typ. Man kan jämföra med vektorer och matriser från matematiken. Ada har flera finesser som gör det lätt att använda arrayer.
array_demo.adb
|
|
Exempel 8: Arrayer |
I början av exempel 8 ovan ser vi en enkel deklaration av en
array A
. Den består av tre heltal som benämns med indexen
1, 2 och 3. Oftast är dock detta sätt att deklarera arrayer inte särskilt
bra. Om vi t.ex. vill skicka arrayen till en procedure för vidare bearbetning
måste vi först skapa en egen array-typ. Det gör vi på nästa rad.
Precis innan huvudprogrammet deklareras en array B
av vår
hemmagjorda array-typ My_Array
. Här ser vi också ett sätt
att placera data i arrayen. Ett annat sätt ser vi på första raden i
huvudprogrammet. B(2)
betecknar position 2 i arrayen
B
.
I underprogrammet Print_Array
ser vi fyra olika
attribut som är användbara när man arbetar med arrayer. Storleken
på arrayen A
(inte samma som i huvudprogrammet) kan härledas
ur attributen:
A'First
ger värdet 1, eftersom arrayens lägsta index
är 1.A'Last
ger värdet 5, eftersom arrayens lägsta index
är 5.A'Length
ger värdet 5, eftersom arrayen har totalt 5
positioner.A'Range
ger värdet 1..5, eftersom det var det område som
angavs när typen deklarerades. A'Range
kan t.ex. ges som
argument till en for
-sats för att på ett smidigt sätt gå
igenom hela arrayen.
array_demo2.adb
|
|
Exempel 9: Flerdimensionella arrayer |
Det finns två sätt att åstadkomma flerdimensionella arrayer. I exempel 9 visar vi dessa två olika sätt genom att implementera spelplaner om 3 x 3 rutor för Tic-tac-toe.
Åtkomsten av enskilda positioner i arrayerna blir också olika beroende
på vilket sätt man väljer. Med det första sättet måste vi skriva
A(1)(1)
medan vi för det andra sättet skriver
B(1,1)
.
Varför vill man då göra på det första sättet med arrayer av arrrayer? Ibland kanske man vill behandla raderna på något speciellt sätt. Då kan det vara bra att kunna komma åt dem med en speciell typ.
string_demo.adb
|
|
Exempel 10: Stränghantering |
Strängar i Ada är egentligen arrayer av tecken och kan behandlas precis som sådana. Det finns dock en hel del speciella saker man kan göra med just strängar. I exempel 10 visar vi de grundläggande saker som kan vara bra att kunna.
Get
. När vi
deklarerade strängen angav vi att den skulle vara tio tecken. Därför kommer
Ada att läsa in tio tecken, varken mer eller mindre. Dessutom kommer Ada
att strunta i att vi trycker Enter och vi måste därför "äta upp"
radslutstecknet med Skip_Line
. Matar vi in fler än tio tecken
kommer dessa att kastas bort, vilket vi ser i exempel 10b.Get_Line
.
Då läser Ada in strängen tills vi trycker på Enter och returnerar sedan
inte bara strängen utan också antalet tecken som lästes in. I exempel 10
sparar vi antalet inlästa tecken i variabeln L
. När vi sedan
ska skriva ut det vi nyss läste in anger vi att vi bara vill skriva ut
de L
första tecknen med notationen S(1..L)
.
Detta är en så kallad array slice, dvs en del av fältet.Index
som finns i paketet Ada.Strings.Fixed
.
Vi anger originalsträng och delsträng som vi vill söka efter.
Index
returnerar en siffra som talar om var delsträngen
börjar. Här ser vi också hur man omvandlar ett tal till en sträng med
Integer'Image()
samt hur man kan konkatentera (slå ihop)
strängar med operatorn &
.Integer'Value()
.
|
Exempel 10b: Utmatning från sträng-exemplet |
I Ada kan du deklarera egna typer som liknar eller utökar de typer som redan finns.
type_test.adb
|
|
Exempel 11: Egna typer |
My_Number
är en exakt kopia av den inbyggda typen
Integer
. Den har samma egenskaper och samma operatorer, men
de är inte utbytbara. På andra raden i huvudprogrammet måste vi explicit
omvandla I
som är Integer
till
My_Number
.Small_Number
är också en kopia av Integer
,
men kan bara innehålla tal i intervallet -127 till 128. Samma sak gäller
här som för My_Number
.Small_Integer
är inte en kopia av Integer
utan en subtyp. Det innebär att Small_Integer
i princip
är Integer
, men med restriktionen att talen bara får vara
i det angivna intervallet. När vi deklarerar en subtyp slipper vi den
explicita typkonverteringen, som vi ser i rad fyra i huvudprogrammet.Weekday
är en uppräkningstyp, dvs vi anger exakt
vilka olika värden som variabler av den här typen kan ha.
record_test.adb
|
|
Exempel 12: Poststrukturer |
I Ada kan man deklarera så kallade poster (eng. record). Dessa
kan användas för att samla information som hör ihop, men inte nödvändigtvis
är av samma typ. Ett typexempel på användningen av poster är personregister.
I exempel 12 deklarerar vi en posttyp Person
som innehåller
namn och födelseår för en person. Dessutom skriver vi en egen
Put
-funktion för att kunna skriva ut posttypen. Detta funkar
alldeles utmärkt, eftersom funktioner överlagras i Ada. De enskilda
fälten i posttypen kommer vi åt med punkt-notationen, dvs vi
anger postvariabeln följt av en punkt följt av ett fältnamn.
|
Exempel 12b: Användning av poststrukturer |
error1.adb
|
|
Exempel 13: Program utan undantagshantering |
Programmet i exempel 13 ser ganska enkelt och oskyldigt ut, men saknar felhantering. En rad olika fel kan uppstå, särskilt kring inmatning. I körexemplet nedan ser vi att programmet fungerar utmärkt när användaren matar in förutsägbara data. När användaren matar in ett tal som ligger utanför intervallet 0 till 9 genereras ett undantag (eng. exception) och programmet avbryts. Samma sak händer om användaren matar in något som inte kan tolkas som ett tal.
|
Exempel 13b: Undantag |
Programmet i exempel 14 har utökats så att det kan fånga upp de
undantag som genereras. Vi gör detta genom att lägga in en
exception
-sektion mellan begin
och end
.
Där skriver vi ut ett lämpligt felmeddelande.
error2.adb
|
|
Exempel 14: Uppfångande av undantag |
|
Exempel 14b: Körexempel för uppfångande |
Att bara avbryta programmet och skriva ut ett meddelande är inte alltid
det bästa sättet att hantera undantag. Om användaren råkade slinta på
tangentbordet kanske han eller hon borde få försöka igen. Vi kan lägga en
loop
-konstruktion runt inmatningen, fånga upp felen och
försöka igen tills ett accepterbart resultat har uppnåtts. En sådan
konstruktion återfinns i exempel 15.
error3.adb
|
|
Exempel 15: Felhantering |
I exempel 15 använder vi återigen Skip_Line
. Detta gör vi
för att tömma inläsningsbufferten. I annat fall skulle den gamla misslyckade
inläsningen ligga kvar och tolkas en gång till, varvid en oändlig loop skulle
uppstå.
|
Exempel 15b: Körexempel på felhantering |
Man kan också deklarera egna undantag i Ada. Detta sker i deklarationsdelen
av en procedure och kan t.ex. se ut
My_Exception : exception
. Därefter kan man generera
ett undantag med kommandot raise My_Exception;
någonstans
i koden.
Vad är en fil egentligen? En klassisk definition är att en fil är en sekvens av tecken. Vi talar ofta om textfiler och binärfiler. Skillnaden mellan dessa är rent akademisk, dvs det beror på hur vi väljer att betrakta dem. En viss fil (sekvens av tecken) kanske innehåller enbart läsbara tecken (bokstäver, siffror, etc) och har radbrytningar med lämpliga intervall. Då kan vi betrakta den som en textfil och behandla den därefter. Vi kan dock lika gärna betrakta samma sekvens av tecken som binärdata och behandla filen därefter.
Det finns två grundläggande sätt att bearbeta filer: sekventiellt eller med direktåtkomst. Det förra innebär att man läser eller skriver filen från början till slut utan att backa. Det senare innebär att man kan peka ut en position i filen och läsa eller skriva där. Vi ska enbart gå igenom sekventiell bearbetning här.
copy_file.adb
|
|
Exempel 16: Kopiera en textfil |
I exempel 16 kopierar vi en textfil. För att kunna hantera filer
överhuvudtaget måste vi deklarera en eller flera filtyper. Dessa
fungerar som ett slags handtag som håller reda på själva filen. Vi öppnar
respektive skapar filer med Open
och Create
.
Vi kan läsa och skriva med Get
och Put
precis
som vanligt. Vi kan också testa om vi har kommit till slutet på en rad
eller slutet på själva filen med End_Of_Line
respektive
End_Of_File
.
Vi använder Skip_Line
för att "äta upp" radslutstecknet
och New_Line
för att mata ut ett nytt. Detta gör vi eftersom
radslut markeras på olika sätt på olika datorer. Vi hade eventuellt kunna
behandla radslutsmarkeringarna som vanliga tecken, men sättet ovan är
bättre.
Det finns tre olika sätt att öppna en fil och dessa anges som andra
argument till Open
eller Create
. De tre sätten
är: In_File
, Out_File
och Append_File
.
Man kan alltså läsa eller skriva till en fil, inte båda. Om man vill
byta läge måste man stänga filen och öppna den igen. Append_File
används om man vill lägga till data i slutet av filen.
copy_binary_file.adb
|
|
Exempel 17: Kopiera en binärfil |
I exempel 17 kopierar vi en binär fil, dvs vi betraktar filen som en
sekvens av Integer
. I exempel 16 med textfiler använde vi
gamla vanliga Ada.Text_IO
, men för binärfiler måste vi fixa
ett eget paket. Det finns ett generisk paket Ada.Sequential_IO
som vi kan använda, men då måste vi instansiera det först (dvs det
generiska paketet är bara en mall och vi måste skapa ett verkligt paket).
För binärfiler använder vi Read
och Write
för
att läsa och skriva. I övrigt fungerar det på samma sätt som för textfiler,
bortsett från att vi inte kan testa om vi kommit till ett radslut.
I Ada kan man gruppera ihop funktioner, procedurer m.m. och lägga dem i särskilda paket. Vi har redan sett hur vi använder standardpaketen i Ada, men vi kan också göra egna paket. I exempel 18 återfinner vi ett exempel på ett paket för hantering av komplexa tal.
Ett paket definieras med två filer, en som innehåller paketets
huvud (efternamn .ads
) och en som innehåller paketets
kropp (efternamn .adb
).
komplex_paket.ads
|
|
komplex_paket.adb
|
|
Exempel 18: Paket för komplexa tal |
Paketets huvud är dess gränssnitt mot omgivningen. Här talar vi om vad vi vill att andra paket och program ska känna till om just det här paketet.
private
längre ner. På det här sättet kommer program
som använder sig av paketet inte ha en aning om hur de komplexa talen
faktiskt lagras. Det enda de vet är att typen finns och att det finns
procedurer och funktioner som kan operera på den.I paketets kropp (som i det här fallet återfinns i filen
komplex_paket.adb
) hittar vi implementationen av de
funktioner och procedurer som utlovades i pakethuvudet.
komplex_test.adb
|
|
Exempel 19: Test av paketet för komplexa tal |
I exempel 19 ser vi hur man kan använda det egendefinierade paketet för komplexa tal.
|
Exempel 19b: Körexempel från test av komplexa tal |
Låt säga att vi vill implementera en stack i Ada. En stack är en datastruktur som funkar ungefär som en trave med tallrikar. Man lägger något på toppen eller så tar man bort något från toppen. Vi kan t.ex. lagra en stack i en array, men då skulle vi tvingas göra massor av olika typer av stackar. Ponera att vi vill ha en stack för heltal, en stack för flyttal och en stack för strängar. Vi vill inte skapa tre olika paket som ser nästan likadana ut. Istället löser vi det genom att skapa ett generiskt paket.
Ett generiskt paket är egentligen inte ett paket, det är en paketmall. Vi anger några generiska parametrar i början som talar om vad det är som ska kunna anpassas. En generisk stack återfinns i exempel 20.
gen_stack.ads
|
|
gen_stack.adb
|
|
Exempel 20: Generiskt paket för stackar |
Vi har tre generiska parametrar i pakethuvudet:
Max
anger vi den maximala storleken på
stacken. Den används sedan i paketkroppen för att deklarera arrayen
S
som innehåller själva stacken.Item
används för att markera typen
av data som ska lagras i stacken. Hela paketkroppen laborerar med den
fiktiva typen Item
utan att veta vad den egentligen är.Put
för att kunna skriva
ut innehållet på stacken.I exempel 21 instansierar vi det generiska paketet. Det innebär att vi fyller paketmallen med innehåll och skapar ett verkligt paket.
gen_stack_test.adb
|
|
Exempel 21: Test av generiskt stackpaket |
I exempel 21 skapar vi en stack som kan lagra maximalt 100 st
Integer
. Dessa kan skrivas ut med hjälp av vår egendefinierade
procedure Put_Stack_item
.
|
Exempel 21b: Körexempel från test av generiskt stackpaket |
En pekare är en referens till någonting - ett sätt att indirekt komma åt data. Att använda pekare är inte så krångligt, men man måste hålla tungan rätt i munnen.
Om vi deklarerar en variabel I
som Integer
så
innebär det att kompilatorn ser till att det finns utrymme för att
lagra ett heltal någonstans. Om vi istället använder pekare måste vi själva
se till att allokera minne när programmet körs.
access_test.adb
|
|
Exempel 22: Demonstration av pekare |
I exempel 22 laborerar vi med pekare till heltal. För att kunna göra
detta måste vi först definiera en pekartyp. Vi definierar också
två stycken pekare I_Ref1
och I_Ref2
. Att
allokera minne för att lagra saker sker enkelt med new
, men
för att kunna lämna tillbaka minnet måste vi instansiera den generiska
proceduren Ada.Unchecked_Deallocation
och tala om vilken
typ av data det är som ska avallokeras och hur vi refererar till den.
Innehållet i programmet är som följer:
Integer
med hjälp
av new
. Adressen till denna minnesbit sparas i
I_Ref1
. Därefter placerar vi ett heltal på den plats som
pekas ut av I_Ref1
med notationen .all
.I_Ref1
så menar vi pekaren och inte
det data som pekaren pekar ut. Om vi jämför pekarna som i exemplet jämför
vi i praktiken alltså två adresser som ju är olika eftersom de pekar ut
skilda data..all
menar vi det data som pekaren
pekar ut. Detta är samma, eftersom båda pekarna pekar på heltalet 45 (som
dock finns lagrat på två olika platser i minnet).Delete
.Om man vill lagra större objekt, t.ex. egendefinierade poster, behöver
man inte använda .all
-notationen. Om vi har en postpekare
P
som pekar på en post med bl.a. fältet Name
betyder alltså P.all.Name
samma sak som P.Name
.