Kirjautuminen

Haku

Tehtävät

Opasarkisto: Aloittelijan QBasic-opas: Osa 3 - SUB, FUNCTION, GOTO/GOSUB ...

  1. Osa 1 - PRINT, CLS, INPUT
  2. Osa 2 - DEFX, IF...ELSE...END IF, FOR...NEXT ...
  3. Osa 3 - SUB, FUNCTION, GOTO/GOSUB ...

Kirjoittaja: thefox

Opetettavat käskyt: CALL, GOSUB, RETURN, GOTO, SUB/FUNCTION, END SUB/FUNCTION, REM

Esisanat

Tervetuloa jo kolmanteen osaan tästä aloitteleville QB-ohjelmoijille suunnatusta oppaasta. Uusia osia pitäisi tulla melko säännöllisesti, ja jokaisen saat heti ilmestyttyä Ohjelmointiputkasta osoitteesta http://www.ohjelmointiputka.net/ ('Oppaat'-osio). Suosittelen hakemaan ensimmäisen ja toisen osan ennen tämän lukua. Tämänkertaisia aiheita ovat:

Ja sitten itse asiaan, eli...

Aliohjelmat

Aliohjelmat ("funktio", "proseduuri") ovat itseasiassa lyhyitä ohjelmia, joita voidaan kutsua ja jotka voivat palauttaa tietynlaisen tuloksen. Jokaisella funktiolla on nimi, ja kun ohjelmaan kirjoitetaan "CALL funktionnimi" haarautuu ohjelma ko. funktioon, ja funktion suorittamisen jälkeen jatkaa suorittamista funktion kutsumista seuraavalla käskyllä. Esimerkki:

PRINT "Nyt ulostan..."
CALL TulostaTeksti
PRINT "Ulostus onnistui."

SUB TulostaTeksti
   PRINT "Näin teen! :)"
END SUB

QB:ssä on kahdenlaisia funktioita, 'SUB'-tyyppiset funktiot eivät palauta arvoa, kun taas 'FUNCTION'-tyyppiset palauttavat. Ylläoleva esimerkkifunktiomme ei palauta arvoa, joten se määritellään 'SUB'-tyyppiseksi. Ulostus.. eikun siis tulostus ylläolevassa funktiossa on seuraavanlainen:

Nyt ulostan...
Näin teen! :)
Ulostus onnistui.

Näin siis määrittelimme funktioon nimeltään 'TulostaTeksti', joka on tyyppiä 'SUB', eli se ei palauta arvoa. Kutsuimme funktiota ohjelmasta käskyllä CALL. Huomaa että QB:ssä funktiot eivät näy kuten yllä olevassa esimerkkiohjelmassa, vaan saat ne esiin painamalla F2-näppäintä. Sitten vain valitset haluamasi funktion ja QB näyttää sen sinulle.

Perinteinen BASIC-tyyli funktioiden kutsumiseen on mielestäni nykyisellään aivan turha, joten en sen suuremmin käy sitä lävitse, tässä kuitenkin ylläoleva esimerkki, "in traditional way":

PRINT "Nyt ulostan..."
GOSUB TulostaTeksti
PRINT "Ulostus onnistui."
END

TulostaTeksti:
   PRINT "Näin teen! :)"
RETURN

Funktiota kutsutaan 'GOSUB'-käskyllä, ja funktiosta palataan 'RETURN'-käskyllä. Huomaa 'END', joka estää ohjelmaamme valumasta funktioon suorittamisen päätyttyä. Niin, 'END':hän vain lopettaa ohjelman. Vetäisenpä nyt tähän samaan lössiin 'GOSUB':in kanssa vielä 'GOTO'-käskyn. Kirjoittamalla "TulostaTeksti:" määrittelimme nimiön, samalla tavalla kuin C:ssäkin. Tähän nimiöön voimme sitten hypätä joko 'GOSUB'-käskyllä, kuten ylläolevassa esimerkissä, tai 'GOTO'-käskyllä.

Mitä eroa sitten on GOSUB:illa ja GOTO:lla? GOSUB tietää, mistä sitä kutsuttiin, GOTO ei. GOTO hyppää nimiöön, mutta ei tiedä minne palata joten RETURN-käskyä ei GOTO:n kanssa käytetä. GOTO tuntuisi mielettömän hyvältä käskyltä, voihan sillä hypätä minne kohtaan koodia tahansa. Siltikään, GOTO:a ei pidä, eikä tarvitse, käyttää. Ongelmat ovat aina ratkaistavissa paremmilla ja selkeimmillä tavoilla. GOTO ei ole oikotie onneen :-)

Mutta sitten jälleen taas asiaan, eli funktioihin. Otetaan esimerkki 'FUNCTION'-tyyppisestä aliohjelmasta, eli funktiosta, joka palauttaa arvon.

PRINT "Nyt ulostan..."
PRINT TulostaTeksti
PRINT "Ulostus onnistui."

FUNCTION TulostaTeksti$
   TulostaTeksti$ = "Näin teen! :)"
END FUNCTION

Toisella rivillä kutsumme funktiota TulostaTeksti$, joka palauttaa merkkijonon (johtuen '$'-merkistä). Itse funktio palauttaa arvon sijoittamalla sen funktion nimeen. Koska funktio palauttaa merkkijonon "Näin teen! :)" tulostaa toinen rivi juuri sen. Sitten teemmekin funktion, joka ottaa parametreja:

PRINT "Paljonko on 14 jaettuna 7.5:llä?"
PRINT Jako(14, 7.5)
PRINT "Aivan oikein :)"

FUNCTION Jako! (a AS SINGLE, b AS SINGLE)
   Jako! = a / b
END FUNCTION

Funktio on tällä kertaa nimeltään 'Jako!', jossa huutomerkki kuvastaa paluuarvon tyyppiä SINGLE, eli 7-numeroinen liukuluku. Parametrit määritellään heti funktion määrittelyn perään, eli "(a AS SINGLE, b AS SINGLE)". Määrittelemme kaksi parametria, a ja b, jotka kummatkin ovat tyypiltään liukulukuja. Näillä voimme sitten leikkiä itse funktiossa, esimerkissämme suoritamme jakolaskun. Funktioista olisi varmasti vielä muutakin sanottavaa, mutta hyppäämme kuitenkin seuraavan aiheeseen, eli matemaattisiin operaattoreihin. Funktiosta lisää (ehkä) jossain toisessa osassa.

Matemaattiset operaattorit

QB:ssä voi tehdä monimutkaisiakin laskutoimituksia helposti. Työnnänpä heti alkuun hienon taulukon:

OperaattoriSelitys
+Yhteenlasku (3+4) = 7
-Vähennyslasku (4-3) = 1
/Jakolasku (10/2) = 5
*Kertolasku (2*5) = 10
MODJakojäännös (10 MOD 3) = 1
SQRNeliöjuuri (SQR(4)) = 2
^Potenssi (3^2) = 9

Ensimmäiset neljä ovat varmasti tuttuja jokaiselle. MOD:illa saamme selville jakojäännöksen, eli arvon, joka jakolaskusta jää yli (kun emme pelaa desimaalien kanssa..). 10 MOD 3 on 1, koska 10 - ((10 / 3) * 3) = 1. Toinen esimerkki: 13 MOD 5 on 3, koska 13 - ((13 / 5) * 5) = 3. Neliöjuuren pitäisi olla vanhaa huttua jokaiselle, jos ei ole niin mene kouluun. Potenssimerkkiä (^) ei pidä sekoittaa C:hen, jossa ko. merkillä suoritetaan XOR-operaatio.

Mitäs sitä muuta matemaattisista operaattoreista sanomaankaan.. jos tulee jotain kysyttävään niin e-mailkusti polkee. Pistetään nyt sentään pienoinen, jo klassikoksi muodostunut, laskinesimerkki:

DIM valinta AS STRING * 1
DIM a1 AS SINGLE, a2 AS SINGLE

CLS
PRINT " -- QBLaskin by fawkz --"
PRINT
PRINT " Valitse laskun tyyppi:"
PRINT "   1) yhteenlasku"
PRINT "   2) vähennyslasku"
PRINT "   3) jakolasku"
PRINT "   4) kertolasku"
PRINT
INPUT " valinta> ", valinta

INPUT " arvo1> ", a1
INPUT " arvo2> ", a2
PRINT " tulos>";

IF valinta = "1" THEN   ' yhteenlasku
   PRINT a1; "+"; a2; "="; a1 + a2
ELSEIF valinta = "2" THEN ' vähennyslasku
   PRINT a1; "-"; a2; "="; a1 - a2
ELSEIF valinta = "3" THEN ' jakolasku
   PRINT a1; "/"; a2; "="; a1 / a2
ELSEIF valinta = "4" THEN ' kertolasku
   PRINT a1; "*"; a2; "="; a1 * a2
ELSE
   PRINT " Valinnan täytyy olla olla väliltä 1-4!"
END IF

END

Ja sitten seuraavaan, ja viimeiseen aiheeseen, eli kommentointiin.

Kommentointi

Ohjelman oikeaoppinen kommentointi on vaikea laji ja varsinkin monelta aloittelijalta kommentit unohtuvat yleensä kokonaan. Kommentteja kannattaa kuitenkin käyttää. Niin, siis mikä on kommentti? Kommentti kertoo, mitä jokin ohjelman osa tekee. Kommentteja voi QB:ssa kirjoittaa muutamalla tavalla:

PRINT "Hello world!": REM Tulostaa ruutuun tekstiä
PRINT "Terva maailma!" ' Tulostaa toisen tekstin

Ylimmäinen on perinteinen BASIC-kommentointitapa, mutta sitä ei enää kannatta käyttää missään tapauksessa, kun käytössä on lyhempi korvike, heittomerkki. REM on itseasiassa ihan oma käskynsä joten tarvitsemme vielä kaksoispisteenkin ennen kommentin laittoa.

Heittomerkillä (tai REM:illä) laitettu komentti kestää rivin loppuun saakka, eikä kommentia ole mahdollista katkaista. Tietenkään lause ei muutu kommentiksi jos lainausmerkki on vaikkapa merkkijonon sisällä:

PRINT "Hi's to you!"

Miksi kommentoida? Kommentit selventävät koodia huomattavasti (varsinkin niitä vaikeimpia purkkaviritelmiä ;-) ja osaat varmasti arvostaa kommentointia kun katsot omaa kommentoimatonta koodiasi parin kuukauden päästä. Koodia kirjoittaessa kaikki on selvää mutta myöhemmin näin ei olekaan :-)

Kommentointia, vaikka se useimmiten onkin vain hyväksi, tulisi silti käyttää varoen. Ei ole mitään järkeä kommentoida itsestäänselvyyksiä, kuten ylläolevissä esimerkeissä. Kommentin ei pidä kertoa mitä joku yksittäinen käsky tekee ('tulostaa tekstiä' tms) vaan mitä joku ohjelman osa tekee. Esimerkki:

DEFINT A-Z
DIM a AS STRING, d AS LONG
INPUT "Anna nimesi: ", a
' Allaolevassa silmukassa laskemme nimen ASCII-arvot
' yhteen lopputuloksen ollessa 'd'-muuttujassa
FOR c = 1 TO LEN(a)
   d = d + ASC(MID$(a, c, 1))
NEXT
PRINT "ASCII koodi:"; d

Vaikka esimerkki ei ehkä ollutkaan paras mahdollinen niin asian pitäisi olla melko selvä. Joten mitäs tässä turhia pulisemaan.

Loppusanat

Ja jälleen kerran olemme päässet onnellisesti (?) loppuun. Nyt voisitkin käyttää kaikkien kolmen osan oppeja hyödyksesi ja koodata vaikkapa parannetun, kommentoidun, laskimen, joka käyttää funktioita, sekä jossa on myös potenssi- ja neliöjuurilaskumahdollisuudet. Siitä vaan töihin.

Minulla ei oikeastaan tällä hetkellä ole pienintäkään ideaa mitä seuraavaan osaan pitäisi pistää. Jos sinulla ideoita sattuu olemaan niin käväise pistämässä vinkkisi Ohjelmointiputkan viestifoorumiin. Ja se on sitten siinä. Kesäloma muuten alkoi juuri tänään, katsotaan miten se vaikuttaa ilmestymisnopeuteen ;-)

Nähdään seuraavassa osassa, joka ilmestyy kun sen jaksan kirjoittaa. Laiskuudestani johtuen se voi tosin viedä jopa viikkoja... (tai vuosia, toim. huom. ;-)) Jos haluat seuraavan osan kirjoittamiseen vauhtia, niin tipauta sähköpostia osoitteeseen _____@luukku.com.


Kommentit

KimmoKM [16.02.2003 12:40:00]

Lainaa #

Oikein hyvä opassarja :)

KimmoKM [16.02.2003 12:41:11]

Lainaa #

Niin, toivottavasti tulee jatkoa.

thefox [28.02.2003 16:21:26]

Lainaa #

Piu pau, voisi kai kirjoittaa sen piiiitkään viimeisen, eli viidennen, osan valmiiksi kyllä. (Neljäs on valmis, pitänee kaivaa se jostain... ;-)

anomizer [02.03.2003 10:53:54]

Lainaa #

tee grafiikka juttuja.

M.K [04.03.2003 17:25:56]

Lainaa #

hYvä OpAs :p

(nimetön) [11.06.2003 21:15:56]

Lainaa #

TOSI hyvä opas!;) ~Jakezu~

(nimetön) [11.06.2003 21:16:14]

Lainaa #

TOSI hyvä opas!;) ~Jakezu~

Dustbin [29.09.2003 15:00:11]

Lainaa #

Miksei se neljäs osa ole jo netissä, kun kerran valmis on???

Mudface [16.11.2003 00:48:59]

Lainaa #

Toivottavasti tulee se neljäs opas nopeasti nettiin..

Dustbin [01.12.2003 20:06:33]

Lainaa #

Ei näytä tulevan, on tainnut hukkua pahemman kerran :(

simänen [30.12.2003 15:26:14]

Lainaa #

tunkekaa se neljäs jo nettiin

Heikki [02.01.2004 17:08:49]

Lainaa #

Eipä taida jatkoa tulla, vaikkakin fawkz väittää että neljäs olisi valmiina.. :D

Tp [07.01.2004 15:34:56]

Lainaa #

Kohtako se saadaan nettiin?

Thief [16.01.2004 01:52:25]

Lainaa #

Hyvä esimerkki tehokkaasta koodista.. Heh vaikka puhutaankin vain qbasicista.

Jan [02.02.2004 14:20:52]

Lainaa #

CLS
Print "hassu juttu"
For i = 1 to 5
hassua = int(rnd * 2)
If hassua = "1" then Print "Hahahaha"
If hassua = "2" then Print "Ei ollut hauskaa"
next i
sleep
end

Jan [03.02.2004 09:02:03]

Lainaa #

huomasin että koodissani on virhe

herkko [25.05.2004 21:56:44]

Lainaa #

Voisko sen nelososan tehdä uudestaan. Sille nimittäin tulisi käyttöä.. Grafiikkaa voisi ainakin käsitellä sekä muuta hienoa... :)

herkko [27.05.2004 21:34:50]

Lainaa #

Käsittelyyn voisi jossain vaiheessa laittaa myöskin tiedostojen tallentamisen ja lataamisen..

rolexxi [12.06.2004 18:38:41]

Lainaa #

sitä nelosta vois alkaa tulemaan tänne. tulis tarpeeseen.. kokeile kaivaa se jostain, tai tee uudestaa.

k00d3r [02.07.2004 21:44:53]

Lainaa #

alkaisko se nelonen jo koht tulee?

k00d3r [02.07.2004 21:44:54]

Lainaa #

alkaisko se nelonen jo koht tulee?

ttuoppi [02.07.2004 21:54:18]

Lainaa #

Fawks...vähän vauhtia, sullo se neljäs osa tänne ja äkkiä...

k.kala [13.07.2004 17:33:34]

Lainaa #

jos ei löydy nii tee uus

p-p [17.11.2004 19:56:47]

Lainaa #

Se nelos osa vois sisältää tiedoston avaamisen,sinne kirjoittamisen,tallentamisen ja sulkemisen.Niinkuin yllä ollaan jo mainittu

GorkkiusSuuri [18.12.2004 20:32:45]

Lainaa #

Nääki keskustelut kohta 2 vuotta kestäny.
Ei taiha nelosta tulla.

thefox [19.12.2004 02:06:38]

Lainaa #

Taitaa tosiaan olla, että neljäs osa jää tulematta. Odottelen vain, että joku innostuu kirjoittelemaan paremman QB-oppaan niin että tämä voitaisiin heittää hevon kuuseen :)

Megant92 [19.02.2005 22:41:24]

Lainaa #

Toivottavasti tänne tulee uusi qbasic opas, joka jatkaa siitä mihin tämä jäi.(Toivottavasti ennen vuotta 2010.)

eraggo [28.04.2005 23:50:32]

Lainaa #

hmph... toi ehdotus paremmasta laskimesta on toteutunut (hieman(!) myöhään), sillä ite oon tehny sellasen... :P
se laskee geometrisia laskui... oli siinä pikkasen hommaa mutte se on vasta "demo".... :)

Khaoralius [27.05.2005 13:36:01]

Lainaa #

hmm... Vai, että kaipaisitte KUNNOLLISTA (tämä oli mielestäni hyvä fawkz!) GBasic opasta... Voisin heittää linkin tähän keskustelun pötköön seuraavalla viikolla ;) josta löytyy kaikki perusasiat (tosin englanniksi). Sen voisin toki suomentaa, sillä voisihan sen alkuperäisen linkittää sitten siitä suomennetusta ja pistää alkuperäisen tekijän nimet ym? Olisiko se hyvä? Mitäs sanotte? (huh miten paljon kysymysmerkkejä :/ )

Khaoralius [30.05.2005 13:47:31]

Lainaa #

Hmm... mikäköhän lienee GBasic opas?! :D

php mies [23.07.2005 02:10:23]

Lainaa #

niinb mikä on GBasic

siansaksamies [30.07.2005 15:06:45]

Lainaa #

Mikä on GBasic? Mitä eroa sillä on QBASIC:iin

Juhko [23.08.2006 15:18:43]

Lainaa #

Tosi hyvä opas! :-)

siansaksamies kirjoitti:

Mitä on GBasic? Mitä eroa sillä on QBASIC:iin

Ehkä se kirjoitti väärin.

Codeprofile [18.12.2006 00:13:18]

Lainaa #

Kun selailen tuota laskin-sorsaa, niin tiedän sen toiminnan. Muttakun yritän itse tehdä sellaista ilman apuja, niin pää tyhjenee :D

Juhko [02.01.2007 12:31:22]

Lainaa #

SSSSS­SE­EE­E­EE­EE­UU­U­UU­U­UURRRRRRR­RA­AA­A­AA­AAVVVVVV­VA­AA­AAAAAA OOOOOOSSSSSSSSAAAAAAAAA!!!!!!!!!!!!!

