Kirjoittaja: Metabolix (2004).
⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠
Pascal on hyvin tarkka kieli muuttujien tyypin suhteen. Kun käyttää Pascalia, ei voi laittaa merkkijonomuuttujan arvoksi lukua 10, koska 10 on luku eikä merkkijono. Tämä ominaisuus tekee Pascalista erittäin mukavan kielen ohjelmoida: sen sijaan, että kääntäjä kirjoittaisi huolella piilotettuun lokitiedostoon pienen varoituksen, se ilmoittaa kiertelemättä, että näin ei voi tehdä.
Muuttujien, vakioiden ja tietueiden nimissä saa käyttää seuraavia merkkejä: 'a' .. 'z', 'A' .. 'Z', '_', '0' .. '9'. Nimi ei saa alkaa numerolla. Kirjainten koolla ei ole käytännön merkitystä; 'etana' on sama kuin 'EtAnA'.
Vakioista on hyvä aloittaa, koska ne ovat yksinkertaisia. Vakio voi olla mikä tahansa tavallinen muuttujatyyppi tai lueteltu tyyppi, mutta se ei voi olla tietue. Vakion tyyppiä ei tarvitse ilmoittaa, vaan kääntäjä päättelee sen annetusta arvosta.
Miksei tätä arvoa voi sitten kirjoittaa joka kerta uudestaan? Kyllähän sen toki voi... Huonoja puolia on kaksi:
Pascalissa vakioiden määrittely tapahtuu sanan const
avulla ja itse ohjelmakoodin ulkopuolella eli ennen sanaa begin
. Se voi olla vaikkapa tällainen:
const OmaTeksti = 'Tämä on tekstivakio!'; Pii = 3.14159265358979; JokuLukuVaan = 3125694; Heksadesimaaliluku = $1F6bC;
Muuttujia on useita erilaisia. Tavallisimpia ovat kokonaisluvut, liukuluvut (desimaaliluvut) ja merkkijonot sekä Boolean
, jonka arvo on True
tai False
(tosi tai epätosi).
Kokonaislukutyypit suurimmasta pienimpään ovat:
Nimi | Lukualue | Lukualue | Muistinvaraus (tavua) |
---|---|---|---|
Int64 | -9223372036854775808 .. 9223372036854775807 | -263 .. 263 - 1 | 8 |
LongWord | 0 .. 4294967195 | 0 .. 232 - 1 | 4 |
Longint | -2147483648 .. 2147483647 | -231 .. 231 - 1 | 4 |
Integer (Yleensä) | -2147483648 .. 2147483647 | -231 .. 231 - 1 | 4 |
Word | 0 .. 65535 | 0 .. 216 - 1 | 2 |
Smallint | -32768 .. 32767 | -215 .. 215 - 1 | 2 |
Integer (Vanhoissa kääntäjissä) | -32768 .. 32767 | -215 .. 215 - 1 | 2 |
Byte | 0 .. 255 | 0 .. 28 - 1 | 1 |
Shortint | -128 .. 127 | -27 .. 27 - 1 | 1 |
Normaalit liukulukutyypit ovat:
Nimi | Lukualue | Muistinvaraus (tavua) | Merkitseviä numeroita |
---|---|---|---|
Single | 1.5 * 10-45 .. 3.4 * 1038 | 4 | 7 .. 8 |
Double | 5.0 * 10-324 .. 1.7 * 10308 | 8 | 15 .. 16 |
Merkkijonotyypit ovat:
Nimi | Maksimipituus | Muistinvaraus |
---|---|---|
ShortString | 255 merkkiä | 2 .. 256 tavua |
AnsiString | 4294967295 merkkiä | 4 tavua .. 2 gigatavua |
String (normaalisti) | 4294967295 merkkiä | 4 tavua .. 2 gigatavua |
WideString | 2147483647 merkkiä | 4 tavua .. 2 gigatavua |
Lisäksi Pascalissa voi määrittää lueteltuja tyyppejä. Nämä laitetaan tietueiden tapaan kohtaan type
, minkä jälkeen ne ovat käytettävissä samoin kuin muutkin muuttujatyypit. Määritys voi olla esimerkiksi tällainen:
type Ase = (Puukko, Kirves, Pistooli, Haulikko, AK_47);
Aseet on numeroitu järjestyksessä, alkaen nollasta. Voit siis suorittaa vertailuja samoin kuin luvuilla, esimerkiksi näin:
if OmaAse < Haulikko then OstaIsompi(TosiIso, VaikkaVelaksi); if Vihollinen.Ase > Kirves then JuoksePakoon(Kauas, Kovaa);
Kaikkein ensimmäiseksi muuttujat pitää määritellä. Pascalissa tämä tapahtuu sanan var
avulla ja itse ohjelmakoodin ulkopuolella eli ennen sanaa begin
:
var H455U_Luku: Integer; __Liukuluku: Single; OmaTeksti: String;
Muuttujia voi käyttää vasta itse ohjelmakoodin alettua eli sanan begin
jälkeen.
Muuttujalle annetaan arvo merkinnällä :=
H455U_Luku := 7; __Liukuluku := 9.99999; OmaTeksti := 'Hello, World!';
Muuttujalle annetava arvo voi olla myös lauseke tai toinen muuttuja.
Lausekkeissa käytetään merkkejä +, -, * ja /. div
palauttaa jakolaskun kokonaisosan ja mod
jakojäännöksen. Jälkimmäiset toimivat vain kokonaisluvuilla.
H455U_Luku := 100 mod 3; { 1 } H455U_Luku := 100 div 3; { 33 } __Liukuluku := 9.99 + Luku; { 9.99 } __Liukuluku := 9.99 * Luku; { 0 } __Liukuluku := 4 / (Luku + 5); { 0.8 } __Liukuluku := -__Liukuluku + 1; { -0.8 + 1 = 0.2 } OmaTeksti := 'Pas' + 'cal' + ' on' + ' ki' + 'va' + ' kie' + 'li.'; { 'Pascal on kiva kieli.' }
Koska kokonaisluvun arvoksi ei voi antaa liukulukua, täytyy liukuluku katkaista trunc
-funktiolla (truncate). Trunc
ei pyöristä lukua, mutta pyöristetyn arvon saa lisäämällä lukuun ensin arvon 0.5. Luvun itseisarvon taas saa funktiolla abs
.
H455U_Luku := trunc(9.999); { 9 } H455U_Luku := trunc(9.999 + 0.5); { 10 } H455U_Luku := trunc(abs(-1.23)); { 1 }
Lisäksi kokonaisluvuille toimivat bittioperaattorit and, or, xor, not, shr
ja shl
. Niitä käytetään aivan samoin kuin tavallisia laskutoimituksia. Tarkemmat tiedot löydät Pascal-hakemistosta.
Joukot ovat juuri sitä mitä nimi sanoo: joukko tietyn tyyppisiä muuttujia. Joukon voi muodostaa mistä tahansa enintään 256 erilaista vaihtoehtoa sisältävästä muuttujatyypistä. Tämä ehto rajaakin hyvin vahvasti joukkojen käyttöä. Joukkovakiot merkitään hakasulkuihin ja joukkoja yhdistellään plus- ja miinusmerkeillä. Tietyn arvon olemassaolo selviää in-operaatiolla. Yleensä suurimman hyödyn joukoista saa juuri lueteltujen tyyppien kanssa.
program AseSet; type Ase = (Puukko, Kirves, Pistooli, Haulikko, AK_47); var Varustus: set of Ase; begin { Varustuksessa olkoot puukko ja kirves } Varustus := [Puukko, Kirves]; { Otetaan puukko pois ja AK_47 tilalle } Varustus := Varustus - [Puukko] + [AK_47]; { Onko meillä nyt haulikko? } if Haulikko in Varustus then Writeln('Haulikko on.'); end.
Taulukko voi nimestään huolimatta olla juuri niin moniulotteinen kuin tarve vaatii. Taulukko määritetään samalla lailla kuin muutkin muuttujat. Määrittelyssä käytetään sanaa array
, jonka voi kukin kirjoittaa halunsa mukaan isolla tai pienellä.
var Taulu: Array [1 .. 5] of Integer; Taulu2D: Array [1 .. 5, 3 .. 8] of Integer; Lippaan_Koko: Array [Ase] of Integer;
Taulukkoa käytettäessä sen alkioon pääsee käsiksi kirjoittamalla hakasulkuihin sen indeksin tai muun tunnisteen:
Taulu[1] := 10; Taulu2D[1, 5] := 17; Lippaan_Koko[Haulikko] := 1; Taulu2D[Taulu[1], Taulu[2]] := 10; { Indeksiksi kelpaavat muuttujatkin. }
Normaalisti taulukon koko määritellään heti, eli taulukko on staattinen. Tällöin taulukkoa voi käyttää heti. Ainakin Delphi tarjoaa toisenkin tavan: koon voi määritellä vasta myöhemmin (dynaaminen taulukko), jolloin taulukko toimii kaikin puolin hieman eri lailla. Tästä on pieni esimerkki seuraavassa.
program YleinenEsimerkki; {$APPTYPE CONSOLE} uses SysUtils; type { Siinä missä Byte voi olla väliltä 0 .. 255, Hedelma voi olla väliltä Omena .. Erikoishedelma } Hedelma = (Omena, Banaani, Paaryna, Erikoishedelma); Planeetat = (Merkurius, Venus, Maa, Mars, Jupiter, Saturnus, Uranus, Neptunus, Pluto); Lampoalue = (Trooppinen, Lauhkea, Jaatikko); var Staattinen: array [Lampoalue, Planeetat] of set of Hedelma; { Staattisesta taulukosta tulee kaksiulotteinen, koska siihen on määritetty kaksi pituutta. } Dynaaminen: array of array of Integer; { Dynaamisesta taulukosta tulee kaksiulotteinen, koska "array of" lukee kaksi kertaa. Tämä ei siis toimi kuin Object Pascalissa. } Palsta: Integer; const Pituus = 5; Leveys = 10; begin { Asetetaan Dynaamisen taulukon pituudeksi Pituus. Koska numerot alkavat nollasta, tulee taulukosta kooltaan 0 .. (Pituus - 1) eli 0 .. 4 } SetLength(Dynaaminen, Pituus); { Asetetaan jokaisen palstan pituudeksi Leveys. Koska numerot alkavat yhä nollasta, tulee kunkin palstan leveydeksi 0 .. (Leveys - 1) eli 0 .. 9 } for Palsta := 0 to Pituus - 1 do SetLength(Dynaaminen[Palsta], Leveys); { Nyt Dynaamisen eri kohdille voidaan antaa arvoja. Koordinaatit laitetaan hakasulkuihin. } Dynaaminen[0][3] := 10; { Staattiselle ei tarvitse tehdä mitään ennen käyttöä. Kukin kohta on tyyppiä "set of Hedelma", jolloin joka kohdassa voi olla hedelmistä koottu joukko. Myös osoitustapa on erilainen kuin Dynaamisessa. Kaikki joukot merkitään hakasulkuihin. Joukkojen yhteen- ja vähenyslaskuissa joukkojen tulee olla samaa tyyppiä. Yksittäisten jäsentenkin tulee muodostaa joukko } Staattinen[Trooppinen, Maa] := [Omena, Banaani, Paaryna, Erikoishedelma]; Staattinen[Lauhkea, Maa] := Staattinen[Trooppinen, Maa] - [Banaani, Erikoishedelma]; Staattinen[Trooppinen, Mars] := [Erikoishedelma]; end.
Käytetystä for .. to .. do
-lauseesta kerrotaan lisää seuraavassa osassa.
Tietueet ovat muuttujia, jotka koostuvat muista muuttujista. Esimerkiksi tietue "TAuto" voisi sisältää osat "KuljettuMatka" ja "Huippunopeus" jotka olisivat vaikkapa kokonaislukuja. Muuttujassa "X", jonka tyyppi on "TAuto", pääsisimme näihin käsiksi kirjoittamalla "X.KuljettuMatka" tai "X.Huippunopeus".
Nimen edessä on T, jotta tunnistamme myöhemminkin koodissa nimen tietuetyypiksi. Merkintä ei ole pakollinen, mutta se selkeyttää koodia.
Ohjelman muistinkäytön pienentämiseksi kannattaa tietueesta jättää kaikki tarpeeton pois. Turha uhrata auton moottorille tilaa, jos sitä ei tarvitse. Epäolennaisia ei turhaan tarvitse muistaa.
Tietueet määritellään yleensä ohjelman alkuun, jotta ne ovat käytössä koko ojelman ajan. Määrittely voi tapahtua esimerkiksi näin:
type TBensatankki = record MaxLitraa: Integer; LitraaJaljella: Integer; end; TAuto = record KuljettuMatka: Integer; Huippunopeus: Integer; Tankki: TBensatankki; end;
Tämän jälkeen voit määritellä tekemääsi tyyppiä olevan muuttujan ja käyttää sitä ohjelmassasi. Lisäksi on mahdollista määritellä tyyppi vasta muuttujan määrittelyn yhteydessä:
var { Käytetään aiempaa tyyppiä, TAuto } OmaAuto: TAuto; { Määritellään, millainen tyyppi naapuri on } Naapuri: record Auto: TAuto; Rahat: Integer; end; begin OmaAuto.Tankki.MaxLitraa := 50; OmaAuto.Tankki.LitraaJaljella := 0; { Viedään naapurilta bensat: } OmaAuto.Tankki.LitraaJaljella := Naapuri.Auto.Tankki.LitraaJaljella; Naapuri.Auto.Tankki.LitraaJaljella := 0; end.
Lauri Kenttä, 17.8.2004
Ahhaaa! Oppaan osat 2 ja 3 ovat menneet sekaisin!
Dynaaminen: array of array of Integer;
Turbo Pascal ei hyväksy tuota. "Error "[" or "(." expected". Onko siinä jotain eroa muihin kääntäjiin verrattuna?
Vai riippuuko jotenkin tuosta SysUtilsista? Sitä ei näytä löytyvän.
Hienoa, että tämäkin puute oppaissa tuli ilmi. Oppaat on nyt korjattu noilta osin.
Kyseessä on siis vain Delphin ominaisuus. Mikäli näitä ilmenee lisää, niistä voi ilmoittaa vaikka sähköpostilla, mutta niihin, jotka huomasin, lisäsin asiasta maininnan.
melko oudosti noi taulukot esittelet
muuten noi dynaamiset taulukot ei toiminut dev-pascalissa (kääntäjä freepascal) kun yritin kääntää :(
tuleepas ihan vanhat ajat mieleen :)
voiko pascalissa muuttuja sisältää muita muuttujia ja mikä niiden "yhdistämismerkki" on? (php:ssä ., vb:ssä & jne.)
Kuten esimerkeistä näkyy (kannattaa lukea opas ennen kommentointia ^^), tekstinpätkiä yhdistellään plus-merkillä.
Luvut ja teksti ovat kaksi eri asiaa, ja niiden keskiset muunnokset eivät ole yhtä suoraviivaisia (näinhän se tapaa useimmissa kielissä olla). Tyypillisesti SysUtils-moduuli sisältää funktiot IntToStr ja StrToInt kokonaislukujen muunnoksiin sekä vastaavat funktiot StrToFloat ja FloatToStr liukulukutyypeille.
Mitä mahdat tarkoittaa muuttujilla, jotka sisältävät muita muuttujia? Mitään PHP-tyylistä järjestelmää ei ole ($muuttuja = "toinen" => $$muuttuja = $toinen), koska muuttujien nimet tapaavat hävitä käännösvaiheessa. Osoittimista kerrotaan myöhemmin oppaissa, kunhan pääset sinne asti :)
Jätkä, kuin vanha sä olit ku kirjotit nää? o_O
Nimittäin aikas hyviä oppaita.
Juhko kirjoitti:
Jätkä, kuin vanha sä olit ku kirjotit nää? o_O
Sen voit laskea profiilistani.
Kyllähän näistä perusasiat selviävät, mutta totta puhuen olen myöhemmin oppinut paljon uusiakin asioita. Vanhoja oppaita vain on hirveän hankala täydentää luontevasti.
Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.