Onko mahdollista QBasicissa määritellä muuttujaa niin, että se veisi muistissa tilaa vain yhden tavun? Kokeilin ensin:
DIM muuttuja AS BYTE
Mutta eipä löytänyt edes BYTE:ä varatuista sanoista. Sitten kävi mielessä tällainen:
DIM muuttuja AS STRING * 1
Sillä eikös jokainen merkki vie yhden tavun verran? Toisaalta tuli mieleen, että ainakin C:ssä merkkijono vaatii aina yhden ylimääräisen tavun loppuun. Päteekö sama QB:ssä, vai olisiko tähän jotain parempaa keinoa?
Juuri oikean tavan löysit, eli yhden merkin pituisen merkkijonon määrittely. Haittana on tosin se, että numeroarvot pitää venkslata CHR$- ja ASC-funktioilla. C-kielessä merkkijonon perässä on aina päättymistä osoittava nollatavu, mutta QBasicissa merkkijono vie tilaa vain pituutensa verran, jos pituus on pysyvä ja merkitty määrittelyssä.
edit: Hieman selvennystä: mikään ei toki C-kielessäkään estä luomasta yksittäistä tavun kokoista char-muuttujaa.
hunajavohveli kirjoitti:
DIM muuttuja AS STRING * 1Sillä eikös jokainen merkki vie yhden tavun verran? Toisaalta tuli mieleen, että ainakin C:ssä merkkijono vaatii aina yhden ylimääräisen tavun loppuun. Päteekö sama QB:ssä, vai olisiko tähän jotain parempaa keinoa?
Visual Basicissa tuo ainakin vie (MSDN:n mukaan) "Length of string", eli tässä tapauksessa juurikin yhden tavun. QBasicista tarkemmin en tiedä.
Ja parempaa tapaa en keksi, kun Byte ei kerran toimi.
Edit: Ah, Laaksonen kirjoitti nopeammin.
No sepäs hyvä, että osasisin keksiä itse tällaisen ratkaisun.
Antti Laaksonen kirjoitti:
Haittana on tosin se, että numeroarvot pitää venkslata CHR$- ja ASC-funktioilla.
Joo, kyse oli nimenomaan numeerisista muuttujista, ja ajattelinkin käyttää noita apuna. Haittapuoli on vain se, että vaativissa ohjelmissa ASCII-funktiot voivat ehkä hidastaa ikävästi, mutta pitänee käyttää näitä, ellei keksi mitään vielä ovelampaa systeemiä. En edes tarvitisisi tätä, ellei muisti loppuisi kesken INTEGER-taulukosta. Sehän vie 2 tavua, eikö niin?
Voithan sä myös tallentaa Integeriin 2 Byteä ja erottaa sitten ylemmän ja alemman tavun Mod-operaattorilla ja kokonaislukujaolla eli kenoviivalla
Yksi mahdollisuus on käyttää POKEa ja PEEKiä ja kirjoittaa tiedot suoraan muistiin oikeisiin paikkoihin. Muuttujan segmentti selviää VARSEG-funktiolla ja siirrososoite VARPTR-funktiolla.
'kymmenen tavun tila DIM testi AS STRING * 10 'määritetään segmentti DEF SEG = VARSEG(testi) 'kirjoitetaan luvut muuttujaan FOR i = 0 TO 9 POKE VARPTR(testi) + i, i NEXT 'luetaan ja näytetään luvut muuttujasta FOR i = 0 TO 9 PRINT PEEK(VARPTR(testi) + i); NEXT
setä kirjoitti:
Voithan sä myös tallentaa Integeriin 2 Byteä ja erottaa sitten ylemmän ja alemman tavun Mod-operaattorilla ja kokonaislukujaolla eli kenoviivalla
Tuo oli se ovelampi tapa, jota rupesin juuri miettimään. Pitää vain vähän järkeillä, että saan toimimaan.
Niin voisihan muistipaikkoja tietysti säätää myös suoraan. Yksi paikkahan vie tavun verran.
Aihe on jo aika vanha, joten et voi enää vastata siihen.