vaikka ite kyl osaan qbtä mut silti heti nettiin se SSSSS­SE­EE­E­EE­EE­UU­U­UU­U­UURRRRRRR­RA­AA­A­AA­AAVVVVVV­VA­AA­AAAAAA OOOOOOSSSSSSSSAAAAAAAAA!!!!!!!!!!!!!

moptim [27.01.2007 07:12:20]

Lainaa #

Juhko > Tuo VAAAA­AA­A­AA­A­AA­A­AA­A­AA­I­II­I­II­I­II­I­II­I­II­KE­EE­E­EE­E­EE­E­EE­EE­UU­U­UU­U­UU­U­UU­U­UU­UUT­TA­AA­A­AA­A­AA­A­AA­AAAAAA lukemista. Itse minä en todellakaan helposti saa tuonlaista tekstiä luettua. Ilmoita vaikka näin: "Seuraava osa, kiitos" tai tee tuosta jotain muuta.

thefox [27.01.2007 19:14:27]

Lainaa #

Seuraavaa osaa ei ole tulossa. Ja toivottavasti joku saa pian tehtyä paremman korvaavan QBasic-opassarjan, että nämä voidaan poistaa täältä :)

Nizbu [25.08.2007 15:39:11]

Lainaa #

Päätin ottaa QBasicin ensimmäiseksi ohjelmointikieleksi ja tämän opassarjan pääsin todella hyvin alkuun, kiitos!

(Tulee vähän myöhässä, eh? :P)

qwerty [15.10.2007 09:04:26]

Lainaa #

Nää oppaat onki aika hyvii, grafiikast ja peleist vois olla lisää.

Buru [07.10.2008 19:35:45]

Lainaa #

Hyvä opas :). Toivottavasti neljäs tulee pian. Voiko QBasicissa kopioida mitenkään?

Buru [07.10.2008 19:39:07]

Lainaa #

Ohhoh, enpäs lukenut aikasempia viestejä :P...

jsbasic [30.12.2008 18:56:18]

Lainaa #

Koska tulee SSSSS­SE­EE­E­EE­EE­UU­U­UU­U­UURRRRRRR­RA­AA­A­AA­AAVVVVVV­VA­AA­AAAAAA OOOOOOSSSSSSSSAAAAAAAAA!!!!!!!!!!!!!

New Samppi [04.01.2009 16:31:50]

Lainaa #

Ei tätä opasta saa lopettaa, tää on hyvä!

Juhko [13.01.2009 15:39:32]

Lainaa #

Buru kirjoitti:

Hyvä opas :). Toivottavasti neljäs tulee pian. Voiko QBasicissa kopioida mitenkään?

Voi, painamalla Ctrl+Insert.

sammakkomies [30.11.2009 22:47:41]

Lainaa #

minulla on idea. Kerro seuraavaksi miten tehdään peli silleen, kuten juhko teki. Lainaan pelistä:

Juho pelit 2007 kirjoitti:

Paina enterii...

ja kun enter napista painaa, peli (yllätys yllätys) alkaa. Miten tämän saa koodattua? Ja nyt sanon ku piti ekassa oppaassa sanoa mut unohtu. Tuo slc on vissiin koodi joka yleisesti tyhjentää näytön. Ainakin DOS.EXE ohjelmassa.

black cat [01.12.2009 12:38:15]

Lainaa #

tulis nyt se uus opas. ku oon vasta aloittelija (tällä hetkellä)

Koodi123 [25.02.2019 19:52:10]

Lainaa #

Antti Laaksonen kirjoitti:

PRINT "Hello world!": REM Tulostaa ruutuun tekstiä
PRINT "Terva maailma!" ' Tulostaa toisen tekstin

Eikö tuon Terva maailma! tekstin tilalla pitäisi olla Terve maailma!?

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta