Ohjelmointi Unixissa

Tämä opas käsittelee ohjelmointia käännettävillä ohjelmointikielillä Unix-ympäristössä. Pääpaino on Fortran-ohjelmoinnilla, mutta oppaassa käsitellään myös C-ohjelmointia sekä yksinkertaisten komentotiedostojen tekemistä.

Päivitetty viimeksi 2001-05-10. Teknisiä korjauksia 2004-11-27. Jukka K. Korpela.

Opas kuuluu sivuston Datatekniikka ja viestintä osaan Ohjelmistot ja dataformaatit.

Johdanto

Oppaan tarkoitus ja kohderyhmä

Tämä opas on tarkoitettu antamaan perusvalmiudet ohjelmien kääntämiseen, ajamiseen ja kehittelyyn Unix-ympäristössä. Pääpaino on Fortran-ohjelmoinnilla, mutta oppaassa käsitellään myös C-ohjelmointia sekä yksinkertaisten komentotiedostojen tekemistä.

Opas soveltuu henkilöille, joilla jo on alkeistiedot ja hiukan kokemusta Unixin käytöstä; aloittelijoille sopii ensimmäiseksi lukemiseksi Unix-opasta. Sen ja tämän oppaan välillä on tarkoituksellisesti jonkin verran päällekkäisyyttä eli niissä esitetään samojakin asioita.

Oppaan tausta

Tämä opas on alkujaan kirjoitettu TKK:n tarpeisiin. Vrt. Unix-oppaan kohtaan Oppaan historia ja muuta selittelyä. Erityisesti huomattakoon, että oppaan taustan takia siinä on käsitelty melko paljon IBM:n Unix-toteutuksen Aixin erikoisuuksia, eikä tekijä ole voinut näitä tietoja kovin hyvin tarkistaa opasta muuten päivittäessään.

Editorit

Ohjelman kirjoittamiseen ei käytetä tekstinkäsittelyohjelmia kuten MS Word vaan jotakin tekstieditoria. (Teoriassa Wordilläkin voisi kirjoittaa ohjelman, jos sen tallentaisi pelkkänä tekstinä, plain text, eikä Wordin normaalilla tallennustoiminnolla.)

Editoreina Unix-ympäristössä käytetään tavallisimmin vi:tä tai Emacsia. Jälkimmäinen on huomattavasti kehittyneempi; sen käytöstä antaa perusohjeet Emacs-opas.

Perusasiat

Perusmenettely

Jos halutaan käyttää eli ajaa ohjelmaa, jonka käyttäjä itse on kirjoittanut esimerkiksi Pascal-, C- tai Fortran-kielellä, menetellään näin:

Lisätietoja on Unix-oppaan kohdassa Ohjelmointi sekä jäljempänä kielikohtaisissa ohjeissa.

Ajokelpoisen ohjelman nimeäminen

Jos ajokelpoiselle ohjelmalle halutaan muu nimi kuin a.out, voidaan menetellä jommallakummalla seuraavista tavoista:

Tämän jälkeen ohjelma voidaan ajaa suoraan nimellään (esimerkissämme lasku), jos käyttäjä on siinä hakemistossa, jossa ohjelma sijaitsee, tai kyseinen hakemisto muutoin on ns. hakupolussa. (Hakupolku, path, luettelee listan hakemistoja, ja komentotulkki käyttää listaa etsiessään suoritettavaa ohjelmaa.)

Varoitus: Unix-koneessa saattaa olla valmiit hakupolkumäärittelyt siten, että polussa on viimeisenä piste, joka tarkoittaa työhakemistoa. (Työhakemisto, working directory, on "se hakemisto, jossa käyttäjä kulloinkin on". Pääteistunnon alussa työhakemistoksi tulee käyttäjän oma kotihakemisto. Työhakemiston voi vaihtaa cd-komennolla.) Tämä merkitsee, että jos käyttäjä kirjoittaa komentotasolla ohjelman nimen, kone suorittaa käyttäjän tämännimisen ohjelman vain, jos ei ole olemassa sennimistä systeemiohjelmaa tai, täsmällisemmin sanottuna, jos mikään muu hakupolussa oleva hakemisto ei sisällä sennimistä ohjelmaa.

Useampi kuin yksi Unixin käyttäjä on törmännyt tähän ongelmaan tehtyään test-nimisen ohjelman ja ihmeteltyään, miksi se ei tulosta mitään. Unixissa nimittäin on test-niminen systeemiohjelma!

Tästä syystä suosittelemme, että käyttäjä

Aliohjelmakirjastojen hyväksikäyttö

Aliohjelmakirjasto tarkoittaa kokoelmaa valmiita aliohjelmia joihinkin tarkoituksiin, esimerkiksi matemaattisiin tehtäviin tai graafiseen tulostukseen. Useimmiten se on hankittu ja asennettu koneeseen erikseen, tavallisesti maksullisena tuotteena joltakin ohjelmistovalmistajalta. Sellaisten kirjastojen valikoima on konekohtainen.

Jos ohjelma käyttää aliohjelmakirjastoa x, tulee kääntämiskomennossa antaa optio -lx. Kirjaston nimi siis kirjoitetaan heti, ilman välilyöntiä, l-kirjaimen perään. Kirjaston nimen tarkka muoto ilmenee kirjasto- ja konekohtaisista käyttöohjeista. Esimerkki:

f77 ohj.f -lnag

Lisäksi on huolehdittava siitä, että asianomainen tiedosto on käyttäjän ns. LIBPATH-hakupolussa, joka vastaa tavallista hakupolkua, mutta ympäristömuuttujan nimi siis on LIBPATH. Aliohjelmakirjaston konekohtaisista käyttöohjeista pitäisi löytyä tieto, mikä komento tarvitaan tätä varten.

Jos käytettäviä kirjastoja on useita, annetaan -l-optio kullekin erikseen.

Keskeisiä apuvälineitä

Komentojen editointi

Käytettäessä tcsh-komentotulkkia voidaan editoida komentoja ja käyttää vanhoja komentoja hyväksi varsin joustavasti.

Jos esimerkiksi olet antanut hiukan virheellisen komennon ja saanut virheilmoituksen, voit kirjoittaa control-P:n ja saada komentorivin takaisin. Kursori jää rivin loppuun. Voit editoida riviä "Emacs-tyylisesti" ja lopuksi painaa returnia. Kursori saa returnia painettaessa olla missä tahansa kohtaa riviä. Tavallisimmat Emacsin toiminnot ovat käytettävissä; esim. control-B vie kursoria taaksepäin ja control-F eteenpäin, control-A rivin alkuun jne.

Kirjoittamalla monta kertaa control-P:n pääset komentohistoriassa taaksepäin. Eteenpäin siinä pääsee control-N:llä.

Edellä mainittujen kontrollimerkkien asemesta voi yleensä käyttää myös nuolinäppäimiä samoihin tarkoituksiin.

Syötön ja tulostuksen ohjaus

Unixissa suoritettavalla ohjelmalla tai komennolla on kolme tietovirtaa (stream):

Esimerkiksi Fortran-ohjelmassa
Nämä kaikki liittyvät oletusarvoisesti käyttäjän päätteeseen mutta ovat helposti muutettavissa seuraavasti (eli aivan samoin kuin Unix-komentojen syöttö ja tulostus ovat uudelleenohjattavissa):

Näitä voidaan tietysti käyttää myös yhdessä, esim.
./ajo <datat >&tulokset

Päätetyöskentelyn lokin saaminen

Usein halutaan päätteellä tehtävästä työskentelystä tiedostoon ja sitä kautta ehkä paperille dokumentti eli loki (log), josta näkyvät annetut komennot ja niiden aiheuttama tulostus. Tämä on Unixissa varsin helppoa:

Ainoa pikku hankaluus on se, että lokitiedostoon tulee rivien loppuun ylimääräisiä return-merkkejä. Päätteelle tai paperille tulostettaessa ne eivät näy, mutta jos tiedostoa käsittelee Emacsilla tai vi:llä, return-merkki näkyy muodossa ^M. (Return-merkit on melko helppo poistaa. Ks. ohjetta tästä dokumentissa Rivinvaihdot ja kappaleet datan käsittelyssä, joka myös valottaa ongelman taustaa.)

Komentotiedostot

Mikä on komentotiedosto?

Komentotiedostolla tarkoitetaan tiedostoa, joka sisältää käyttöjärjestelmän komentoja ja joka mahdollistaa kyseisten komentojen suorittamisen kirjoittamalla vain komentotiedoston nimi.

Useissa käyttöjärjestelmissä komentotiedostojen nimille on jokin sääntö tai suositus, mutta Unixissa komentotiedoston nimi on vapaasti valittavissa.

Komentotiedosto saattaa pelkkien komentojen lisäksi sisältää myös kontrollirakenteita kuten ehdollisuutta ja silmukoita. Näistä piirteistä kuvataan seuraavassa vain ehdollisuus eli if-rakenne. Lisätietoja kontrollirakenteista on mm. Otadatan kirjassa Johdatus UNIXiin.

Komentotiedoston rakenne

Unixissa komentotiedostoja kutsutaan shell scripteiksi, ja niiden muoto riippuu käytettävästä komentotulkista eli shellistä.

Perussäännöt ovat:

Seuraavassa on esimerkki tyypillisestä yksinkertaisesta shell scriptistä, joka kääntää ja ajaa Fortran-ohjelman käyttäen määrättyjä tiedostoja. Oletetaan, että shell scriptiä ajettaessa halutaan vain ohjelmatiedostot ali2.f ja ali3.f kääntää uudestaan, kun taas ohjelman muut osat ovat valmiiksi käännettyinä tiedostoissa paa.o ja ali1.o.

#!/bin/tcsh
f77 paa.o ali1.o ali2.f ali3.f
rm -f fort.7
rm -f fort.8
ln -s data fort.7
ln -s results fort.8
a.out
rm fort.7
rm fort.8

Kaiutus

Usein on hyödyllistä, että komentotiedoston suorituksen aikana tulostuu päätteelle tietoja etenemisestä. Tämä saadaan aikaan kirjoittamalla komentotiedostoon echo-komentoja, esimerkiksi

echo 'Program started.'

Alustustiedostot

Yhteyttä otettaessa järjestelmä automaattisesti suorittaa käyttäjän kotihakemistossa olevan tiedoston .cshrc (jos käyttäjän oletus-shell on tcsh) ja sen jälkeen tiedosto .login. (Tiedostoilla, joiden nimi alkaa pisteellä, on yleensä jokin erikoismerkitys. Ne näkyvät ls-komennolla saatavassa tiedostolistassa vain, jos komennossa on optio -a. Muutoin niitä voi käsitellä kuten muitakin tiedostoja.)

Jos pääteistunnon aikana käynnistetään komentotulkki komentotulkin alla - kuten käy esim. annettaessa script-komento - niin järjestelmä aluksi suorittaa .cshrc-tiedoston (mutta ei .login-tiedostoa).

Käyttäjälle mahdollisesti perustetaan automaattisesti sellaiset tiedostot .cshrc ja .login, joissa on source-komentoja, joilla asetetaan voimaan eräitä järjestelmän yleisiä määrittelyjä. Jos haluat lisätä omia määrittelyjä, lisää ne .cshrc- tai .login-tiedostoosi source-komennon jälkeen.

Parametrien käyttö

Edellä kohdassa Komentotiedoston rakenne esitetty esimerkki sopii tilanteeseen, jossa ohjelman käsittelemien tiedostojen nimet halutaan ilmoittaa komentotiedostossa. Toinen tavallinen (tavallisempi?) tilanne on, että tiedostojen nimet haluttaisiin ilmoittaa komennossa, jolla ajo käynnistetään. Tämä voidaan tehdä komentotiedoston parametrien avulla.

Komentotiedostossa voidaan symboleilla $1, $2 jne. viitata parametreihin, jotka annetaan komentotiedostoa käynnistettäessä.

Seuraavassa on esimerkki komentotiedostosta, joka suorittaa (valmiiksi käännetyn) Fortran-ohjelman ajo käyttäen syöttö- ja tulostustiedostona niitä tiedostoja, jotka annetaan parametreina komentotiedostoa käynnistettäessä.

#!/bin/tcsh
rm -f fort.1
rm -f fort.2
ln -s $1 fort.1
ln -s $2 fort.2
ajo
rm fort.1
rm fort.2 

Jos tällaisen komentotiedoston nimi on esimerkiksi xqt ja se käynnistetään komennolla

xqt ajo.datat ajo.results

niin se suorittaa ohjelman ajo siten, että syöttötiedostona (josta ohjelma lukee kanavalta 1) on ajo.datat ja tulostustiedostona (johon ohjelma tulostaa kanavalle 2) on ajo.results.

Ohjausrakenteet

Ehtorakenteet ovat hiukan erilaisia eri shellejä käytettäessä. Seuraavat ohjeet koskevat tcsh:ta.

Komentotiedostoissa voidaan käyttää seuraavanlaista ehtorakennetta:

if (lauseke) then
komentojono1
else
komentojono2
endif

Lausekkeissa tavallisimpia rakenneosia ovat

Lausekkeen kunkin rakenneosan ympärillä tulee olla välilyönnit! Esimerkiksi 1+1==2 ei kelpaa, vaan pitää kirjoittaa 1 + 1 == 2. Muutoin lausekkeet kirjoitetaan kuten C-ohjelmointikielessä. Tämä merkitsee erityisesti seuraavia asioita: Esimerkki. Seuraava komentotiedosto toteuttaa eräänlaisen run-komennon: jos komentotiedoston nimenä on run, niin run abc kääntää Fortran-ohjelman abc.f ja, jos käännös menee virheittä, lataa ja tallentaa suoritusvalmiin ohjelman tiedostoon abc ja käynnistää sen.

#!/bin/tcsh
if ( { f77 -O -o $1 $1.f } ) then
  $1
endif

Jos haluaisimme tarkistaa tiedoston olemassaolon ennen kuin yritetään käännöstä, voisimme lisätä if-lauseen eteen seuraavan:

if ( ! -e $1.f ) then
  echo 'Tiedostoa ei löydy.'
  exit
endif

Lause exit aiheuttaa komentotiedoston suorituksen päättymisen.

Ehtorakenteen lisäksi voi tcsh-komentotulkissa olla muitakin ohjausrakenteita, kuten while-end, switch-endsw ja foreach-end. Näistä rakenteista on enemmän selostettu esim. Johdatus UNIXiin -kirjassa.

Erä- ja tausta-ajot

Erä- ja tausta-ajot

Unix-tietokoneissa voi ajaa tausta-ajoja tai käynnistää ohjelmia at-komennolla haluamaansa aikaan esim. yöllä (ks. man at).

Usein käyttäjä haluaa samanaikaisesti sekä ajaa jotakin ei-vuorovaikutteista ohjelmaa että työskennellä vuorovaikutteisesti, esimerkiksi editoida. (Ei-vuorovaikutteisella tarkoitetaan ohjelmaa, joka ei lue päätteeltä eikä tulosta päätteelle. Tarvittaessa voidaan päätetulostus estää kääntämällä tulostus tiedostoon.)

Tämä on mahdollista siten, että ei-vuorovaikutteinen ohjelma käynnistetään tausta-ajona: käynnistyskomennon loppuun kirjoitetaan & (et-merkki), esim.

ajo <ajo.input >ajo.output &

Jos tausta-ajo yrittää tulostaa päätteelle, se useimmissa Unix-järjestelmissä keskeytyy eli "suspendoituu". Päätetulostus voidaan kuitenkin sallia komennolla stty -tostop ja kumota komennolla stty tostop.

Tausta-ajon päätyttyä tulostuu päätteelle ilmoitus, joka sisältää hakasuluissa olevan numeron (prosessin numeron), sanan Done ja käynnistyskomennon. Ilmoitus tulostuu kuitenkin vain oltaessa komentotasolla. Jos siis ollaan esim. editoimassa, niin ilmoitus saadaan vasta, kun editorista on poistuttu.

Käyttäjä voi lopettaa pääteistunnon (logout), vaikka hänellä olisi tausta-ajoja pyörimässä - ne jäävät pyörimään.

Käyttäjällä voi olla useita samanaikaisia tausta-ajoja. Ei kuitenkaan ole mitenkään suotavaa esim. ajaa rinnakkain samaa ohjelmaa eri lähtötiedoilla. Sellainen ryöstää resursseja muilta käyttäjiltä.

Ohjelmien hallinta (make)

Perusidea make-komennossa

Yleensä on järkevää, että koko ohjelma ei ole yhdessä tiedostossa vaan jaettuna useaan tiedostoon siten, että yksi tiedosto sisältää yhden aliohjelman tai joukon loogisesti yhteenkuuluvia aliohjelmia. Tällöin ei pikku muutoksen jälkeen tarvitse kääntää koko ohjelmaa uudestaan.

Toisaalta eteen tulee ongelmiakin, jos ohjelma on useassa tiedostossa:

Ohjelmakokonaisuuksien hallintaa varten Unixissa on make-komento, jonka ideana on, että yhdessä tiedostossa (makefile-tiedostossa) kuvataan ohjelman koostuminen tiedostoista, tiedostojen riippuvuudet toisistaan, kääntämisessä käytettävät optiot jne. Ohjelman kääntäminen ja lataaminen (ajovalmiin ohjelman tuottaminen) voidaan sitten hoitaa yksinkertaisesti komennolla make.

Komennon make yhteydessä käytettävän tiedoston nimen ei tarvitse olla juuri makefile, mutta se lienee yksinkertaisinta. Huomaa, että jos suosituksemme mukaisesti perustat kullekin ohjelmakokonaisuudelle oman alihakemiston, voit aina käyttää makefile-nimeä.

Alkeisesimerkki

Jos Fortran-ohjelma koostuu tiedostoista a.f, b.f ja c.f, voisi makefile-tiedoston sisältö olla seuraava:
prog : a.o b.o c.o
        f77 -o prog a.o b.o c.o

missä toisen rivin alussa on tabulointimerkki (ei välilyöntejä!). Ensimmäinen rivi kertoo, että ohjelma prog riippuu ilmoitetuista tiedostoista. Toinen rivi puolestaan kertoo, millä komennolla prog tulee tuottaa. Sen, että a.o puolestaan pitää tuottaa kääntämällä a.f:stä jne., make-komento osaa itse päätellä.

Jos nyt annetaan komento make, niin se eri tiedostojen viimeisimmistä kirjoitusajankohdista päättelee, mitä kaikkea pitää tehdä, ja tuottaa ajantasaisen ajovalmiin ohjelman tiedostoon prog.

Fortran-kääntäjän optiot voidaan ilmoittaa kätevästi kirjoittamalla makefile-tiedoston alkuun rivi, jolla on sana FFLAGS, yhtäläisyysmerkki ja halutut optiot, esimerkiksi

FFLAGS = -O -qsource

C-kielen tapauksessa menetellään samoin, mutta sanan FFLAGS asemesta kirjoitetaan CFLAGS.

Monimutkaisempi esimerkki

Seuraavassa on hiukan monimutkaisempi esimerkki makefile-tiedostosta, jossa on kaksi erillistä mutkistavaa asiaa:

Jälkimmäinen asia hoidetaan siten, että makefile-tiedosto sisältää säännön, joka ilmoittaa tiedostojen paa.f ja ali1.f riippuvan tiedostosta defs.f. Tämän ansiosta make-komento automaattisesti kääntää tiedostot paa.f ja ali.f, jos tiedostoa defs.f on muutettu viimeisimmän kääntämisen jälkeen.

Tarvittava makefile-tiedoston sisältö on:

FFLAGS = -O
ajo : paa.o ali1.o ali2.o
        f77 -o ajo paa.o ali1.o ali2.o -lnag
paa.o ali1.o : defs.f

Vihjeitä

Usein ohjelmakokonaisuus koostuu kaikista jonkin hakemiston sisältämistä ohjelmatiedostoista. Tällöin voidaan menetellä seuraavasti:

Tutkinta (debuggaus)

Johdanto

Tutkinta (debuggaus) tarkoittaa käyttäjän ohjelman suorittamista erityisen tutkintaohjelman (debuggerin) alaisuudessa siten, että ohjelmaan voidaan asettaa katkokohtia (breakpoints), ohjelman muuttujien arvoja voidaan tulostaa ja muuttaa jne. Tarkoituksena on yleensä löytää "luteet" (bugs) eli selvittää, miksi ohjelma toimii väärin.

Aiemmin käsiteltiin väärin tai oudosti toimivaa ohjelmaa yleensä siten, että siihen lisättiin välitulostuksia. Nykyisin tämä on yleensä tarpeetonta, koska tutkintaohjelmat mahdollistavat muuttujien arvojen tulostamisen muuttamatta käyttäjän ohjelmaa.

