Dynaamisen muistin varaus VB:llä

Pankaas pieni esimerkki vaikkapa linkitetyn listan tekemisestä. Onnistuuko?
5411
Äänestä

Muut lukivat myös

Vastaukset 5

Vanhimmat

Miksi joku C-ohjelmoija kyselee VB:stä? Kun tuossa äsken sanoin VB:n olevan hyvä ohjelmointikieli, ei se tarkoita, että pitäisin muita ohjelmointikieliä huonona. Jos todella haluaisit kysyä neuvoa ohjelmointiongelmasta, toki kertoisit ongelman. Eli jos yleensä joku haluaa ratkaisun ja vain ratkaisu on tärkeä, ei tekotapa, hän kertoo ongelman, eikä sinun tavallasi vaadi ratkaisua tietyllä tavalla. Täsmennän vielä. Olet ymmärtänyt ohjelmoinnin väärin, jos vaadit ohjelmointiongelman ratkaisua tietyllä tavalla. Ohjelman käyttäjähän ei tiedä, mitä ohjelmakoodia ohjelma sisältää, joten ei ohjelman toimintoja tarvitse tietyllä tavalla tehdä. Eri ohjelmointikielissä kannattaa asiat ratkaista eri tavalla. C-kielessä on pointterit, joilla kyseinen asia onnistuu. C-räpeltäjät luulevat, että koska VB:ssä ei ole pointtereita, ei myöskään linkitetyn listan tekeminen onnistu.

Yrität provosoida jonkun vastaamaan, joten minä nyt vastaan (enhän voi pitää päätäni kiinni). Sanoit otsikossa ”Dynaamisen muistin varaus VB:llä”. Vastaan tuohon ensin, koska siihen on helppo vastata, sillä VB:ssä on Dim-käsky ja ReDim-käskyt, joilla muistia voidaan varata dynaamisesti. Kun käytetään ”ReDim Preserve” jää taulukkoon myös aikaisemmat arvot. Seuraavaa esimerkkiä varten, aloita uusi Projekti, lisää perusformiin yksi tekstikenttä oletusnimellä (Text1) ja kopioi formin ohjelmakoodiin allaoleva esimerkki. Teksikenttään syötät taulukon alkioiden maksimimäärän (esimerkissä rajattu arvoihin 1..30) ja painat enteriä. Tämän jälkeen ohjelmaa varaa dynaamisesti oikean kokoisen taulukon. Taulukon alkioihin lisätään aikaisempaan arvoon kirjain A:sta lähtien (ascii arvot 65..). Lopuksi taulukko tulostetaan ruudulle siten, että vierekkäin ensimmäisestä indeksistä suurimpaan ja toiseen suurimmasta pienimpään. Esim. jos ensin syötetään arvo 2 ja sitten 4, tulee taulukoiden arvoksi AA,BB,C,D. Koska vanha arvo jätetään pohjaksi.

Dim LKM, I
Dim Taulukko() As String

Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then
LKM = Val(Text1.Text)
If LKM < 1 Or LKM > 30 Then Exit Sub
'määritellään taulukolle uusi koko
ReDim Preserve Taulukko(LKM)
TäytäTaulukko
TulostaTaulukko
KeyAscii = 0
End If
End Sub

Sub TäytäTaulukko()
For I = 1 To LKM
Taulukko(I) = Chr$(64 I)
Next
End Sub

Sub TulostaTaulukko()
Cls 'tyhjennetään ruutu
'tulostetaan taulukko ruutuun
For I = 1 To LKM
Print I, Taulukko(I), LKM - I 1, Taulukko(LKM - I 1)
Next
End Sub


Tuossa siis esimerkki dynaamisesta muistinvarauksesta. VB:ssähän tämä toimii loistavasti. Toki tuon tietää jokainen, joka on vähääkään VB:llä ohjelmoinnut.


Ja sitten toiseen kysymykseesi, eli esimerkki linkitetystä listasta. Linkitetty listahan on taulukko, joka viittaa toiseen taulukkoon, joten voidaan dynaamisesti lisätä arvoja. Juuri tässä kysymyksessä oleellista olisi ongelma, joka pitäisi ratkaista, jotta voisi kertoa kyseiseen ongelmaan parhaimman ratkaisun. Mutta pääsääntö VB:ssä on, että linkitettyä listaa ei tarvitse käyttää, koska tavallista taulukkoa voidaan käyttää linkitettynä listana. Eli edellinen esimerkki oli myös esimerkki linkitetystä listasta, kuten varmaan heti tajusitkin.

Laitan tähän loppuun vielä lyhyen esimerkin linkitetystä listasta. Tarvitset projektille vain yhden tekstikentän Text1-nimellä. Kun syötät kenttään tekstin ja painat enteriä (ascii 13), ohjelma varaa dynaamisesti Nimet$-taulukkoon uuden alkion ja laittaa syötetyn tekstin siihen. Taulukko tulostetaan ruutuun käänteisessä järjestyksessä jokaisen syötön jälkeen.

Dim LKM
Dim Nimet$()

Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim i
If KeyAscii = 13 Then
KeyAscii = 0
LKM = LKM 1
ReDim Preserve Nimet$(LKM)
Nimet$(LKM) = Text1.Text
Cls
For i = LKM To 1 Step -1
Print i, Nimet$(i)
Next
End If
End Sub


Ylläoleva esimerkki osoittaa, kuinka kätevää on VB:ssä määritellä muistia dynaamisesti. Eikä linkitettyä listaa edes tarvita. Aikaisemmissa Basic-versioissa olen myös käyttänyt varsinaisia linkitettyjä listoja (taulukkoja, jotka viittaavat toiseen taulukkoon), mutta VB hoitaa ne helpommin. Ah, niin on hyvä ohjelmointikieli VB ja helppo sillä ongelmat ratkaista. Kirjoitin sille vielä lyhyen runon:

VB:llähän ohjelmia väsään
-------------------------------------
Kato VB:llä ohjelmia teen,
ongelmat ratkaisen,
hommat hoidan.

Kaunista tulosta helppo on tehdä,
beisikillä parhaat keinot,
asiat hoitaa,
vaivaton väsätä,
muistia varata
dynaamiset taulukot,
listat ja linkit,
sulavaa, joustavaa,
ketterää koodia.

Äänestä
  • Olisi pitänyt hiukan tarkemmin määritellä mitä tarkoitin. Linkitetyn listan etunahan on, että listan keskeltä voi tiputtaa alkion pois ja vapauttaa sen käyttämän muistin. Onnistuuko muuten kuin siirtämällä poistettavasta alkiosta lähtien taulukon alkioita pykälällä taaksepäin ja sitten pienentämällä taulukkoa?

    Äänestä

  • Janne kirjoitti:

    Olisi pitänyt hiukan tarkemmin määritellä mitä tarkoitin. Linkitetyn listan etunahan on, että listan keskeltä voi tiputtaa alkion pois ja vapauttaa sen käyttämän muistin. Onnistuuko muuten kuin siirtämällä poistettavasta alkiosta lähtien taulukon alkioita pykälällä taaksepäin ja sitten pienentämällä taulukkoa?

    Alkuperäinen kysymyksesi oli vain sen verran provosoiva.

    Tuolla tavalla ainakin itse teen (siirrän taulukon alkioita pykälällä). Suurellakin tietomäärällä se tapahtuu nopeasti. Joskus olen käyttänyt yhtä merkkijonoa tuohon tarkoitukseen (VB:ssähän merkkijono voi olla megoja tai teroja, tavuja). Jos merkkijonot ovat eripituisia (tekstiä), olen laittanut kunkin merkkijonon alkuun esim. chr$(0) . Tiedon hakuun sitten Instr-käskyä. Mutta nykyään käytän suoraan taulukoita, koska koodi on selkeämpää ja kuitenkin nopeata.

    Ja olen todellakin sitä mieltä, ettei tekotapa ole oleellinen, vaan se, että ratkaisu on selkeä ja toimii riittävän nopeasti. Ainahan sitä joutuu vääntämään koodia, joten turha takertua johonkin mielestäni filosofiseen kysymykseen ohjelmoinnissa.

    Äänestä

  • Petri_Petri kirjoitti:

    Alkuperäinen kysymyksesi oli vain sen verran provosoiva.

    Tuolla tavalla ainakin itse teen (siirrän taulukon alkioita pykälällä). Suurellakin tietomäärällä se tapahtuu nopeasti. Joskus olen käyttänyt yhtä merkkijonoa tuohon tarkoitukseen (VB:ssähän merkkijono voi olla megoja tai teroja, tavuja). Jos merkkijonot ovat eripituisia (tekstiä), olen laittanut kunkin merkkijonon alkuun esim. chr$(0) . Tiedon hakuun sitten Instr-käskyä. Mutta nykyään käytän suoraan taulukoita, koska koodi on selkeämpää ja kuitenkin nopeata.

    Ja olen todellakin sitä mieltä, ettei tekotapa ole oleellinen, vaan se, että ratkaisu on selkeä ja toimii riittävän nopeasti. Ainahan sitä joutuu vääntämään koodia, joten turha takertua johonkin mielestäni filosofiseen kysymykseen ohjelmoinnissa.

    > VB:ssähän merkkijono voi olla megoja tai teroja, tavuja

    Korjaa jos olen väärässä mutta megoja kyllä, teroja ei, siksi nääs että 32-bit koneessa maks. osoiteavaruus on 4GT (2^32 T). Loppuu muisti kese...

    Huh, kyllä sai taas pilkku kyytiä ;)

    Äänestä

  • Punikki & 7 hyypiötä kirjoitti:

    > VB:ssähän merkkijono voi olla megoja tai teroja, tavuja

    Korjaa jos olen väärässä mutta megoja kyllä, teroja ei, siksi nääs että 32-bit koneessa maks. osoiteavaruus on 4GT (2^32 T). Loppuu muisti kese...

    Huh, kyllä sai taas pilkku kyytiä ;)

    Ilmeisesti koneen muistin määrä rajoittaa. Ja minä olen luullut, että Windows käyttää virtuaalimuistia, jossa kovalevy on myös käytössä. Perskules, niin ei taida ollakaan.

    Kun 128 MB:n muistilla tein 100 MB:n merkkijonon käskyllä A$ = String(100000000, "a"), alkoi tietokone menemään hitaaksi.

    En nyt tiedä teoreettista maksimia, mutta eipä kannata ladata kaikkia suomalaisten nimiä kerralla koneen muistiin. Tai no ne taitaisivat kyllä sopia.

    Äänestä

Kommentoi aloitusta


Janne kirjoitti:

Pankaas pieni esimerkki vaikkapa linkitetyn listan tekemisestä. Onnistuuko?

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu