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?