Tyypillisesti tutkinnassa ensin asetetaan ohjelmaan muutamia katkokohtia, käynnistetään ohjelma ja tulostellaan muuttujien arvoja, kunnes selviää, missä kohdassa menee pieleen. Jos ohjelma on iso, saadaan näin selville aluksi vain virheen karkea sijainti - siis minkä katkokohtien välissä tapahtuu jotain outoa. Sen jälkeen kyseisten katkokohtien väliin asetetaan muutamia katkokohtia ja ajetaan ohjelma uudestaan. Näin jatketaan, kunnes virhe saadaan paikannetuksi. Tämän prosessin loppuvaiheessa voi olla kätevämpää ajaa ohjelmaa rivi kerrallaan kuin asettaa enää katkokohtia.

Käytettävissä on tietokoneesta ja ohjelmointikielestä riippuen erilaisia tutkintaohjelmia.

Miten ohjelma on käännettävä?

Tutkintaohjelman käyttö edellyttää, että käännösvaiheessa annetaan optio -g. Lisäksi on Fortrania käytettäessä erittäin suositeltavaa antaa optio -C, joka aiheuttaa sen, että kääntäjä tuottaa koodin, joka tarkistaa taulukoiden ja alimerkkijonojen indeksit. Tätä valitsinta voi käyttää varsinaisesta tutkinnasta riippumattakin, mutta silloin virhetilanteissa saatava ilmoitus on aika hämärä, kuten tutkintaesimerkki osoittaa.

Esimerkki:

f77 -gC paa.f ali1.f ali2.f

Tutkinnan aloitus

Tutkinta käynnistetään komennolla

dbx ohjelma

missä ohjelma on sen tiedoston nimi, joka sisältää suoritusvalmiin ohjelman, esimerkiksi

dbx a.out

Käynnistyessään tutkintaohjelma tulostaa seuraavantapaista:

 
dbx version 3.1 for AIX.
Type 'help' for help.
reading symbolic information ...
(dbx)
Tässä (dbx) on tutkintaohjelman kehote (prompt), joka tarkoittaa, että se on valmis ottamaan vastaan komentoja käyttäjältä.

Jos ohjelman ajaminen normaalisti (siis ilman tutkintaohjelmaa) on katkennut ajonaikaiseen virheeseen, joka on tuottanut muistivedoksen (core dump, tiedosto nimeltä core), niin dbx osaa lukea muistivedoksen. Täten voidaan tutkia ohjelman tilaa virheen jälkeen. Tosin sisäisten virherutiinien kutsut aiheuttavat sen, että muuttujien arvojen tulostamisessa on vaikeuksia. Lisäksi on huomattava, että koneessa saattaa muistivedosten muodostuminen olla oletusarvoisesti estetty (asetuksella limit coredumpsize 0).

Tutkintakomennot

Ohjelman ajaminen ja jäljitys

Tiivistelmä:
run
käynnistää ohjelman
cont
jatkaa ohjelman suoritusta
trace
tulostaa aliohjelmien kutsuketjun
stop
asettaa katkokohdan
status
kertoo katkokohdat ja jäljitystilanteen
delete
poistaa katkokohdan tai jäljityksen
step
suorittaa seuraavan rivin
next
suorittaa seuraavan rivin kokonaisuutena.
Huomautuksia:

Tiedon käsittely

Tiivistelmä:
print
tulostaa lausekkeen (esim. muuttujan) arvon
whatis
tulostaa muuttujan määrittelyn
whereis
kertoo tunnuksen eri merkitykset ohjelmassa
assign
antaa muuttujalle arvon; käsky on muotoa assign muuttuja = lauseke
Myös taulukoita voidaan tulostaa print-käskyllä. Jos halutaan tulostaa koko taulukko, annetaan argumenttina vain sen nimi. Jos halutaan tulostaa osa taulukosta, kirjoitetaan argumentiksi taulukon nimi ja suluissa indeksin alaraja, kaksi pistettä ja yläraja, esimerkiksi

print tbl(5..10)

Samaa periaatetta voi soveltaa moniulotteisiinkin taulukoihin, esim.

print matr(3..5,1..8)

Aliohjelmien käsittely

Tiivistelmä:
where
näyttää aliohjelmien kutsuketjun
dump
tulostaa paikallisten muuttujien nimet ja arvot.
dump-käskyä on syytä käyttää harkiten: se on kätevä silloin, kun paikallisia muuttujia on vähän. Ota huomioon, että taulukot tulostuvat alkioittain. Jos ollaan pääohjelmassa, dump tulostaa sen muuttujat.

Muut komennot

Tiivistelmä:
sh
antaa komentorivin komentotulkille (shell)
alias
asettaa tutkintakomennolle synonyymin
help
tulostaa tutkintakomentojen luettelon ja selitykset
source
lukee tutkintakomentoja tiedostosta
quit
lopettaa tutkinnan.

Ohjelmatiedostojen käsittely

Tiivistelmä:
edit
aloittaa ohjelmatiedoston editoinnin
file
vaihtaa ohjelmatiedostoa
func
vaihtaa aliohjelmaa
list
tulostaa ohjelmarivejä
use
määrittelee, mistä ohjelmatiedostoja tulee hakea
/xxx
etsii tiedostosta merkkijonoa xxx
?xxx
etsii taaksepäin tiedostosta merkkijonoa xxx
Kahdessa viimeksi mainitussa voi xxx:nä olla merkkijonon asemesta yleisemmin ns. säännöllinen lauseke (regular expression, regexp).

list-käsky tulostaa ilman argumenttejakin yleensä joitakin "sopivia", tilanteeseen liittyviä rivejä, mutta rivit voi aina määrätä kirjoittamalla rivinumeron, pilkun ja toisen rivinumeron, esim. list 120,135

Lausekkeet

Tutkintaohjelmalle annettavien lausekkeiden (esim. assign-käskyssä) tulee olla C-kielen mukaisia. Kuitenkin jakoviiva / tarkoittaa aina reaalilukujakolaskua, ja kokonaisjako ilmaistaan operaattorilla div (kuten Pascalissa); esim. lausekkeen 20 div 3 arvo on 6.

Jos ohjelmasi on kirjoitettu Fortranilla, ota siis huomioon, että C-kielessä ja Fortranissa käytetään erilaisia vertailuoperaattoreita:

vertailuoperaattori             Fortranissa     C:ssä

yhtäsuuri kuin                  .EQ.            ==
erisuuri kuin                   .NE.            !=
pienempi kuin                   .LT.            <
suurempi kuin                   .GT.            >
pienempi tai yhtäsuuri kuin     .LE.            <=
suurempi tai yhtäsuuri kuin     .GE.            >=
Huomaa erityisesti, että C:ssä yhtäsuuruusvertailu esitetään kahdella yhtäläisyysmerkillä.

Tutkintaesimerkki

Seuraavassa on esimerkki tutkintaohjelman käytöstä ohjelman virhetilanteen paikantamiseen. On huomattava, että näin saadaan selville virheen välitön syy (tässä taulukon ylivuoto) ja se, missä ja miten se sattui - ei sitä, miten siihen joudutaan eli mitä ohjelman logiikassa on pielessä. - Selitykset ovat esimerkkiajon jälkeen.

leka 51 % xlf -O looppi.f
** _main   === End of Compilation 1 ===
1501-510  Compilation successful for file looppi.f.
leka 52 % a.out >tulos
5
Segmentation fault
leka 53 % xlf -C looppi.f
** _main   === End of Compilation 1 ===
1501-510  Compilation successful for file looppi.f.
leka 54 % a.out >tulos
5
Trace/BPT trap
leka 55 % xlf -C -g looppi.f
** _main   === End of Compilation 1 ===
1501-510  Compilation successful for file looppi.f.
leka 56 % dbx a.out
dbx Version 3.1
Type 'help' for help.
reading symbolic information ...
(dbx) run
 ANNA I
5
           4 
           4 

trace trap in _main at line 8
    8            N(J)=N(J)+N(J-1)
(dbx) print j
6 
(dbx) print n
(1)	0
(2)	0
(3)	4
(4)	4
(5)	4
 
(dbx) list 5,10
    5         J=I-1
    6         N(J-1) = J
    7    2    IF(J.GT.1) THEN
    8            N(J)=N(J)+N(J-1)
    9            J=J+1
   10            WRITE(6,*)N(J-1)
(dbx) quit
leka 57 % 

Mitä oikein tehtiin:

Tämä oli tietenkin alkeellinen esimerkki (ilman katkokohtien asettamista tms., jota tarvitaan silloin, kun virhe ei paikannu yhtä yksinkertaisesti kuin tässä) mutta osoittanee sen, että tutkinta on huomattavan helppoa.

Ohjelmointi Fortran-kielellä

Perusasioita Fortran-ohjelmien ajamisesta

Tässä kappaleessa annetaan ohjeita Unixeissa Fortranilla ohjelmoiville. Fortran-ohjelmointikielen joutuu opettelemaan muualta. Fortraniin liittyvää tietoa (mm. Fortran-77-standardi ja useita oppikirjantapaisia esityksiä Fortranista) löytyy dokumentin Tietoa Fortran-ohjelmointikielestä Internetistä kautta.

Fortran-ohjelman kirjoittaminen ja editointi

Fortran-ohjelmatiedostot nimetään niin, että nimi loppuu merkkeihin .f (piste ja pieni f-kirjain). Tämä on tarpeen, jotta kääntäjä käsittelisi tiedoston oikein. Lisäksi siitä on se etu, että käytettäessä Emacsia editori osaa asettua ns. Fortran-moodiin, mikä merkitsee mm. seuraavaa:

Lisätietoja Fortran-moodista saa esim. Emacsista itsestään, kun sen ollessa Fortran-moodissa antaa näppäinyhdistelmän control-H m. Emacsin hienouksista on tietoja myös GNU Emacs Manualissa, joka löytyy atk-keskuksen kirjastosta.

Unixissa voi Fortran-ohjelmassa käyttää isoja tai pieniä kirjaimia tai molempia: voi kirjoittaa CONTINUE tai continue tai Continue tai vaikka cOnTINue. Huomaa, että sama ei koske Unixin komentoja eikä tiedostonnimiä - niissä isojen ja pienten kirjainten ero on merkitsevä!

Tavallisinta lienee käyttää pieniä kirjaimia; jos ohjelma on siirretty muusta ympäristöstä ja on kirjoitettu isoin kirjaimin, voi olla hyvä idea pitää alkuperäinen koodi isokirjaimisena mutta tehdä muutokset ja lisäykset pienikirjaimisina.

Fortran-kääntäjät

Unix-koneissa mahdollisesti olevilla Fortran-kääntäjillä on eroa, mutta yhteisiä piirteitä ovat yleensä seuraavat:

Fortran-ohjelman kääntäminen ja ajaminen

Ohjelma yhdessä tiedostossa

Jos Fortran-ohjelma on yhdessä tiedostossa, se voidaan kääntää komennolla

f77 nimi

missä nimi on ohjelmatiedoston nimi (jonka on syytä loppua merkkeihin .f). Usein kannattaa kuitenkin antaa komennossa yksi tai useampia optioita.

Tämä komento myös lataa ohjelman tuottaen ajokelpoisen ohjelman a.out-nimiseen tiedostoon. Tämän jälkeen ohjelma voidaan käynnistää komennolla a.out edellyttäen, että voimassa ovat sopivat ympäristömäärittelyt. (Yleisessä käytössä olevissa koneissa tällaiset määrittelyt ovat yleensä automaattisesti voimassa. Jos näin ei ole, voidaan käyttää komentoa ./a.out tai yleisemmin ./x, missä x on ajokelpoisen ohjelman nimi.)

Ohjelma useassa tiedostossa
Jos ohjelma on jaettu useaan tiedostoon, voidaan ensinnäkin menetellä siten, että kaikki ohjelmatiedostot luetellaan yhdessä f77-komennossa erottaen niiden nimet välilyönneillä, esim.

f77 paa.f ali1.f ali2.f ali3.f

Jos käännös menee läpi virheittä, syntyy ajokelpoinen ohjelma tiedostoon a.out.

Tämä on kuitenkin usein epäkäytännöllistä ohjelmankehittelyssä, koska aina ei ole tarpeen kääntää uudestaan kaikkia ohjelmatiedostoja. Voidaan menetellä niin, että käännetään kerralla vain yksi tai muutama ohjelmatiedosto esim. seuraavaan tapaan:

f77 -c ali1.f ali2.f
f77 -c ali3.f
f77 paa.f ali1.o ali2.o ali3.o
Tällöin ensimmäisessä vaiheessa syntyvät käännöstiedostot (objektikooditiedostot) ali1.o ja ali2.o ja toisessa vaiheessa ali3.o. Viimeisessä vaiheessa sitten käännetään vain tiedosto paa.f, mutta myös aiemmin muodostetut käännöstiedostot on mainittava f77-komennossa. Viimeisessä vaiheessa syntyy taas ajokelpoinen ohjelma a.out.

Edellä esitetyissä komennoissa optio -c ilmoittaa, että ohjelmaa ei pidä yrittääkään vielä ladata. Jos unohdat kirjoittaa option -c, saat ilmoituksia, jotka johtuvat siitä, että käännettävät tiedostot eivät muodosta kokonaista ohjelmaa (esim. pääohjelma puuttuu). Ilmoitukset näyttävät virheilmoituksilta (ERROR: Unresolved or undefined symbols detected), mutta ne eivät ole mitenkään vakavia, vaan voit jatkaa normaalisti.

Jos ohjelmatiedostoja on paljon, kannattaa opetella käyttämään make-komentoa (ks. kohtaa 6 Ohjelmien hallinta).

Kääntäjän optiot

Fortran-kääntäjillä on lukuisia optioita (valitsimia), jotka ovat usein varsin hyödyllisiä. Optiot annetaan kääntäjän nimen f77 ja tiedostonnimien välissä, ja kukin optio alkaa yhdysviivalla (-).

Esimerkiksi IBM:n Unix-toteutuksen (Aix) Fortran-kääntäjän optioista mainittakoon seuraavat:

-qsource
Aiheuttaa mm. sen, että päätteelle tulostuviin virheilmoituksiin tulee mukaan itse virheellisen rivin sisältö (eikä pelkkää rivi- ja sarakenumeroa) ja että muodostuu käännöslistaus. Listaustiedoston nimen kääntäjä muodostaa ohjelmatiedoston nimestä korvaamalla loppu-f:n merkeillä lst.
-u
Aiheuttaa sen, että kaikkien muuttujien tyyppien tulee olla erikseen määriteltyjä (ei siis alkukirjainsäännön eikä IMPLICIT-lauseen perusteella). Tämä vastaa sitä, että jokaisessa ohjelmayksikössä olisi lause IMPLICIT NONE. Option avulla voidaan usein havaita kirjoitusvirheistä johtuvia ongelmia.
-O
Optimointioptio, joka yleensä lyhentää ohjelman suoritusaikaa varsin merkittävästi. Optimointioption käyttö on suositeltavaa, ellei kyse ole pienestä kokeilu- tms. ohjelmasta.
-lmsaa
Tämän option ansiosta saadaan ajonaikaiset virheilmoitukset tilanteista, joissa matemaattista standardifunktiota on kutsuttu argumentilla, joka aiheuttaa laskennassa virhetilanteen.
-o
Tämän option avulla voidaan antaa ajokelpoiselle ohjelmalle haluttu nimi.
-qrndsngl
Aiheuttaa sen, että ohjelma laskee yksinkertaisella tarkkuudella ne liukulukulausekkeet, joiden operandit ovat yksinkertaista tarkkuutta.
-g
Tämä optio tarvitaan, jos ohjelman toimintaa halutaan tarkastella tutkintaohjelmalla eli debuggerilla.
Seuraavassa on kaksi esimerkkiä eri tilanteisiin sopivien optioiden antamisesta. Kummassakin oletamme yksinkertaisuuden vuoksi, että koko ohjelma on yhdessä tiedostossa ohj.f.

Ohjelman kehittelyvaiheessa:

f77 -qsource -u -g -lmsaa ohj.f

Tehtäessä ohjelmasta "tuotantoversio":

f77 -o ohj -O -lmsaa ohj.f

Syöttö ja tulostus Fortran-ohjelmissa

Rivinvaihdon ohjaus

Rivikirjoitintulostuksessa Fortran-ohjelmasta kunkin rivin ensimmäinen merkki on ns. lomakkeenohjauskoodi: se ei tulostu vaan ohjaa rivinvaihtoa: välilyönti aiheuttaa normaalin rivinvaihdon, numero 0 kaksi rivinvaihtoa jne. Hyvin usein Fortran-ohjelmien tulostuslauseet ja formaatit kirjoitetaan tämän mukaisesti, ja siirrettävyyssyistä se onkin järkevää.

Rivikirjoitintulostusta ei kuitenkaan juurikaan enää käytetä, eikä useimpiin Unix-koneisiin edes ole liitetty perinteisiä rivikirjoittimia, vaan tulostus hoidetaan laserkirjoittimilla. Niille taas ei tulosteta suoraan vaan ohjaamalla tulostus tiedostoon ja sitten lähettämällä tiedosto kirjoittimelle sopivalla komennolla.

Monissa järjestelmissä lomakkeenohjauskoodit ovat voimassa ainakin rajoitetusti myös päätteelle tulostettaessa. Unix-järjestelmissä näin ei yleensä ole.

Esimerkiksi IBM:n Unix-toteutuksessa (Aix) lomakkeenohjauskoodien toimintaa voidaan kuitenkin simuloida käyttämällä Aixin pientä apuohjelmaa asa. Esimerkkejä käyttötavoista:

xyz | asa
suorittaa ohjelman siten, että sen tulostus päätteelle muotoutuu lomakkeenohjauskoodien mukaisesti
asa rslts
tulostaa päätteelle tiedoston rslts lomakkeenohjauskoodien mukaisesti
asa rslts | enscript
tulostaa laserkirjoittimelle tiedoston rslts lomakkeenohjauskoodien mukaisesti.

Kanavannumeroiden merkityksen määrittely

Jos kanavannumerolle halutaan muu kuin em. oletusmerkitys, voidaan kanavannumeron ja tiedoston vastaavuus esittää

Edellinen sopii käytettäväksi varsinkin silloin, kun ohjelma käyttää kiinteännimisiä tiedostoja. Unixissa kirjoitetaan tällöin tiedostonnimi sellaisenaan OPEN-lauseen FILE-argumenttiin heittomerkkien sisään, esim.

OPEN(UNIT=10,FILE='input.dat')

Jos kuitenkin halutaan esim. käsitellä samalla ohjelmalla useita erinimisiä tiedostoja, on joustavampaa antaa tiedostomäärittelyt ohjelman ulkopuolella. Tätä varten on kussakin käyttöjärjestelmässä omat komentonsa.

Unixissa voidaan e.m. tarkoitukseen käyttää erilaisia välineitä, joista yleiskäyttöisin on seuraavassa kuvattava tapa, joka perustuu ns. symbolisten linkkien käyttöön. Tällöin käytetään esimerkiksi muotoa

ln -s nimi fort.n

olevaa komentoa, missä n on kanavannumero ja nimi on haluttu tiedostonnimi, esimerkiksi

ln -s input.data fort.1

Tässä oletettu vastaavuus, jossa Fortranin ns. kanavannumeroa n vastaa tiedostonnimi fort.n, ei mitenkään välttämättä päde kaikissa järjestelmissä ja on ymmärrettävä lähinnä esimerkiksi. Tarkista asia kääntäjäkohtaisista ohjeista!

Tämä komento luo tiedostolle input.data toisen, rinnakkaisen nimen fort.1. Voimme myös sanoa, että se luo uuden tiedoston fort.1, joka kuitenkin on pelkkä "symbolinen linkki" tiedostoon input.data.

Ohjelman ajamisen jälkeen on symbolinen linkki syytä poistaa komennolla

rm fort.n

Muutoin nimittäin ei uusi ln-komento samalle kanavalle onnistukaan. Komennossa voidaan (erityisesti jos se esiintyy komentotiedostossa) antaa optio -f, jolloin komento ei "valita", vaikka kyseiselle nimelle ei olisi olemassa symbolista linkkiä. Huomaa, että symboliseen linkkiin kohdistettava rm-komento ei poista sitä tiedostoa, johon linkki viittaa, vaan vain linkin.

Symbolisella linkillä asetettu tiedostomäärittely on voimassa, kunnes se erikseen poistetaan rm-komennolla. Huomaa, että esim. yhteyden katkaisu (logout) ei poista symbolisia linkkejä, koska ne ovat tiedostojärjestelmään eivätkä vain pääteistuntoon liittyviä asioita.

Edellä esitetyllä tavalla asetetut, voimassaolevat symboliset linkit saa selville sellaisella ls-komennolla, jossa on optio -l, esimerkiksi

ls -l fort.*

Unixissa myös laitteisiin viitataan tiedostonnimillä. Tärkeimmät tällaiset nimet ovat

/dev/tty
käyttäjän pääte
/dev/null
"olematon laite"
Täten esimerkiksi tulostus kanavalle 12 voidaan ohjata päätteelle komennolla

ln -s /dev/tty fort.12

On kuitenkin huomattava, että tällöin tulostus on puskuroitua, ja päätteeltä lukemisen ja päätteelle tulostamisen järjestys ei välttämättä ole todellisuudessa sama kuin ohjelmakoodissa. Jos ohjelma esim. tulostaa kanavalle 12 ja sen jälkeen lukee päätteeltä, käy todennäköisesti niin, että se odottaa syöttötietoja ennen tulostamista.

Kanavannumeroiden oletusmerkitykset

Fortran-ohjelmissa tiedostoihin viitataan tunnetusti ns. kanavannumeroilla (unit numbers). Suosittelemme, että käytetään numeroita väliltä 1 - 99, joskin monissa järjestelmissä voidaan käyttää muitakin numeroita.

Jos kanavannumeron merkitystä ei muutoin ilmoiteta, niin Unix-järjestelmien Fortraneissa

Numeerinen laskenta Fortranissa

Laskenta aina kaksoistarkkuudella Aix-koneissa

IBM:n Aix-koneet suorittavat liukulukulaskennan aina kaksinkertaisella tarkkuudella. Tietenkin jos laskennan tulos tallennetaan REAL-tyyppiseen muuttujaan, tarkkuutta katoaa. Yleensä uusia ohjelmia tehtäessä kannattaa käyttää kaksoistarkkuuden reaalilukutyyppiä DOUBLE PRECISION.

Kaksinkertainen tarkkuus aiheuttaa joskus yllätyksiä etenkin, jos ohjelmassa pyritään laskemalla määrittämään joitakin koneen aritmetiikan ominaisuuksia. Esimerkiksi seuraava funktio (joka on peräisin kirjasta Fortran 77) ei toimi halutulla tavalla Aix-koneissa:

      REAL FUNCTION EPS()
      EPS = 1
100   EPSNEW = EPS/2
      IF (1+EPSNEW.EQ.1) RETURN
      EPS = EPSNEW
      GOTO 100
      END

Tarkoitus on, että funktio määrittää kone-epsilonin, so. pienimmän positiivisen reaaliluvun epsilon, jolle 1+epsilon on ykkösestä poikkeava. Aix-koneessa kuitenkin funktio palauttaa kaksoistarkkuuden laskentaa vastaavan kone-epsilonin, vaikka käytetyt muuttujat olisivat REAL-tyyppisiä! Tämä johtuu siitä, että kone käyttää ehdon 1+EPSNEW.EQ.1 laskennassa kaksoistarkkuutta. Näin ei kävisi, jos esim. sijoitettaisiin lausekkeen 1+EPSNEW arvo REAL-tyyppiseen apumuuttujaan ja käytettäisiin sitä IF-lauseessa. Helpompi tapa estää tämäntapaiset yllätykset on kuitenkin käyttää kääntäjän optiota

-qrndsngl

joka aiheuttaa sen, että kone laskee yksinkertaisella tarkkuudella sellaiset liukulukulausekkeet, joiden operandit ovat yksinkertaista tarkkuutta.

Nelinkertaisen tarkkuuden luvut

XL Fortranissa (IBM:n Aix-koneiden Fortran) on tyyppi REAL*16 (ja XL C:ssä vastaava tyyppi long double).

Nelinkertaisen tarkkuuden lukuvakioissa käytetään eksponenttikirjaimena Q:ta, joten esim. 1.0Q0 esittää lukua yksi nelinkertaisen tarkkuuden vakiona.

Lukualueet

Aix-koneissa kokonaisluvut ovat 32-bittisiä, joten kokonaislukujen arvoalue on -maxint-1 .. +maxint, missä

maxint = 2**31 - 1 = 2147483647

Aix-koneissa on käytössä IEEE-standardin mukainen reaalilukujen esitys.

Seuraava taulukko esittää eri reaalilukutyyppien lukualueet (pienin positiivinen reaaliluku ja suurin reaaliluku) Aix-tietokoneissa. Lukuarvot ovat tietysti pyöristettyjä. Käytämme tässä reaalilukutyypeistä epästandardeja IBM-tyyppisiä nimiä, joita XL Fortran ymmärtää: REAL*4 on sama kuin REAL ja REAL*8 sama kuin DOUBLE PRECISION, kun taas REAL*16 on standardiin kuulumaton nelinkertaisen tarkkuuden reaalilukutyyppi.

Tyyppi   Lukualue Aix-koneissa

REAL*4   1.175*E-38 .. 3.403E+38   

REAL*8   2.225D-308 .. 1.798D+308  

REAL*16  4.941Q-324 .. 1.798Q+308  

Laskentatarkkuus Aix-koneissa

Kone-epsilon (pienin liukuluku, joka ykköseen lisättynä tuottaa ykkösestä poikkeavan tuloksen) on:

laskentatarkkuus           kone-epsilon Aix-koneissa	

yksinkertainen tarkkuus    1.192E-7
kaksinkertainen tarkkuus   2.220D-16
nelinkertainen tarkkuus    4.940Q-324

Ylivuodot ja muut poikkeustilanteet

Yleensä Aix-koneet eivät anna mitään ilmoituksia ylivuodoista, alivuodoista, nollalla jakamisista yms. numeerisen laskennan poikkeustilanteista (virhetilanteista).

Reaalilukuoperaatio, joka on matemaattisesti määrittelemätön tai jonka tulos on koneen lukualueen ulkopuolella, tuottaa IEEE-standardin mukaisen suureen "infinity", "not a number" tms., joka formatoidusti tulostettuna ei näy lukuna vaan symbolisena merkintänä NaNQ, INF tms.

Tavallisimpien aritmeettisten virheiden käsittely on tarkemmin sanottuna seuraava:

Jos halutaan saada selville esim. matemaattisten funktioiden laskennan virheitä, kannattaa lisätä f77-komentoon optio -lmsaa, koska sen ansiosta saadaan ajonaikaiset virheilmoitukset tilanteista, joissa matemaattista standardifunktiota on kutsuttu argumentilla, joka aiheuttaa laskennassa virhetilanteen. Virhetilanteita aiheuttavat esimerkiksi SQRT-funktion kutsuminen negatiivisella argumentilla ja EXP-funktion kutsuminen niin suurella argumentilla, että tulos ei mahdu lukualueeseen.

Fortran HP-koneissa

Tiedostojen käsittelyssä Fortranilla HP/UX-työasemissa on huomattava seuraavat seikat:

Jos edellä mainittua ohjetta kirjoittamisen lopettamisesta ENDFILE-lauseella ei noudateta, niin tiedoston loppuun jää ylimääräinen nollatavu (NUL-merkki), mikä voi aiheuttaa ongelmia tiedostoa luettaessa.

Kääntäjä tukee monia epästandardeja piirteitä, mm. nelinkertaisen tarkkuuden reaalilukuja (REAL*16).

Kääntäjän optiolla -a voi pyytää ilmoituksia epästandardien piirteiden käytöstä.

Tavallisia virheitä Fortran-ohjelmissa

Seuraavassa on lista tavallisista syistä, joiden takia Fortran-ohjelma ei toimi oikein.

  1. Aliohjelman kutsu on vääränlainen, esimerkiksi

  2. COMMON-alueella on erilaiset määrittelyt ohjelman eri osissa. Vaikka tämä on joissakin tapauksissa sallittua, yleensä se aiheuttaa pahoja sotkuja. Huomaa, että muuttujien järjestys COMMON-määrittelyssä on olennainen, toisin kuin tavallisissa muuttujien määrittelyissä.

  3. Ohjelmarivi on pitempi kuin 72 merkkiä. Kääntäjä tulkitsee rivin loppuosan kommentiksi!

  4. Ohjelmassa voi olla yksinkertaisia kirjoitusvirheitä, joita kääntäjä ei havaitse. Klassillinen esimerkki:

    DO 100 I = 1. 10

    missä pitäisi olla pisteen tilalla pilkku. (Kääntäjä tulkitsee lauseen sijoituslauseeksi, joka antaa muuttujalle DO100I arvon 1.10, sillä välilyönnit eivät ole merkitseviä.) Toinen esimerkki:

    INTEGER FOO, ZAP BAR

    mistä oletettavasti puuttuu pilkku ZAPin ja BARin välistä, mutta kääntäjä käsittelee lauseen muodollisesti oikeana lauseena, joka määrittelee muuttujat FOO ja ZAPBAR.

  5. Taulukko vuotaa yli, t.s. ohjelma viittaa taulukkoon käyttäen indeksiä, joka ei ole määritellyissä rajoissa. Useissa kääntäjissä on optio (usein -C), jolla voidaan pyytää sitä tuottamaan automaattiset ajonaikaiset indeksitarkistukset, joilla näitä virheitä voi havaita.

Ohjelmointi C-kielellä

Yleistä C-ohjelmien ajamisesta

Unix-koneissa C-kääntäjän nimenä on tavallisimmin cc, jolloin käyttöohjeet saa komennolla man cc. Käytössä voi olla tämän lisäksi muitakin C-kääntäjiä, erityisesti Gnu-C, nimellä gcc.

Jos ohjelma käyttää matematiikkakirjaston math.h funktioita, täytyy (sen lisäksi, että itse ohjelmassa on direktiivi #include <math.h>) käyttää cc-komennon lopussa optiota -lm, esim.
cc ohj.c ali1.c ali2.c -lm

Aix-koneissa voidaan -lm-option asemesta käyttää myös optiota -lmsaa, jolloin saadaan ajonaikaiset virheilmoitukset esim. ylivuodoista matemaattisten funktioiden laskemisessa.

Isoja, paljon keskusyksikköaikaa kuluttavien C-ohjelmien kääntämisessä kannattaa käyttää optimointioptiota -O, joka varsinkin Aix-koneissa voi huomattavasti nopeuttaa ohjelman suoritusta.

C-ohjelmoinnin apuvälineitä

Käytettävissä saattavat olla seuraavat C-ohjelmoinnin apuvälineet:

lint
Tekee melko monipuolisia tarkistuksia. Käyttö on erittäin suositeltavaa.
cflow
Tuottaa C-ohjelmasta rakennekaavion.
cxref
Tekee C-ohjelmasta ristiviitelistan (cross-reference listing) ns. ulkoisista viittauksista.
cb
Muotoilee C-ohjelman uudelleen käyttäen systemaattista sisennystä.
Syynä lint-ohjelman suositteluun on mm. se, että C-kääntäjän tekemät tarkistukset ovat melko vähäisiä. Hankaluuksia lintin kanssa tuottaa usein se, että se antaa ilmoituksia (varoituksia) turhan herkästi. Usein kannattaa käyttää optiota -u, joka aiheuttaa sen, ettei lint anna ilmoitusta muuttujista ja funktioista, jotka on määritelty mutta joita ei käytetä missään.

Lisäksi on huomattava, että lint saattaa käsitellä ohjelman C-kielen vanhemman määrittelyn mukaisesti, joten ANSI C:n mukaisesta ohjelmasta se voi antaa paljonkin harhaanjohtavia ja suorastaan virheellisiä ilmoituksia.

Lisätietoja saa käsikirjoista ja man-komennolla.

Vastauksia usein esitettyihin kysymyksiin

Joitakin asioita kysytään yhä uudelleen, joten nyyseissä on koottu ns. "Answers to Frequently Asked Questions" -listoja, johon on mietitty hyvät vastaukset valmiiksi. C-kielen FAQ-lista on Webissä osoitteessa
http://www.eskimo.com/~scs/C-faq/top.html
se on jaettu osiin seuraavasti:

  1. Declarations and Initializations
  2. Structures, Unions, and Enumerations
  3. Expressions
  4. Pointers
  5. Null Pointers
  6. Arrays and Pointers
  7. Memory Allocation
  8. Characters and Strings
  9. Boolean Expressions and Variables
  10. C Preprocessor
  11. ANSI/ISO Standard C
  12. Stdio
  13. Library Functions
  14. Floating Point
  15. Variable-Length Argument Lists
  16. Strange Problems
  17. Style
  18. Tools and Resources
  19. System Dependencies
  20. Miscellaneous

Lisää C-kieleen liittyvää tietoa löytyy Webistä mm. sivun Tietoa C-kielestä (ja C++:sta) Internetissä kautta.

Ohjelmointi Pascal-kielellä

Toteutusten eroista

Pascal- kielen toteutukset Unix-koneissa poikkeavat usein huomattavasti mikrojen Pascal-toteutuksista, esim. Turbo Pascalista, koska viimeksi mainitut poikkeavat kielen standardista. Tämän takia esim. Turbo Pascal -ohjelman siirtäminen Unix-koneeseen voi olla varsin työlästä.

Yleisesti jos olet siirtämässä Pascal-ohjelmaa muusta koneesta, on syytä huomata, että varsinkin mikrojen Pascal-toteutukset sisältävät monia kielen laajennuksia, jotka eivät ole yhteensopivia muiden toteutusten kanssa. Esimerkiksi ne proseduurit yms., joilla saadaan aikaan graafinen tulostus, ovat yleensä täysin konekohtaisia.

Tiedostojen liitännät

Tiedostojen liitäntä (ohjelman käyttämien tiedostotyyppisten muuttujien ja fyysisten tiedostojen vastaavuus) on oletusarvoisesti yleensä seuraava:

Joissakin toteutuksissa tiedostomuuttujan voi liittää haluamaansa tiedostoon määrittelemällä ympäristömuuttujan, jolla on sama nimi kuin tiedostomuuttujalla ja jonka arvo on haluttu tiedostonnimi. Esimerkki:
setenv filevariable filename

Joissakin toteuksissa liitännän voi tehdä myös itse ohjelmassa käyttämällä Reset- tai Rewrite-proseduurin kutsussa toista parametria, joka on merkkijonotyyppinen ja sisältää määritteen name=tiedostonnimi. Sanan name voi kirjoittaa isolla tai pienellä. Esimerkki:
Rewrite(filevariable,'name=filename');

Ensin mainittu tapa, jos järjestelmä tukee sitä, on yleensä suositeltavampi, koska silloin liittäminen tapahtuu itse ohjelman ulkopuolella eikä epästandardilla rakenteella ohjelmassa. Huomaa, että mainittu Reset- tai Rewrite-proseduurin laajennettu kutsu on käytettävissä useissa Pascal-järjestelmissä mutta yksityiskohdiltaan vauhtelevana (varsin usein toinen parametri on pelkkä tiedostonnimi), joten ohjelma ei ole sellaisenaan siirrettävä.