Pääteohjaus 2
Seuraavien harjoitusten tarkoituksena on opettaa ohjelmointiympäristön käyttöä. Itse C-kielisten ohjelmien syntaksiin
ei vielä ole syytä takertua liiaksi.
Tässä harjoituksessa opittavat asiat tulevat hyödyksi ohjelman koodaamisessa ja testaamisessa. Itse ohjelman suunnittelun kanssa tällä harjoituksella ei ole mitään tekemistä!
Ohjelman kirjoittaminen ja kääntäminen
Jos olet Windowsissa, on tämä harjoitus vielä parasta tehdä
DOSista käsin. Siis aukaise yksi DOS-ikkuna 2-näpäyttämällä
DOS-ikonia.
Siirry omaan hakemistoosi (C:\OMAT\OHJELMOI\tunnus). Jos
hakemistoa ei ole, luo hakemisto.
Katso DIR-komennolla mitä tiedostoja on hakemistossa.
Kirjoita Borland C:llä seuraava C-ohjelma nimelle JARJ2.C
(käynnistyy komennolla BC jarj2.c[RET]). Yritä saada vastaavat sisennykset ja ole tarkkana kirjainten 1 (yksi), i (ii, india) ja l (ällä, lima) suhteen. Myös isojen ja pienten kirjainten kanssa on syytä olla tarkkana! Jos huomaat
mallissa kirjoitusvirheitä, niin älä korjaa niitä nyt, koska
tarkoituksena on opetella tulkitsemaan kääntäjän virheilmoituksia.
jarj2.c
Mitä luulet ohjelman tulostavan?
Talleta valmis ohjelma ([F2]).
Käännä ohjelma ([Alt-C]M tai [Alt-F9]).
Mikäli sait ohjelman kirjoitettu aivan vastaavasti kuin mallissa, ilmestyy ruudun alalaitaan "MESSAGE"-ikkuna, johon
tulee tekstit:
Compiling JARJ2.C:
Error JARJ2.C 7: Undefined symbol 'd'
Error JARJ2.C 7: Function call missing )
Error JARJ2.C 7: Unterminated string or character constant
Warning JARJ2.C 9: Possible use of 'x1' before definition
Error JARJ2.C 12: Undefined symbol 'T'
Error JARJ2.C 15: Statement missing ;
Warning JARJ2.C 16: Function should return a value
Warning JARJ2.C 16: 't' is assigned a value that is never
used
Liikuttamalla kursoria ylös ja alaspäin virheikkunassa, nähdään virheiden paikat (likimäärin!) ohjelmakoodissa. Kokeile!
Siirry ensimmäisen virheen kohdalle ja paina [RET].
Huomaat varmaakin, että värit osoittavat jotakin ohjelmakoodissa. Mitä? Värit auttavat paikallistamaan useita virheitä.
Korjaa virhe! Virhe ei välttämättä ole kursorin kohdalla,
vaan se vasta paljastuu siinä kohdassa. Sama virhe saattaa
poikia useita eri virheilmoituksia!
Paina [Alt-F8] kunnes olet seuraavassa todellisessa
virheessä. Korjaa ja jatka kunnes kaikki virheet on korjattu.
Käännä ohjelma uudelleen.
Talleta korjattu ohjelma.
Aja ohjelma ([Alt-R]R). Ohjelman tulostuksen saat uudelleen näkyviin painamalla [Alt-F5] tai voit avata uuden ikkunan tulostusta varten ([Alt-W]O ja siirrä
ikkunan hiirellä sopivaksi).
Borland C-editorin käyttöohjeet
Ikkunat
Borland-C ympäristö on suurinpiirtein seuraavan näköinen:
= File Edit Search Run Compile Debug Project Options Window Help
+-[o]-------------------+------------------------+-----------------------1-[ ]-+
|/* Ohjelma järjestää ka| Run Ctrl-F9 |seen. */
|#include <stdio.h> | Program reset Ctrl-F2 |
| | Go to cursor F4 |
|int main(void) | Trace into F7 |
|{ | Step over F8 |
| int x1,x2,t; | Arguments... |
| printf("Anna 1. luku +------------------------+
| printf("Anna 2. luku >"); scanf("%d",&x2);
| if ( x1>x2 ) {
| t = x1;
| x1 = x2;
| x2 = T;
| }
| printf("Luvut: %d %d.\n",x1,x2)
| return 0;
|}
|
|
Näyttö koostuu siis useista ikkunoista. Käytössä olevan ikkunan ympärillä on kaksinkertainen raami. Ikkunoiden kokoa
ja paikkaa voidaan muuttaa hiirellä tarttumalla kiinni ikkunan yläreunaan tai ikkunan johonkin nurkkaan. Kokeile!
Ikkunasta toiseen voidaan siirtyä joko hiirellä näpäyttämällä sitä ikkunaa, johon halutaan siirtyä tai painamalla [Alt-?], missä ? on sen ikkunan numero (oikeassa yläkulmassa
ikkunaa) johon halutaan siirtyä. Kokeile!
Menut
Toimintoja voidaan valita joko hiirellä yläreunasta, tai
painamalla [Menu] ([F10]) ja siirtymällä kursorilla halutun toiminnon kohdalle. Toiminto voidaan valita
myös painamalla toiminnon korostetua kirjainta. Siis vaihtoehtoja on useita. Alkuksi menujen käyttö on näppärää nuolinäppäimillä tai hiirellä, mutta haluttaessa tehokkaampaa
toimintaa, kannattaa käyttää suoravalintoja.
Kokeile ajaa edellinen ohjelma neljällä eri tavalla:
valitse hiirellä menuista Run ja sieltä Run.
paina [F10], liiku kursorilla kohtaan Run. Paina [RET]. Siirry nuolilla kohtaan Run. Paina [RET].
paina [Alt-R]R
paina [Ctrl-F9]
Mikä edellistä tavoista tuntuu parhaalta?
Mistä keksittiin [Ctrl-F9]?
Alla on lueteltu funktionäppäinten käyttötarkoitukset. Selaile menuista kullekin funktionäppäimelle myös menuvalinta
(tyyliin [Ctrl-F9] = [Alt-R]R):
Funktio-näppäimet
[F1] - apua
[F2] - talleta tiedosto
[F3] - avaa tiedosto
[F4] - aja ohjelmaa kursoririville saakka
[F5] - zoom (muuta ikkuna isoksi/pieneksi)
[F6] - seuraava ikkuna
[F7] - suorita seuraava rivi
[F8] - suorita seuraava rivi käskynä
[F9] - käännä ja linkitä ohjelma
[F10] - menu
[Alt-F1] - viimeksi katsottu apua-ruutu
[Alt-F3] - sulje ikkuna
[Alt-F4] - muuttujan arvon tutkiminen
[Alt-F5] - vaihda tulostusruutuun/editoriin
[Alt-F7] - siirry edelliseen virheeseen
[Alt-F8] - siirry seuraavaan virheeseen
[Alt-F9] - käännä ohjelma
[Ctrl-F1] - apua kursorin kohdalla olevasta sanasta
[Ctrl-F2] - alusta ohjelma
[Ctrl-F3] - kutsupino
[Ctrl-F4] - muuta muuttujan arvoa
[Ctrl-F5] - siirrä ikkunan paikkaa/muuta ikkunan kokoa
[Ctrl-F6] -
[Ctrl-F7] - lisää muuttuja WATCH-ikkunaan
[Ctrl-F8] - poista/lisää breakpoint
[Ctrl-F9] - käännä ja linkitä tarvittaessa, aja ohjelma
[Alt-0] - valintalista ikkunoista
[Alt-#] - siirry ikkunaan nro #
[Alt-W]W - siirry WATCH-ikkunaan
[Alt-X] - poistu käyttöjärjestelmään
[Ctrl-Ins] - laita lohko leikekirjaan
[Shift-Ins] - ota lohko leikekirjasta
[Shift-Del] - poista lohko ja laita se leikekirjaan
[Ctrl-Del] - poista lohko
[Ctrl-Y] - tuhoa rivi
[Ctrl-T] - poista sana
[Ctrl-nuolet] - liiku sana kerrallaan
[Home] - rivin alkuun
[End] - rivin loppuun
[PgUp] - näytöllinen ylöspäin
[PgDn] - näytöllinen alaspäin
[Ctrl-PgUp] - tiedoston alkuun
[Ctrl-PgDn] - tiedoston loppuun
[Esc] - poistu menusta tai apua-toiminnosta
[Alt-BS] - UNDO, eli peru muutokset
[Ctrl-Q]] - siirry sulun vastinpariin vasemmalle ( { [
/* "
[Ctrl-Q][ - siirry sulun vastinpariin oikealle ) } ] */
"
[Ctrl-Q]F - etsi
[Ctrl-K]B - aloita lohko (vasen ylänurkka)
[Ctrl-K]K - lopeta lohko
[Shift-nuolet] - maalaa lohkoa
[Ctrl-K]W - kirjoita lohko levylle
[Ctlr-K]R - lue lohko levyltä
Ikkunan osat ja painikkeet
Usein jokin ikkuna saattaa olla jakautunut useisiin ali-ikkunoihin. Esimerkiksi seuraava ikkuna saadaan [Alt-O]EP:
+-[*]-------------- Preferences ------------------+
| |
| Screen Size Auto Save |
| (.) 25 lines [X] Editor files |
| ( ) 43/50 lines [X] Environment |
| [X] Desktop |
| Source Tracking [X] Project |
| (.) New window |
| ( ) Current window [ ] Save old messages |
| |
| OK Cancel Help |
| |
+-------------------------------------------------+
Nyt ali-ikkunoina on otsikoiden alla olevat tekstit (Screen
Size, Auto Save, jne). Ali-ikkunasta toiseen voidaan siirtyä [Tab] ja [Shift-Tab] -näppäimillä. Kokeile!
Painikkeita on 2 eri tyyppiä: radionäppäimet (yhtä painamalla muut ponkaisevat ylös, vrt. vanha matkaradio) ja tavalliset painikkeet. Painike voidaan painaa hiirellä tai
painamalla [Alt-kirjain] tai siirtymällä ko. ali-ikkunaan ja liikkumalla nuolilla ja välilyöntinäppäimellä. Kokeile!
Kääntäjän virheilmoitukset
Borlandin kääntäjissä voidaan monipuolisesti asetella
optioita siitä, mistä kääntäjä valittaa. Yleisesti ottaen
kannattaa pitää kaikki mahdolliset virheilmoitukset päällä,
koska varoitus on käytännössä jotakin vikaa ohjelmassa.
Kaikki virheilmoitukset saat päälle seuraavasti:
Valitse: Options Compiler Messages Display
Katso, että All on valittu.
Valitse Options Make
Katso, että kohdassa Break Make On on kohta Warnigs
-valittuna.
Help-toiminto
Borlandin ohjelmaympäristöissä on varsin hyvä Help-toiminto.
[F1]-näppäimellä saadaan tavallinen Help. Kokeile!
Mikä on esimerkiksi komento lohkon sisentämiseksi?
[Ctrl-F1] antaa apua siitä sanasta, jonka kohdalla kursori on. Kokeile vaikkapa sanoihin printf, scanf ja return. Esimerkiksi printf:n kohdalla voit jatkaa helpissä
format-kohtaan ja katsoa millainen format voi olla.
Tätä käyttäen voidaan yleensä aina löytää syntaksi halutulle
käskylle. Myöhemmin tässä ohjauksessa käytetään satunnaislukugeneraattoria rand. Kokeile löytää kutsun syntaksi kirjoittamalla koodiin ylimääräinen rand ja paina [Ctrl-F1]. Yleensä helpistä löytyy myös valmis esimerkki
funktion tai käskyn käytöstä. Tämä esimerkki tai sen osa
voidaan tarvittaessa kopioida omaan koodiin. Muista lopuksi
pyyhkiä rand pois koodista.
Kääntäjän tekemät tiedostot
Poistu käyttöjärjestelmään ja kirjoita ylös mitä juuri kirjoittamaasi ohjelmaan liittyviä tiedostoja on syntynyt hakemistoosi hakemistoosi (joskus kääntäjä on asetettu siten,
että käännöksen tulokset menevät RAM-levylle. Tarkista siis
sekin) ja mitä varten mikäkin tiedosto on:
_________________
_________________
_________________
_________________
_________________
_________________
Anna käyttöjärjestelmässä komento JARJ2[RET]. Mitä tapahtuu? Miksi?
Borland C debugger
Käynnistä Borland C uudelleen ja huolehdi siitä, että saat
tiedoston JARJ2.C näkyviin.
Siirrä myös WATCH-ikkuna näkyviin ([Alt-W]W).
Laita yksi kerrallaan WATCH-ikkunaan muuttujat x1, x2 ja t
([Ctrl-F7]). Watch ikkunaan saa muuttujia myös siirtymällä tekstissä muuttujan nimen päälle ja painamalla sitten [Ctrl-F7]. Laita WATCH-ikkunaan myös ehdon x1>x2 arvo ([Ctrl-F7]x1>x2[RET]). Aluksi muuttujien perässä voi olla virheilmoitus jonka pitäisi poistua kun ohjelman suoritus aloitetaan ja muuttujan "elämä alkaa".
Aja ohjelmaa rivi kerrallaan ([F7]).
Katso välillä tulostusruutua ([Alt-F5]).
Kokeile uudestaan. Käytä myös kursoriin saakka ajamista
(eli siirrä kursori vaikkapa riville x2=t ja paina [F4]).
Siirrä vaihtamisessa suoritettavat lauseet samalle riville:
t=x1; x1=x2; x2=t;
Eli:
siirry rivin loppuun ([End])
poista rivin loppu ([Ctrl-T] tai ([Del])
poista seuraava sana ([Ctrl-T])
lisää välilyönti
Kokeile suoritusta rivi kerrallaan uudelleen, kun ko. lauseet on siirretty.
Kokeile suoritusta rivi kerrallaan käyttämällä nyt näppäintä
[F8]. Mitä eroa näppäimeen [F7]
______________________.
Aja vielä kerran riville if ( x1... Muuta muuttujan x1 arvoa ([Ctrl-F4]x1[RET]) ennenkuin jatkat suorittamista rivi kerrallaan.
Lisää ohjelmaan tulostusrivi, joka kertoo ohjelman käyttäjälle mitä ohjelma tekee.
Talleta ohjelma lopuksi ([F2]).
Lohkojen käsittely
Aloita uusi ohjelma nimeltä JARJ3.C ([F3]jarj3.c[RET])
Lue pohjaksi edellinen ohjelma ([Ctrl-K]Rjarj2.c[RET]).
Tarkoituksena on muuttaa ohjelmaa siten, että järjestetäänkin 3 lukua suuruusjärjestykseen (rivit on numeroitu jotta
alla voidaan viitata riveihin; numeroita ei missään tapauksessa kirjoiteta!):
LUE ENSIN HUOLELLISESTI KOHTIEN 4 JA 5 OHJEET!
01 /* Ohjelma järjestää kolme lukua suuruusjärjestykseen.*/
02 #include <stdio.h>
03 int main(void)
04 {
05 int x1,x2,x3,t;
06 printf("Anna 1. luku >"); scanf("%d",&x1);
07 printf("Anna 2. luku >"); scanf("%d",&x2);
08 printf("Anna 3. luku >"); scanf("%d",&x3);
09 if ( x1>x2 ) {
10 t=x1; x1=x2; x2=t;
11 }
12 if ( x1>x3 ) {
13 t=x1; x1=x3; x3=t;
14 }
15 if ( x2>x3 ) {
16 t=x2; x2=x3; x3=t;
17 }
18 printf("Luvut: %d %d %d\n",x1,x2,x3);
19 return 0;
20 }
Kolmannen luvun lukeminen voidaan kopioida vaikkapa 2. luvun
lukemisesta (rivinumerot viittaavat valmiiseen koodiin):
siirry rivin 07 alkuun (nuolet ja [Home])
merkitse lohkon alku (paina [Shift] pohjaan ja pidä se
siellä)
siirry seuraavan rivin alkuun (nuoli alas)
merkitse lohkon loppu (päästä [Shift] ylös)
laita lohko leikekirjaan ([Ctrl-Ins])
ota lohko leikekirjasta ([Shift-Ins], mahd uudestaan
jos rivi ei tullut kahdesti)
tee riville tarvittavat muutokset
Vertailut saadaan vastaavasti kopioimalla rivit 09-11 (ed.
esim. mukaiset valmiit rivinumrot) kahteen kertaan:
siirry rivin 09 alkuun (nuolet ja [Home])
merkitse lohkon alku ([Shift] pohjaan ja pidä siellä)
siirry rivin 12 alkuun (nuolet alas)
merkitse lohkon loppu ([Shift] ylös)
laita lohko leikekirjaan ([Ctrl-Ins])
kopioi lohko ([Shift-Ins], mahd. uudestaan jos vanha
hävisi)
kopioi lohko ([Shift-Ins])
tee riveille tarvittavat muutokset
Tee loput tarvittavat muutokset.
Talleta ohjelma.
Lisää myös x3 WATCH-ikkunaan.
Ajele ohjelmaa ja tutki toimiiko.
Lohkon voi merkitä myös hiirellä. Kokeile sitäkin, mutta
muista että näppäimistö on aina nopeampi ja tarkempi (kun
sen kunnolla opettelee)!
Aliohjelmat
Muokkaa tiedostosta JARJ3.C seuraava tiedosto JARJ3A.C:
jarj3a.c
Laita WATCH-ikkunaan muuttujat x1, x2, x3, a, b ja t.
Kokeile ajaa askel kerrallaan käyttäen sekä [F7] että [F8]. Mikä on näppäinten välinen ero?
_______________________.
Poista aliohjelmasta kaikki tähdet (*a -> a jne) sekä pääohjelmasta aliohjelman vaihda kutsussa olevat &-merkit.
Talleta muutettu ohjelma nimelle JARJ3AA.C ([Alt-F]A[RET]jarj3aa.c[RET]).
Kokeile muutetun ohjelman toimintaa askel kerrallaan. Muuttuvatko x1, x2 ja x3 aliohjelman suorituksen aikana kuten
edellisellä kerralla?
Avaa edellinen jarj3a.c uudelleen ja kokeile vielä kerran
suoritusta askel kerrallaan. Vertaa toimintaa ohjelmaan
jar3aa.c.
C++
Sama ohjelma voidaan tehdä myös C++:lla. Erona C++:ssa on
että syötössä ja tulostuksessa voidaan käyttää << ja >>
-operaattoria (voidaan tulostaa ja lukea myös kuten
C-kielessä) sekä voidaan käyttää referenssiä &, jonka
ansiosta aliohjelmassa tehdyt muutokset heijastuvat
pääohjelmaan vaikkei parametreja viedäkään osoittimien
avulla.
Avaa jarj3aa.c ja lisää siihen aluksi vain muutos:
void vaihda(int &a, int &b)
Talleta nimelle jarj3.cpp ja kokeile toimintaa. Pitäisi
toimia. Muuta ohjelma vielä seuraavaksi "kunnon" C++
-ohjelmaksi:
jarj3.cpp
Taulukot
Miten edellistä ohjelmaa pitäisi muuttaa mikäli haluttaisiin
järjestää 4 lukua. Taitaisi jo tulla varsin sotkuiseksi.
Muutetaan ohjelmaa (kirjoita nimelle JARJ3TA.C käyttäen pohjana JARJ3.C-ohjelmaa) siten, että apuna käytetään taulukkoa:
jarj3ta.c
Aliohjelma vaihda voidaan hakea tiedostosta JARJ3A.C seuraavasti:
Siirry tiedostoon JARJ3A.C ([Alt-ikkunan nro]).
Merkitse aliohjelma lohkoksi (siirry alkuun ja [Shift] pohjaan, siirry nuolilla loppuun ja [Shift] ylös)
Laita lohko leikekirjaan ([Ctrl-Ins]).
Siirry tiedostoon JARJ3TA.C.
Kopioi lohko leikekirjasta (siirry haluttuun kohtaan ja paina [Shift-Ins]).
Edellinen ohjelma ei ehkä ole yhtä selkeä (?) kuin JARJ3.C,
mutta lukujen lukumäärä esiintyy ohjelmassa enää vain yhdessä paikassa. Missä?
Talleta ohjelma.
Poista WATCH-ikkunasta kaikki tarpeeton:
siirry WATCH-ikkunaan ([Alt-W]W)
siirry poistettavalle riville
poista rivi ([Ctrl-Y] tai [Del])
...
siirry takaisin C-ikkunaan ([Alt-#], missä # on sen
ikkunan numero jossa haluttu C-ohjelma on.)
Lisää taulukko luvut sekä muuttujat pienin ja tutki
WATCH-ikkunaan.
Aja ohjelmaa askel kerrallaan. Toimiiko täsmälleen vastaavasti kuin JARJ3.C?
Muuta KOKO 5 ja kokeile toimintaa.
C-kielen kirjasto
Järjestämisessä voimme C-kielen tapauksessa käyttää apuna
myös valmista kirjastorutiinia qsort. Rutiinin käyttämistä
varten meidän tarvitsee vain kirjoittaa aliohjelma, joka
osaa verrata järjestettävän taulukon kahta alkiota keskenään
palauttaen negatiivisen luvun, nollan tai positiivisen luvun
sen mukaan, miten verratattavat alkiot suhtautuvat toisiinsa:
Muuta edellinen ohjelma seuraavanlaiseksi ja talleta nimellä
jarjta.c:
jarjta.c
Aja ohjelmaa askel kerrallaan. Toimiiko?
Laita keskeytyskohta riville
return *(int *)a - *(int *)b;
sekä lisää muuttujat a ja b WATCH-ikkunaan. Aja ohjelmaa
Run-käskyllä. Monta kertaa aliohjelmassa käydään?
Kirjoita vielä edellisestä korjaillen seuraava ohjelma nimelle jarjtar.c:
jarjtar.c
Aja ohjelma ja ota aika kauanko ohjelman suoritukseen menee.
Kirjoita vastaava versio ohjelmasta jarj3ta.c ja kokeile
kauanko sen suorittamiseen menee. Miksi?
Tavoite
Edellisistä ohjelmista JARJ3A.C näytti ehkä kaikkein selkeimmältä. Siinä oli kuitenkin se vika, että muuttaminen
useamman luvun käsittelyä varten vaatisi suuria muutoksia
itse ohjelmaan.
JARJ3TA.C voidaan helposti muuttaa käsittelemään useampaakin
lukua. Se ei kuitenkaan ole sellaisenaan turhan selkeä.
Jatkossa pyritään siihen, että em. ohjelma voitaisiin kirjoittaa muodossa:
...
{ /* Pääohjelma */
lue(luvut);
jarjesta(luvut);
tulosta(luvut);
return 0;
} /* Pääohjelma */
Kerho-ohjelma 1. versiot
paamenu.c
Mene omaan hakemistoosi ja luo sen alle hakemisto nimeltä
KERHO ja vaihda itsesi sinne.
Kopioi KERHO-ohjelman 0. versio omaan hakemistoosi:
C:\OMAT\OHJELMOI\VESA>copy n:\kurssit\cpp\kerho\paamenu.0\*.*[RET]
Tutki Borland-C:llä tiedostoa kerho.c
Laita tulosikkunan näkyville.
Aja ohjelmaa kokonaisena ja askel kerrallaan. Missä kohti
tulostuu jäsenien lukumäärä?
Muuta ohjelmaa siten, että se tulostaa jäsenien määräksi 15.
Ymmärrätkö kaikki rivit?