</copymode
                               1001  READ *,I
                                756  IF(I+1) 103,45,7777
                                103  GOTO 1001
                               7777  I=-1
                                     GOTO 756
                                 45  GOTO 103
                                     END
>
</motto<-- -- anonymous </sc fortran> programmer>>

/chapter<Crayn Fortran>
 
/iii<fortran 77> /iii<fortran 8x> /iii<fortran 90>
Crayn </sc/ii<fortran>> on likimain standardin mukaista 
</sc fortran> 77:{{, jota on t{ydennetty ehdotetun </sc fortran> 8x
-standardin (josta tosin tullee </sc fortran 90>) 
tapaisilla vektori- ja matriisioperaatioilla. 
Muuttujien talletustapa on tavukoneista (kuten VAX, IBM)
poikkeava ja saattaa vaatia muutoksia muualta siirrett{viin
ohjelmiin.

/section<Ohjelman ulkoasu>

Ohjelmarivin pituus on 72 merkki{, eik{ pitempi{ rivej{ voi
k{ytt{{ (toisin kuin VAXin </sc fortran>issa).
/ii<Tabulaattori>merkki tulkitaan kahdeksaksi v{lily|nniksi, joten
jatkorivin alussa sit{ ei voi k{ytt{{. Yleens{kin
tabulaatoreita olisi syyt{ v{ltt{{, koska niiden tulkinta
riippuu k{{nt{j{st{, ja lis{ksi ne tulostuvat eri tavoin
eri laitteille.

/iii<fortranin tunnukset>
/iii<globaalit tunnukset>
Ohjelman voi kirjoittaa isoilla tai pienill{ kirjaimilla.  K{{nt{j{
k{sitt{{ ison ja pienen kirjaimen samaksi symboliksi paitsi
merkkijonon sis{ll{. Esimerkiksi </tt abc> ja </tt ABC> viittaavat
samaan muuttujaan. Tunnuksissa voi kirjainten ja numeroiden lis{ksi
k{ytt{{ my|s alaviivaa (</tt /char95>).  Tunnusten pituus saa olla
korkeintaan 31 merkki{.  Globaalit tunnukset sen sijaan eiv{t saa olla
8 merkki{ pitempi{. T{llaisia ovat mm. </tt/ii<common>> -alueiden,
funktioiden ja aliohjelmien nimet.

/iii<kommentit> /iii<!>
Huutomerkki{ (</tt !>) seuraava osa rivist{ tulkitaan
kommentiksi. Huutomerkki{ ei kuitenkaan saa kirjoittaa
sarakkeille 1--6. 

Ohjelmaan voi sis{llytt{{ muita tiedostoja </tt/ii<include>>-lauseilla 
samaan tapaan kuin VAXilla.  Lause on muotoa

</copymode
         include 'fyle'
>

</sc Unix>issa isot ja pienet kirjaimet tarkoittavat eri asiaa, joten
tiedoston nimi on muistettava kirjoittaa pienill{ kirjaimilla,
mik{li sen nimi tiedostohakemistossa on kirjoitettu pienill{
kirjaimilla (ja t{m{nh{n n{kee esim </tt ls> -komennolla).

 
/section<Muuttujien tyypit>

/iii<fortranin muuttujat> 
Crayn huomattavin ero muihin koneisiin verrattuna on
muuttujien talletustapa.  Pienin osoitettavissa oleva
yksikk| on 64-bittinen sana, johon voidaan tallettaa yksi
kokonaisluku tai reaaliluku.  T{llainen yksinkertaisen
tarkkuuden muuttuja vastaa useimpien muiden koneiden
kaksoistarkkuutta, joten varsinaista kaksoistarkkuutta ei
juuri tarvita.  Kaksoistarkkuuden muuttujiakin voi k{ytt{{,
mutta niill{ laskeminen hoidetaan ohjelmallisesti ja on
huomattavasti (20--25 kertaa) hitaampaa kuin yksinkertaisen
tarkkuuden muuttujilla operointi. 
 
Tavukoneille tyypilliset m{{rittelyt, kuten
</tt integer*4>, </tt/ii<real*4>>, </tt/ii<real*8>> 
eiv{t kuulu </sc fortran>in standardiin, eik{ niit{ pit{isi
k{ytt{{ Crayll{. Jos ohjelmassa esiintyy </tt real*4>
tai </tt real*8> -tyyppisi{ muuttujia, k{{nt{j{ tekee
niist{ kyll{ automaattisesti tavallisia </tt real>-muuttujia,
mutta varoittaa ep{ilytt{vist{ m{{rittelyist{.
(Itse asiassa </sc fortran>issa /ii<kaksoistarkkuuden 
muuttuja>n tyypin oikeaoppinen muoto on </tt/ii<double precision>>.)

/iii<implisiittiset m{{rittelyt>
/iii<implicit none>
Implisiittisten m{{rittelyjen k{ytt| voidaan est{{
sanomalla

</copymode
     implicit none
>

T{m{ ei kuulu </sc fortran>in standardiin, mutta l|ytyy jo
monesta muustakin k{{nt{j{st{ (kuten VAXin </sc fortran>, IBM:n
</sc vs-fortran>).  Sen avulla s{{styy usein monilta harmeilta,
kun v{{rin kirjoitetut muuttujien nimet l|ytyv{t jo
k{{nn|svaiheessa.  Crayll{ </tt implicit none> on viel{
voimallisempi kuin VAXilla tai IBM:ll{, sill{ se edellytt{{,
ett{ kaikkien modulin kutsumien funktioiden
(intrinsic-funktioita lukuunottamatta) ja lausefunktioiden
tyypit on m{{ritelt{v{ ja kutsuttavat aliohjelmat on
ilmoitettava </tt external>-m{{rittelyll{. 

Mik{li tavukoneelta siirrett{v{ss{ ohjelmassa on 
</tt/ii<equivalence>>-lauseilla samaistettu erimittaisia 
muuttujia, voivat seuraukset olla
mielenkiintoisia, varsinkin, jos muuttujien sijaintia samassa paikassa
on k{ytetty ilke{mielisell{ tavalla hyv{ksi.

/ii<Kokonaisluku> (</tt/ii<integer>>) varaa aina  yhden
64-bittisen sanan. Oletusarvoisesti sanasta k{ytet{{n
kuitenkin vain 46 bitti{, jolloin muuttuja voi olla
v{lill{
$$-2^<46> /le </rm I> /le 2^<46> /approx 10^<14>.$$
K{{nt{j{n optiolla </tt -i 64> saadaan k{ytt||n koko sana,
jolloin lukualue on
$$-2^<63> /le </rm I> /le 2^<63> /approx 10^<19>.$$

/ii<Reaalimuuttuja> (</tt/ii<real>>) koostuu etumerkist{
(bitti 63), eksponentista (bitit 62--48) ja /ii<mantissa>sta
(bitit 47--0). /ii<Eksponentti>osa ilmoittaa kakkosen
potenssin, johon on lis{tty $40000_8$.
Lukualue on noin
$$10^<-2467> /lt /vert </rm R> /vert /lt 10^<2465>$$
ja tarkkuus noin 15 merkitsev{{ desimaalia.

/ii<Kaksoistarkkuuden muuttuja> (</tt/ii<double precision>>)
vie tilaa kaksi sanaa.  Ensimm{inen niist{ on t{sm{lleen
samanlainen kuin tavallinen </tt real>-muuttuja, ja toisen
sanan biteiss{ 0--47 on lis{{ mantissaa.  Lukualue ei siis
kasva, mutta tarkkuus lis{{ntyy noin 29 desimaaliin.  Koska
t{llaista tarkkuutta tarvitaan eritt{in harvoin, kannattaa
kaksoistarkkuuden muuttujat vaihtaa tavallisiksi.  T{m{n voi
tehd{ automaattisesti k{{nt{j{n valitsimella </tt/ii<-dp>>. 
T{llainen menettely on tarpeen, jos samaa ohjelmaa halutaan
k{ytt{{ eri koneilla.  Mutta vaikka k{ytt{isitkin t{t{
optiota, ilmoita muuttujien tyypeiksi joko </tt real> tai
</tt double precision>, eik{ </tt real*4> tai </tt real*8>. 

/ii<Kompleksimuuttuja>t (</tt/ii<complex>>) esitet{{n kahden per{kk{isen
reaaliluvun avulla. Kaksoistarkkuuden kompleksilukuja ei ole.

/ii<Loogiset muuttujat> (</tt/ii<logical>>) varaavat my|skin
kokonaisen sanan.  Jos sanan sis{lt| on nollasta poikkeava,
on muuttujan arvo tosi, ja ep{tosi, jos sana on nolla. 
Tilan s{{st{miseksi on monissa vanhoissa ohjelmissa pakattu
pieni{ numeroita </tt/ii<logical*1>> -tyyppisiin muuttujiin. 
Crayll{ t{st{ ei ole mit{{n hy|ty{.  Muuttujien sis{isen
esitystavan erojen vuoksi t{llaisia temppuja sis{lt{v{t
ohjelmat voivat toimia v{{rin tai johtaa ohjelman
kaatumiseen (jos saat virheilmoituksen "/ii<operand range
error>", t{m{ on yksi mahdollinen syy).  Crayll{ loogisia
muuttujia tulisi k{ytt{{ vain standardin mukaiseen
totuusarvojen esitt{miseen. 

/ii<Merkkijonot> (</tt/ii<character>>) esitet{{n kahdeksan bitin
ASCII-koodina ja yhteen sanaan talletetaan kahdeksan merkki{.
Merkkijonovakiot voi ymp{r|id{ heitto- tai  lainausmerkeill{.
Esimerkiksi seuraavat merkkijonot ovat laillisia:
</tt 'huihai', "hohhoijaa", '"  "'>.

</sl/ii<Osoittimet>> (</tt/ii<pointer>>) ovat Crayn </sc fortran>in
omia laajennuksia.  Osoitin on muuttuja, jonka arvo on
osoite, ja se viittaa siis aina johonkin 64 bitin sanaan. 
Merkkijonoja pitkin seilaavia osoittimia (kuten C:ss{) 
</sc fortran> ei tunne (eip{ tietenk{{n, kun osoitteet viittaavat
aina sanoihin eiv{tk{ tavuihin).  Osoitin ei itse asiassa
voi lainkaan osoittaa </tt character>-tyyppiseen muuttujaan. 
Osoitettava olio ei saa esiinty{ </tt save>, </tt common>,
</tt equivalence> tai </tt parameter> -lauseessa eik{
my|sk{{n funktion tai aliohjelman muodollisena parametrina. 

Osoittimen osoittamalla muuttujalla ei ole osoitetta ennen kuin
osoittimelle on annettu arvo. Jos t{t{ arvoa muutetaan suoritusaikana,
siirtyy my|s osoitettava muuttuja viittamaan t{h{n uuteen
osoitteeseen.

Osoittimia voidaan k{ytt{{ esimerkiksi
/ii<dynaamiseen ty|tilan varaamiseen> seuraavasti:

</copymode
     subroutine zonk(n)
     common pool(1000000)
     real x(1000),y(n),z(n)
     pointer (px,x), (py,y), (pz,z)
     px = loc(pool)
     py = px+1000
     pz = py+n
     ...
> 

T{m{ siis sijoittaa taulukot </tt x>, </tt y> ja </tt z>
muistialueelle </tt pool>. Funktio </tt/ii<loc>> palauttaa
argumenttina annetun muuttujan osoitteen.

Toinen tapa varata muistia dynaamisesti on k{ytt{{
dynaamista </tt common>-aluetta. Sellaisen m{{rittelemist{
selostetaan luvussa /ref<16.7>.

</sl/ii<Automaattiset taulukot>> (/ii<automatic array>) ovat my|s
Crayn laajennuksia. Ne ovat paikallisia taulukoita, joissa
ainakin yhden indeksin raja on v{litetty aliohjelman argumenttina
tai se on </tt common>illa sijaitseva muuttuja.
T{ll|in taulukon koko m{{r{ytyy dynaamisesti suoritusaikana.
Esimerkiksi seuraavassa </tt x> on automaattinen taulukko:

</copymode
      subroutine f(n)
      integer n
      real x(n)
      ...
      end
>

/section</ii<Muuttujien talletustapa>>

Muuttujat voidaan tallettaa joko staattisesti tai dynaamisesti.
Talletustapa valitaan k{{nt{j{n optiolla </tt -a>.

/iii<staattinen tilanvaraus>
K{ytett{ess{ staattista talletusta (</tt -a /ii<static>>)
muuttujat talletetaan kiinte{lle muistialueelle. 
Aliohjelmien paikallisten muuttujien arvot eiv{t kuitenkaan
s{ily kutsujen v{lill{.  Staattinen tilanvaraus est{{
ohjelman rinnakkaistamisen. 

/iii<dynaaminen tilanvaraus>
Dynaamisessa tilanvarauksessa (</tt -a /ii<stack>>, oletusarvo
X-MP EA ja Y-MP -laitteistoissa) aliohjelmien paikalliset
muuttujat talletetaan /ii<pino>on.  Staattisesti talletetaan
edelleen </tt/ii<common>>-alueella olevat muuttujat sek{
</tt/ii<data>>- ja </tt/ii<save>>-lauseissa esiintyv{t muuttujat. 
Dynaamisesti varattavat muuttujat luodaan aina uudestaan
aliohjelmaa kutsuttaessa.  Jos paikalliset muuttujat
talletetaan dynaamisesti, funktiot ja aliohjelmat voivat
kutsua rekursiivisesti itse{{n.  Dynaaminen talletustapa
s{{st{{ muistitilaa, koska aliohjelmasta poistuttaessa sen
paikallisten muuttujien varaama tila vapautuu. 

Mik{li muuttujien arvot halutaan s{ilytt{{ aliohjelmakutsusta
toiseen, niiden t{ytyy esiinty{ </tt common>illa, 
</tt save>- tai </tt data>-lauseessa.

/ii<Automaattiset taulukot> varataan  aina dynaamisesti suoritusaikana,
joten niiden sis{lt| katoaa aliohjelmasta poistuttaessa
riippumatta siit{, miten ohjelma on k{{nnetty. 
Automaattisia taulukkoja ei voi tallettaa </tt save>-lauseella.

</bf Huom: standardi ei sano mit{{n paikallisten muuttujien
s{ilymisest{ kutsujen v{lill{.  Joissakin koneissa ne
saattavat s{ily{, ja jotkut ohjelmat k{ytt{v{t t{t{ hyv{ksi. 
[l{ kuitenkaan koskaan luota t{h{n, vaan huolehdi
eksplisiittisesti s{ilytett{viksi tarkoitettujen muuttujien
tallettamisesta!>



/section</ii<Taulukko-operaatiot>>

Crayn </sc fortran>issa on joukko vektorioperaatioita, joita
k{ytt{m{ll{ monet silmukat voidaan korvata yhdell{
sijoituslauseella.  N{m{ operaatiot muistuttavat paljon
esimerkiksi </sc matlab>in operaatioita.  Ne ovat my|s
tulossa jossakin muodossa </sc fortran> 90 -standardiin. 

Jos olemme m{{ritelleet esimerkiksi

</copymode
     real x(100),y(100),z(100)
>

voimme korvata silmukan

</copymode
     do 1 i=1,100
        y(i) = exp(x(i))
        z(i) = x(i)//y(i)+1.0
 1   continue
>

yksinkertaisesti lauseilla

</copymode
     y = exp(x)
     z = x//y+1.0
>

Voimme operoida my|s taulukon osiin eli /ii<taulukkosektio>ihin
(/ii<array section>). Sektio valitaan valitsimella (/ii<selector>),
joka yksinkertaisimmassa tapauksessa ilmoittaa indeksiv{lin.
Olkoon meill{ taulukot /iii<valitsin>

</copymode
     real x(100),y(0:1,0:2),z(10,10)
>

Silloin voimme poimia niist{ vaikkapa seuraavanlaisia
sektioita:

</copymode
     x(1:5)                !  x(1),...x(5)
     x(10:100:10)          !  x(10),x(20),...,x(100)
     y(:,1)                !  y(0,1),y(1,1)
     y(0,:)                !  y(0,0),y(0,1),y(0,2)
     z(1:5:4,8:9)          !  z(1,8),z(5,8),z(1,9),z(5,9)
>

Valitsimena voi olla my|s kokonaislukuarvoinen taulukko,
taulukkolauseke tai taulukkosektio. Siis esimerkiksi

</copymode
     integer i(5)
     real x(5)
     data i //1, 2, 3, 4, 5//
     ...
     x(i(5:1:-1))=x(i)
>

Ja voil/'a, olemme permutoineet </tt x>:n alkiot 
k{{nteiseen j{rjestykseen.

Taulukkolausekkeiden operandien ja sijoituslauseiden
molempien puolten on tietenkin oltava muodoltaan
samanlaisia sektioita. Poikkeuksena t{st{ ovat skalaarit,
jotka automaattisesti kopioidaan kaikkiin tarvittaviin
paikkoihin. Taulukon osa voidaan siis nollata esimerkiksi
seuraavasti:

</copymode
     z(:,1:5)=0.0
>

Taulukkosijoituksissa lasketaan ensin sijoituslauseen
kummatkin puolet ja vasta sitten suoritetaan sijoitus.
Lause

</copymode
     x(2:3)=x(1:2)
>

toimii siis ik{{nkuin

</copymode
     temp=x(1:2)
     x(2:3)=temp
>

eik{ kuten

</copymode
     x(2)=x(1)
     x(3)=x(2)
>

jonka tulos olisi ilmeisestikin aivan muuta kuin mit{ haluttiin.


              
/subtitle<Kontrollirakenteet>

/iii<fortranin kontrollirakenteet>
Kontrollirakenteet ovat </sc fortran> 77 -standardin mukaisia.
Kieless{ ei ole VAXin </sc fortran>in tapaisia laajennuksia, kuten
osoitteettomia </tt do ... enddo> -rakenteita ja 
</tt/ii<while>>-silmukoita.

/iii<rekursiivinen aliohjelma>
Jos muuttujat talletetaan pinoon, voivat aliohjelmat
ja funktiot kutsua rekursiivisesti itse{{n.





